You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:实现游戏胜利触发的滚动数字递增动画

游戏获胜分数滚动数字动画实现方案

我想给游戏的获胜分数做一个滚动数字动画,要求只有在游戏获胜时,分数从0开始逐个递增(比如0→1→2这样一步步往上跳),目前写了部分代码,但不知道怎么完成完整的实现。

现有代码

JS

let firstTarget = 0;

JSX

<div
    style={{ backgroundColor: gameLost ? failureOp : gameWon ? successOp : 'lightgray' }}
    ref={firstNodeRef}
    className="inner-target-child"
>
    <div id="counter" className="animated">
        <ul className="digits luckie">
            <li>{firstTarget}</li>
            <li>{firstTarget + 1}</li>
            <li>{firstTarget + 2}</li>
            <li>{firstTarget + 3}</li>
        </ul>
    </div>
</div>

CSS

#counter {
   height: 1em;
   overflow: hidden;
}

.digits {
   float:center;
   list-style-type: none;
   font-size: 1em;
   line-height: 1em;
   margin-top: 0em;

   animation-duration: 2s;
   animation-timing-function: ease;
   animation-delay: 2.2s;
   animation-fill-mode: forwards;
}

.luckie {
   animation-name: luckie;
}

/* Animations */
@keyframes luckie {
   100% {
       margin-top: -3em;
   }
} 

实现方案

要实现仅在获胜时逐个递增的滚动动画,需要从触发时机、动态数字生成、分步动画控制三个方面修改:

1. 状态与动画触发控制

用React状态变量控制动画的启动/重置,仅当gameWon为true时执行动画:

import { useState, useEffect } from 'react';

const [winScore, setWinScore] = useState(0); // 存储最终获胜分数

2. 动态生成数字列表

根据最终获胜分数生成从0到目标值的所有数字项,替代固定的+1/+2/+3:

<div
    style={{ backgroundColor: gameLost ? failureOp : gameWon ? successOp : 'lightgray' }}
    ref={firstNodeRef}
    className="inner-target-child"
>
    <div id="counter" className="animated">
        <ul className="digits" style={{ '--offset': '0' }}>
            {Array.from({ length: winScore + 1 }, (_, idx) => (
                <li key={idx}>{idx}</li>
            ))}
        </ul>
    </div>
</div>

3. 分步滚动动画逻辑

通过定时器逐个调整列表的margin-top,实现数字逐个滚动的效果:

useEffect(() => {
    if (gameWon) {
        // 替换为实际游戏逻辑中的获胜分数
        const finalScore = 5;
        setWinScore(finalScore);
        
        let currentNum = 0;
        const scrollInterval = setInterval(() => {
            currentNum++;
            const digitList = document.querySelector('.digits');
            if (digitList) {
                // 每个li高度为1em,偏移量为 -currentNum em
                digitList.style.setProperty('--offset', `-${currentNum}em`);
            }
            // 到达目标分数后停止动画
            if (currentNum >= finalScore) {
                clearInterval(scrollInterval);
            }
        }, 500); // 调整此值控制滚动速度(单位ms)
        
        return () => clearInterval(scrollInterval);
    } else {
        // 游戏未获胜时重置状态与样式
        setWinScore(0);
        const digitList = document.querySelector('.digits');
        if (digitList) {
            digitList.style.setProperty('--offset', '0');
        }
    }
}, [gameWon]);

4. 调整CSS样式

用CSS变量控制偏移,替换固定的关键帧动画,适配动态分数:

#counter {
   height: 1em;
   overflow: hidden;
}

.digits {
   margin: 0 auto; /* 修正float:center的错误,实现居中 */
   list-style-type: none;
   font-size: 1em;
   line-height: 1em;
   margin-top: var(--offset);
   transition: margin-top 0.3s ease; /* 平滑过渡效果 */
}

关键说明

  • 仅在gameWon状态变为true时启动动画,避免不必要的执行
  • 定时器间隔可根据需求调整,数值越小滚动速度越快
  • 动态生成数字列表确保不管最终分数是多少,都能完整展示每一步的数值
  • 游戏未获胜或重新开始时,重置样式与状态,保证下次动画正常触发

内容的提问来源于stack exchange,提问作者Nyanjan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:50:47