仿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
相关产品推荐
相关产品推荐

