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

