JS修改动画速度时龙动画随机起始位置问题求助
问题分析与解决方案
问题原因
- 静态位置获取:
dragonPosition是页面加载时一次性获取的计算样式,不会实时更新龙的当前位置,导致判断逻辑失效。 - 重复定时器:每次按上箭头都会创建新的
setInterval,多个定时器同时修改龙的状态,造成位置混乱。 - 动画状态未重置:修改
animation-duration时,CSS动画会继续沿用当前的动画进度,不会从头开始播放,导致龙从中间位置启动。
修正后的代码
CSS代码
.dragon { background-image: url(images/dragon.png); background-position: center; background-size: contain; background-repeat: no-repeat; width: 180px; height: 120px; position: absolute; bottom: 0; left: 2000px; animation: ani-dragon 6s linear infinite; } @keyframes ani-dragon { 0% { left: 2000px; } 100% { left: -500px; } } .ani-dino { animation: ani-dino 1s linear; } @keyframes ani-dino { 0% { bottom: 0; } 50% { bottom: 300px; } 100% { bottom: 0; } }
JavaScript代码
let dino = document.querySelector(".dino"); let dragon = document.querySelector(".dragon"); let dragonAnimationTime = parseFloat(window.getComputedStyle(dragon).animationDuration); let newAni = dragonAnimationTime; let speedUpTimer = null; document.addEventListener("keydown", function (e) { if (e.key === "ArrowUp") { dino.classList.add("ani-dino"); // 只初始化一次定时器,避免重复创建 if (!speedUpTimer) { speedUpTimer = setInterval(() => { // 实时获取当前龙的位置 const currentLeft = parseInt(window.getComputedStyle(dragon).left); if (newAni > 2 && Math.round(currentLeft) < -490) { newAni = dragonAnimationTime - 0.1; dragonAnimationTime = newAni; // 重置动画:先移除动画,再重新添加,确保从头开始 dragon.style.animation = "none"; // 强制触发重绘 void dragon.offsetWidth; dragon.style.animation = `ani-dragon ${newAni}s linear infinite`; // 同步重置left属性 dragon.style.left = "2000px"; } }, 10); } setTimeout(() => { dino.classList.remove("ani-dino"); }, 1000); } });
关键修改点
- 实时获取位置:每次判断时重新调用
window.getComputedStyle(dragon).left,确保拿到当前最新位置。 - 单一定时器:添加判断逻辑,只创建一个定时器,避免多个定时器同时修改状态导致混乱。
- 重置动画状态:通过先移除动画、强制重绘再重新添加动画的方式,让动画从头开始播放,保证龙每次从右侧2000px位置启动。
- 补充元素获取:补充
dragon元素的获取逻辑,避免未定义报错。
内容的提问来源于stack exchange,提问作者Jatin Duggal
相关产品推荐
相关产品推荐

