求助:实现游戏胜利触发的滚动数字递增动画
游戏获胜分数滚动数字动画实现方案
我想给游戏的获胜分数做一个滚动数字动画,要求只有在游戏获胜时,分数从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
相关产品推荐
相关产品推荐

