HTML画布-翻译,旋转,剪辑-使用context.restore可以更快地还原

在几天前询问有关动画速度的问题后,stackoverflow帮再次解决了我的问题.但是,这引起了另一个问题. [了解得越多,您就越了解不知道.

基本上,画布上的状态更改越少,事情就会越快.如果我只是更改fillStyle,那么使用ctx.save和ctx.restore是多余的,因为恢复了所有状态.过度杀伤=慢.相反,只需将fillStyle的oldvalue保留在某个位置,然后在完成后再将其放回即可.

那么,如何针对ctx.translate(x,y),ctx.rotate(angle)和ctx.clip()执行此操作?

我如何在不使用ctx.restore的情况下将这些家伙恢复到更改前的状态?

最佳答案
您可以使用负值取消转换.

ctx.translate(100,100);
// draw lots of stuff
ctx.translate(-100,-100);

ctx.scale(.75,.50);
// draw stuff
ctx.scale(-.75,-.50);

ctx.rotate(Math.PI/4);
// draw stuff
ctx.rotate(-Math.PI/4);

如果执行多次转换,则必须以相反的顺序撤消它们

ctx.translate(100,100);
ctx.scale(.75,.50);    
ctx.rotate(Math.PI/4);

// draw lots of stuff

ctx.rotate(-Math.PI/4);
ctx.scale(-.75,-.50);
ctx.translate(-100,-100);

但是在平移(移动)一些项目时,使用偏移量而不是变换会更快.

strokeRect(20+100,20+100,50,30);
fillRect(20+100,20+100,50,30);

剪辑是半永久性的,因此您必须保存/恢复整个上下文状态才能撤消剪辑:

context.save();
// define a clipping path
context.clip();
// draw stuff
context.restore();

使用转换矩阵进行转换. Canvas使您可以使用context.setTransform方法访问该矩阵.

scaleX=.75;
scaleY=.50;
skewX=0;
skewY=0;
translateX=100;
translateY=100;

context.setTransform(scaleX, skewX, skewY, scaleY, translateX, translateY);

// draw stuff

context.setTransform(-scaleX, -skewX, -skewY, -scaleY, -translateX, -translateY);

要同时设置旋转矩阵,您必须设置比例尺&这样的偏斜值:

var radianAngle=Math.PI/4;
var cos=Math.cos(radianAngle);
var sin=Math.sin(radianAngle);

context.setTransform(cos,sin,-sin,-cos,0,0);

// draw stuff

context.setTransform(-cos,-sin,sin,cos,0,0);

要与其他变换一起旋转,只需将旋转值添加到比例和倾斜值.

context.setTransform(scaleX+cos, skewX+sin, skewY-sin, scaleY-cos, translateX, translateY);

// draw stuff

context.setTransform(-scaleX-cos, -skewX-sin, -skewY+sin, -scaleY+cos, -translateX, -translate);

转载注明原文:HTML画布-翻译,旋转,剪辑-使用context.restore可以更快地还原 - 代码日志