我试图在画布中移动一个模式,但是在几秒钟(或几分钟)之后,情况变得难以管理。
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个透明图案在不同的方向上移动并相互重叠。是否可以调整它?
提前谢谢。
答案 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);
}