使用GSAP的逐帧滚动动画页面加载时不显示问题求助
问题:GSAP滚动触发逐帧动画页面加载时无图像显示
使用逐帧图片制作GSAP滚动触发动画后,出现以下问题:页面加载完成后画布无图像显示,仅在滚动时才会出现,回滚至页面上方时图像又消失。需要实现页面加载完成后直接渲染第一帧,滚动时正常触发动画的效果。
解决方案
核心是确保页面加载完成+所有帧图加载完毕后立即渲染第一帧,同时修正GSAP ScrollTrigger的无效配置,具体调整如下:
- 确保所有图片加载完成后触发初始渲染
- 修正ScrollTrigger的
start配置(原语法无效) - 添加页面加载完成后的兜底渲染逻辑
- 优化渲染时的帧索引边界判断,避免数组越界
修改后的完整代码
HTML(无需修改)
<div class="hero"> <div id="home"> <canvas></canvas> </div> <div class="about"></div> </div>
CSS(无需修改,可根据布局调整margin-top)
canvas { margin: 0 auto; margin-top: -189px; display: block; aspect-ratio: 16 / 9; }
JS(关键修改版)
function sequence_animation() { const canvas = document.querySelector('#home>canvas'); const context = canvas.getContext('2d'); // 初始设置为窗口宽高,适配不同设备 canvas.width = window.innerWidth; canvas.height = window.innerHeight; let imagesLoaded = 0; const frameCount = 19; const images = []; const imageSeq = { frame: 0, }; function files(index) { const data = ` ../assets/img/animation/1.png ../assets/img/animation/1.png ../assets/img/animation/1-2.png ../assets/img/animation/2.png ../assets/img/animation/2-2.png ../assets/img/animation/3.png ../assets/img/animation/3-2.png ../assets/img/animation/4.png ../assets/img/animation/4-2.png ../assets/img/animation/5.png ../assets/img/animation/5-2.png ../assets/img/animation/6.png ../assets/img/animation/6-2.png ../assets/img/animation/7.png ../assets/img/animation/7-2.png ../assets/img/animation/8.png ../assets/img/animation/8-2.png ../assets/img/animation/9.png ../assets/img/animation/9-2.png ../assets/img/animation/10.png `; return data.split('\n')[index].trim(); } for (let i = 0; i < frameCount; i++) { const img = new Image(); img.src = files(i); images.push(img); img.onload = () => { imagesLoaded++; // 所有图片加载完成后渲染第一帧 if (imagesLoaded === frameCount) { render(); } }; } window.addEventListener('resize', function () { canvas.width = window.innerWidth; canvas.height = window.innerHeight; render(); }); gsap.to(imageSeq, { frame: frameCount - 1, snap: 'frame', ease: 'none', scrollTrigger: { scrub: 1, pin: false, trigger: '.header__list-item.message', start: "top bottom", // 修正无效配置:触发元素顶部碰到视口底部时启动动画 end: "bottom top" // 可选:设置动画结束时机 }, onUpdate: render, }); function render() { // 限制帧索引范围,避免数组越界报错 const currentFrame = Math.max(0, Math.min(imageSeq.frame | 0, frameCount - 1)); scaleImage(images[currentFrame], context); } function scaleImage(img, ctx) { const canvas = ctx.canvas; ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, canvas.width, canvas.height); } // 页面完全加载后兜底渲染,确保第一帧显示 window.addEventListener('load', () => { if (imagesLoaded === frameCount) { render(); } }); } sequence_animation();
关键修改说明
- 把canvas初始宽高从固定值改为窗口宽高,提升适配性
- 修正了ScrollTrigger的
start配置(原left %为无效语法) - 添加
window.load事件兜底,确保页面加载完成后至少显示第一帧 - 给
render()函数增加索引边界判断,避免因动画值异常导致的数组越界 - 整理了帧路径字符串格式,避免多余空格引发的路径错误
内容的提问来源于stack exchange,提问作者Nilpy
相关产品推荐
相关产品推荐

