网页星空下落动画动态调速跳转问题求助
解决星星动画变速跳转问题
问题根源
- 每次调用
updateStarSpeed时重新生成randomFactor,导致同一星星的速度系数突变,既破坏3D空间感,又引发位置跳转。 - 通过修改
animation-duration和animation-delay调速的方式会重置动画状态,无法实现平滑过渡。 - 依赖
Date.now()跟踪动画时间存在精度误差,容易导致进度计算偏差。
解决方案
改用CSS的animation-play-rate属性动态调整动画速度,该属性可在不重置动画的前提下,从当前状态平滑切换播放速率,完美解决跳转问题。同时为每个星星固定速度系数,保持稳定的3D空间感。
1. 修改CSS代码
将星星的下落动画固定基准时长,后续通过播放速率控制速度:
body::before { content: ""; position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; background-color: #000; overflow: hidden; } @keyframes moveDown { 0% { transform: translateY(-100vh); } 100% { transform: translateY(100vh); } } .stars { position: absolute; width: 1px; height: 1px; background-color: #fff; /* 固定下落动画基准时长为10s,闪烁动画保持不变 */ animation: moveDown 10s linear infinite, twinkle 4s infinite alternate; animation-fill-mode: forwards; animation-play-state: running; } @keyframes twinkle { 0% { opacity: 1; } 50% { opacity: 0.7; } 100% { opacity: 1; } }
2. 重构JavaScript代码
修改createStar函数
为每个星星保存固定的速度系数,并设置初始播放速率:
function createStar(enginePower) { const star = document.createElement('div'); star.className = 'stars'; const xPos = Math.random() * window.innerWidth; const yPos = -10; star.style.left = `${xPos}px`; star.style.top = `${yPos}px`; const size = Math.random() + 1; star.style.width = `${size}px`; star.style.height = `${size}px`; const twinklingDelay = Math.random() * 2; star.style.animationDelay = `0s, ${twinklingDelay}s`; // 为星星保存固定的速度差异系数,后续调速不再改变 star.randomFactor = Math.random() * 2 + 0.5; // 计算初始播放速率:引擎功率越高,速率越快 const initialRate = Math.max(0.1, enginePower * star.randomFactor + 0.1); star.style.animationPlayRate = initialRate; star.addEventListener('animationiteration', () => { if (star.getBoundingClientRect().top > window.innerHeight) { // 星星移出屏幕后重置到顶部,避免频繁DOM操作 star.style.top = '-10px'; } }); document.body.appendChild(star); stars.push(star); }
修改updateStarSpeed函数
直接通过修改播放速率实现平滑调速:
function updateStarSpeed(enginePower) { stars.forEach(star => { // 基于固定的randomFactor计算新的播放速率 const newRate = Math.max(0.1, enginePower * star.randomFactor + 0.1); // 直接设置播放速率,动画会从当前状态平滑过渡 star.style.animationPlayRate = newRate; }); }
调整startDivertGame中的星星生成逻辑
starSpawnInterval = setInterval(() => { if (starCounter < 150) { // 直接传入当前enginePower,由createStar计算初始速率 createStar(enginePower); starCounter++; } else { clearInterval(starSpawnInterval); } }, 50);
关键改进点
- 固定速度系数:每个星星的
randomFactor在创建时确定,后续调速时保持不变,确保3D空间感的一致性。 - 平滑速率调整:使用
animation-play-rate替代修改动画时长,动画会从当前位置继续以新速率运动,完全消除跳转。 - 优化循环逻辑:星星移出屏幕后直接重置到顶部,减少DOM删除/创建操作,提升性能。
内容的提问来源于stack exchange,提问作者Christopher Bürgmann
相关产品推荐
相关产品推荐

