fix: 翻牌样式优化,动画效果完善

This commit is contained in:
Gsh
2025-11-01 18:39:02 +08:00
parent 9d401a9c93
commit e15eb6149b

View File

@@ -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>
<!-- 显示已有的邀请码 --> <!-- 显示已有的邀请码 -->