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

使用GSAP的逐帧滚动动画页面加载时不显示问题求助

问题:GSAP滚动触发逐帧动画页面加载时无图像显示

使用逐帧图片制作GSAP滚动触发动画后,出现以下问题:页面加载完成后画布无图像显示,仅在滚动时才会出现,回滚至页面上方时图像又消失。需要实现页面加载完成后直接渲染第一帧,滚动时正常触发动画的效果。

解决方案

核心是确保页面加载完成+所有帧图加载完毕后立即渲染第一帧,同时修正GSAP ScrollTrigger的无效配置,具体调整如下:

  1. 确保所有图片加载完成后触发初始渲染
  2. 修正ScrollTrigger的start配置(原语法无效)
  3. 添加页面加载完成后的兜底渲染逻辑
  4. 优化渲染时的帧索引边界判断,避免数组越界

修改后的完整代码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:07:45