fix: 翻牌样式优化,动画效果完善
This commit is contained in:
@@ -97,8 +97,16 @@ async function playShuffleAnimation() {
|
|||||||
|
|
||||||
isShuffling.value = true;
|
isShuffling.value = true;
|
||||||
|
|
||||||
// 随机选择3张大奖卡片
|
// 获取未翻开的卡片编号列表
|
||||||
bigPrizeCards.value = generateRandomCards(3, 10);
|
const unflippedCards = taskData.value?.flipRecords
|
||||||
|
?.filter(record => !record.isFlipped)
|
||||||
|
.map(record => record.flipNumber) || [];
|
||||||
|
|
||||||
|
// 随机数量取min(3, 未翻开卡片数量)
|
||||||
|
const randomCount = Math.min(3, unflippedCards.length);
|
||||||
|
|
||||||
|
// 从未翻开的卡片中随机选择
|
||||||
|
bigPrizeCards.value = generateRandomCards(randomCount, unflippedCards);
|
||||||
|
|
||||||
// 阶段1:展示大奖卡片正面(2.5秒)
|
// 阶段1:展示大奖卡片正面(2.5秒)
|
||||||
shuffleStage.value = 'showing';
|
shuffleStage.value = 'showing';
|
||||||
@@ -121,13 +129,23 @@ async function playShuffleAnimation() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 生成随机卡片编号
|
* 生成随机卡片编号
|
||||||
|
* @param count 需要随机选择的数量
|
||||||
|
* @param availableCards 可选的卡片编号数组(未翻开的卡片)
|
||||||
*/
|
*/
|
||||||
function generateRandomCards(count: number, max: number): number[] {
|
function generateRandomCards(count: number, availableCards: number[]): number[] {
|
||||||
const cards = new Set<number>();
|
// 如果没有可用卡片或数量为0,返回空数组
|
||||||
while (cards.size < count) {
|
if (!availableCards.length || count === 0) {
|
||||||
cards.add(Math.floor(Math.random() * max) + 1);
|
return [];
|
||||||
}
|
}
|
||||||
return Array.from(cards);
|
|
||||||
|
// 如果需要的数量大于等于可用卡片数量,直接返回所有可用卡片
|
||||||
|
if (count >= availableCards.length) {
|
||||||
|
return [...availableCards];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从可用卡片中随机选择指定数量
|
||||||
|
const shuffled = [...availableCards].sort(() => Math.random() - 0.5);
|
||||||
|
return shuffled.slice(0, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -276,6 +294,7 @@ function updateLuckyValue() {
|
|||||||
* @param record 卡片记录对象
|
* @param record 卡片记录对象
|
||||||
*/
|
*/
|
||||||
async function handleFlipCard(record: CardFlipRecord) {
|
async function handleFlipCard(record: CardFlipRecord) {
|
||||||
|
console.log('record---', record);
|
||||||
// 防止洗牌动画期间点击
|
// 防止洗牌动画期间点击
|
||||||
if (isShuffling.value) {
|
if (isShuffling.value) {
|
||||||
return;
|
return;
|
||||||
@@ -334,6 +353,12 @@ async function handleFlipCard(record: CardFlipRecord) {
|
|||||||
const clonedCard = cardElement.cloneNode(true) as HTMLElement;
|
const clonedCard = cardElement.cloneNode(true) as HTMLElement;
|
||||||
clonedCard.classList.add('cloned-flipping-card');
|
clonedCard.classList.add('cloned-flipping-card');
|
||||||
|
|
||||||
|
// 移除可能影响显示的类(hover效果等)
|
||||||
|
clonedCard.classList.remove('card-clickable');
|
||||||
|
|
||||||
|
// 禁用鼠标事件,避免hover效果干扰
|
||||||
|
clonedCard.style.pointerEvents = 'none';
|
||||||
|
|
||||||
// 获取原卡片的位置信息
|
// 获取原卡片的位置信息
|
||||||
const rect = cardElement.getBoundingClientRect();
|
const rect = cardElement.getBoundingClientRect();
|
||||||
|
|
||||||
@@ -383,7 +408,60 @@ async function handleFlipCard(record: CardFlipRecord) {
|
|||||||
const res = await flipCard({ flipNumber: record.flipNumber });
|
const res = await flipCard({ flipNumber: record.flipNumber });
|
||||||
lastFlipResult.value = res.data;
|
lastFlipResult.value = res.data;
|
||||||
|
|
||||||
// 6. 给克隆卡片添加翻转动画类
|
// 6. 根据接口返回的结果,动态更新克隆卡片的card-back内容
|
||||||
|
const cardBack = clonedCard.querySelector('.card-back') as HTMLElement;
|
||||||
|
if (cardBack) {
|
||||||
|
// 获取Vue scoped样式属性(用于保持样式一致性)
|
||||||
|
const scopedAttr = Array.from(clonedCard.attributes).find(attr => attr.name.startsWith('data-v-'));
|
||||||
|
const scopedAttrName = scopedAttr ? scopedAttr.name : '';
|
||||||
|
|
||||||
|
// 辅助函数:为元素及其所有子元素添加scoped属性
|
||||||
|
const addScopedAttr = (element: HTMLElement) => {
|
||||||
|
if (scopedAttrName) {
|
||||||
|
element.setAttribute(scopedAttrName, '');
|
||||||
|
// 递归为所有子元素添加属性
|
||||||
|
Array.from(element.children).forEach((child) => {
|
||||||
|
addScopedAttr(child as HTMLElement);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 清空原有内容(保留伪元素样式)
|
||||||
|
cardBack.innerHTML = '';
|
||||||
|
|
||||||
|
// 创建card-result容器
|
||||||
|
const cardResult = document.createElement('div');
|
||||||
|
cardResult.className = res.data.isWin ? 'card-result win' : 'card-result lose';
|
||||||
|
|
||||||
|
if (res.data.isWin) {
|
||||||
|
// 中奖情况:显示中奖样式
|
||||||
|
cardResult.innerHTML = `
|
||||||
|
<div class="win-glow"></div>
|
||||||
|
<img src="${systemLogo}" class="result-watermark" alt="Logo">
|
||||||
|
<div class="result-icon">🎉</div>
|
||||||
|
<div class="result-text">中奖啦!</div>
|
||||||
|
<div class="result-amount">${formatTokenDisplay(res.data.rewardAmount || 0)}</div>
|
||||||
|
<div class="result-unit">Tokens</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 未中奖情况:显示未中奖样式
|
||||||
|
cardResult.innerHTML = `
|
||||||
|
<img src="${systemLogo}" class="result-watermark" alt="Logo">
|
||||||
|
<div class="result-icon">💫</div>
|
||||||
|
<div class="result-text">未中奖</div>
|
||||||
|
<div class="result-tip">继续加油!</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 为新创建的元素添加scoped属性,确保样式正确应用
|
||||||
|
addScopedAttr(cardResult);
|
||||||
|
|
||||||
|
// 将card-result添加到card-back中
|
||||||
|
cardBack.appendChild(cardResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. 给克隆卡片添加翻转动画类
|
||||||
const cardInner = clonedCard.querySelector('.card-inner') as HTMLElement;
|
const cardInner = clonedCard.querySelector('.card-inner') as HTMLElement;
|
||||||
if (cardInner) {
|
if (cardInner) {
|
||||||
cardInner.style.transition = 'transform 0.8s ease-in-out';
|
cardInner.style.transition = 'transform 0.8s ease-in-out';
|
||||||
@@ -393,10 +471,10 @@ async function handleFlipCard(record: CardFlipRecord) {
|
|||||||
// 等待翻转动画完成
|
// 等待翻转动画完成
|
||||||
await new Promise(resolve => setTimeout(resolve, 800));
|
await new Promise(resolve => setTimeout(resolve, 800));
|
||||||
|
|
||||||
// 7. 刷新任务状态
|
// 8. 刷新任务状态
|
||||||
await fetchTaskStatus();
|
await fetchTaskStatus();
|
||||||
|
|
||||||
// 8. 卡片停留展示结果(2秒)
|
// 9. 卡片停留展示结果(2秒)
|
||||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||||
|
|
||||||
// === 显示中奖结果 ===
|
// === 显示中奖结果 ===
|
||||||
@@ -421,7 +499,7 @@ async function handleFlipCard(record: CardFlipRecord) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 9. 移除克隆卡片
|
// 10. 移除克隆卡片
|
||||||
if (clonedCardElement.value) {
|
if (clonedCardElement.value) {
|
||||||
// 添加淡出动画
|
// 添加淡出动画
|
||||||
clonedCardElement.value.style.opacity = '0';
|
clonedCardElement.value.style.opacity = '0';
|
||||||
@@ -431,7 +509,7 @@ async function handleFlipCard(record: CardFlipRecord) {
|
|||||||
clonedCardElement.value = null;
|
clonedCardElement.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10. 清除占位状态,原卡片显示为已翻转
|
// 11. 清除占位状态,原卡片显示为已翻转
|
||||||
flippingCardNumber.value = null;
|
flippingCardNumber.value = null;
|
||||||
}
|
}
|
||||||
catch (error: any) {
|
catch (error: any) {
|
||||||
@@ -975,7 +1053,9 @@ function getCardClass(record: CardFlipRecord): string[] {
|
|||||||
<!-- 已使用过邀请码的提示 -->
|
<!-- 已使用过邀请码的提示 -->
|
||||||
<div v-if="taskData?.isInvited" class="invite-disabled-box">
|
<div v-if="taskData?.isInvited" class="invite-disabled-box">
|
||||||
<span class="disabled-icon">🔒</span>
|
<span class="disabled-icon">🔒</span>
|
||||||
<p class="disabled-text">您已使用过他人的邀请码,无法生成自己的邀请码</p>
|
<p class="disabled-text">
|
||||||
|
您已使用过他人的邀请码,无法生成自己的邀请码
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 显示已有的邀请码 -->
|
<!-- 显示已有的邀请码 -->
|
||||||
|
|||||||
Reference in New Issue
Block a user