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

仿AirPods Pro页面滚动动画故障求助(多图片实现)

解决滚动逐帧动画图片叠加的问题

我懂你想复刻AirPods Pro官网那种丝滑的滚动帧动画,但现在滚动时所有图片都堆在屏幕上——这问题其实很典型:你每次绘制新帧前没有清空画布,Canvas会保留之前所有绘制的内容,新图片直接画在旧图上面,自然就看起来所有帧都停留在屏幕上了。

核心问题修复

你的updateImage函数只负责加载并绘制新图片,却没清除掉上一帧的内容。只需要在绘制新图前,用clearRect清空整个画布即可:

const updateImage = index => {
  // 关键:清空画布,参数是画布的左上角坐标和宽高
  context.clearRect(0, 0, canvas.width, canvas.height);
  img.src = currentFrame(index);
  context.drawImage(img, 0, 0);
}

额外优化建议

除了核心修复,还有两个小细节可以让你的动画更完善:

  • 补全预加载的帧:你的preloadImages循环用了i < frameCount,但帧总数是162,这样会少加载最后一帧(第162帧),改成i <= frameCount就能把所有帧都预加载完毕:
    const preloadImages = () => {
      for (let i = 1; i <= frameCount; i++) {
        const img = new Image();
        img.src = currentFrame(i);
      }
    };
    
  • 优化帧索引计算:当前的滚动计算里,frameIndex最后加1的逻辑可以调整得更简洁,避免可能的帧索引越界:
    window.addEventListener('scroll', () => {
      const scrollTop = html.scrollTop;
      const maxScrollTop = html.scrollHeight - window.innerHeight;
      const scrollFraction = scrollTop / maxScrollTop;
      // 直接计算出正确的帧索引,不用额外加1,同时确保不超过总帧数
      const frameIndex = Math.min(frameCount, Math.ceil(scrollFraction * frameCount));
      requestAnimationFrame(() => updateImage(frameIndex))
    });
    

这样修改后,滚动时画布会先清空上一帧,再绘制当前对应的帧,就能实现和AirPods Pro官网类似的滚动动画效果了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:38:12