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

网页星空下落动画动态调速跳转问题求助

解决星星动画变速跳转问题

问题根源

  1. 每次调用updateStarSpeed时重新生成randomFactor,导致同一星星的速度系数突变,既破坏3D空间感,又引发位置跳转。
  2. 通过修改animation-duration和animation-delay调速的方式会重置动画状态,无法实现平滑过渡。
  3. 依赖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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 04:59:51