优化画布上的移动模式?

时间:2016-06-05 11:26:31

标签: canvas three.js

我试图在画布中移动一个模式,但是在几秒钟(或几分钟)之后,情况变得难以管理。

canvas = document.querySelector('canvas');
canvas.width = 400;
canvas.height = 240;
ctx = canvas.getContext('2d');
image = new Image();
image.src = 'pattern.png';
t = 0;

update();

function update() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.save();

  ctx.translate(t, 2*t);
  ctx.fillStyle = ctx.createPattern(image, 'repeat');
  ctx.rect(0, 0, canvas.width, canvas.height);
  ctx.fill();
  ctx.restore();

  t++;

  requestAnimationFrame(update);
}

这里是jsfiddle(内存消耗警报)。

我的目标是将该画布用作THREEjs精灵的纹理,在场景中连续运行。我无法为使用uvOffsets的精灵素材设置动画,因为将有3或4个透明图案在不同的方向上移动并相互重叠。是否可以调整它?

提前谢谢。

1 个答案:

答案 0 :(得分:1)

它随着时间的推移而减速的原因是rect()会随着时间的推移在路径对象上添加和累积,因此每次调用fill()时,所有这些矩形路径都会被填充。

只需更换此行:

ctx.rect(0, 0, canvas.width, canvas.height);

ctx.fillRect(0, 0, canvas.width, canvas.height);

在添加beginPath()之前,可以选择添加rect()fillRect()直接栅格化而不将矩形添加到路径中。

还要记住补偿矩形位置,因为它填充的区域也会移动,最终到达画布区域之外。只需使用翻译值的反向补偿:

ctx.fillRect(-t, -t*2, canvas.width, canvas.height);

在较新的浏览器中,我们可以直接在setTransform对象上使用CanvasPattern

// assuming pattern is set as fill-style
ctx.fillStyle.setTransform(1,0,0,1, x, y);

修改后的示例包括其他一些优化循环的建议:

...
image.onload = function() {
  ctx.fillStyle = ctx.createPattern(image, 'repeat');
  update();
};

function update() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  ctx.setTransform(1,0,0,1, t, 2*t);  // optionally replace save/restore/translate
  ctx.fillRect(-t, -t*2, canvas.width, canvas.height);

  t++;

  requestAnimationFrame(update);
}