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

JavaScript视差侧滚动动画各图层滚动速度不更新问题

视差侧滚动动画:图层独立速度修复方案

问题根源

你当前的代码里,所有图层共享了类实例的x和x2属性,每次调用updateDraw时,所有图层都会修改这两个公共变量,导致所有图层的滚动位置被强制同步,自然无法体现各自的速度差异。

修复方案

给每个图层单独维护自身的位置状态(x、x2),而非使用类实例级的公共变量。具体调整如下:

修改后的完整代码

const canvas = document.getElementById('canvas2')
const ctx = canvas.getContext('2d')
const CANVAS_WIDTH = canvas.width = 1600;
const CANVAS_HEIGHT = canvas.height = 720;

class ParallaxLayer {
    constructor(imageARR, speedARR) {
        this.width = 3840;
        this.height = 720;
        this.gameSpeed = 5;
        // 每个图层独立维护自身状态:图片、速度、坐标x和x2
        this.layers = [];

        // 初始化每个图层的独立状态
        Object.values(imageARR).forEach((layerSrc, index) => {
            const img = new Image();
            img.src = layerSrc;
            const speed = speedARR[index] * this.gameSpeed;
            this.layers.push({
                img,
                speed,
                x: 0,
                x2: this.width
            });
        });
    }

    updateDraw(layer) {
        let newX = layer.x;
        let newX2 = layer.x2;

        // 更新当前图层第一个副本的坐标
        if (newX <= -this.width) {
            newX = this.width + newX2 - layer.speed;
        }
        newX = Math.floor(newX - layer.speed);

        // 更新当前图层第二个副本的坐标
        if (newX2 <= -this.width) {
            newX2 = this.width + newX - layer.speed;
        }
        newX2 = Math.floor(newX2 - layer.speed);

        // 绘制当前图层的两个循环副本
        ctx.drawImage(layer.img, newX, 0, this.width, this.height);
        ctx.drawImage(layer.img, newX2, 0, this.width, this.height);

        // 同步更新图层对象的坐标
        layer.x = newX;
        layer.x2 = newX2;
    }

    animate() {
        ctx.clearRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
        // 遍历每个独立图层,执行更新与绘制
        this.layers.forEach(layer => {
            this.updateDraw(layer);
        });
        requestAnimationFrame(() => this.animate());
    }
}

const arrayofSpeed = [0.2, 0.4, 1, 2, 4];
const dayScene = new ParallaxLayer(timeCollection[0], arrayofSpeed);
dayScene.animate();

核心修改说明

  • 将原有的imgSet和speed数组合并为layers数组,每个元素是包含img、speed、x、x2的独立对象,确保每个图层拥有专属的位置状态
  • updateDraw方法改为接收单个图层对象,操作该对象的私有坐标,不再修改类实例的公共属性
  • 构造函数中直接计算每个图层的最终速度,避免重复计算逻辑

内容的提问来源于stack exchange,提问作者Dave Chapporal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 17:32:47