我使这段代码可以独立旋转/移动两个框,同时保持第三个框静止以确认静态基础变换。在每个转换序列之后未成功应用save()restore()之后,我终于可以通过使用setTransform(1,0,0,1,0,0)使其工作。尽管它现在可以正常工作,但我仍然想知道是否存在正确的保存/恢复顺序来解决问题,而不是重置转换。
<canvas id="ctx" width="500" height="500" style="border:1px solid #000000;">
</canvas>
<script>
var ctx = document.getElementById("ctx").getContext("2d");
canvasWidth=500;
canvasHeight=500;
// box 1
var x=250;
var y=250;
var box = 50;
var angle1 = 90;
//box 2
var x2=200;
var y2=200;
var box = 50;
var angle2 = 90;
function rotate() {
angle1-=1;
angle2+=1;
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.save();
//box 1
x=x-2;
y=y+2;
var ctrX = x+box/2;
var ctrY = y+box/2;
//box 2
x2=x2+.5;
y2=y2+.5;
var ctrX2 = x2+box/2;
var ctrY2 = y2+box/2;
// box 1
ctx.translate(ctrX, ctrY);//-------------------------------- move reg to center
box
ctx.rotate(angle1 / 60);//----------------------------------rotate
ctx.translate(-ctrX, -ctrY);//-------------------------------- move reg back same
amt
//------------------------------------------------------- draw
ctx.fillStyle = "blue";
ctx.fillRect(x, y, box, box);
ctx.fillStyle = "red";
ctx.fillRect(x, y, 10, 10);
ctx.fillStyle = "black";
ctx.fillRect(ctrX-5, ctrY-5, 10, 10);
ctx.setTransform(1,0,0,1,0,0);
//-------------------------------------------------------------------- second box
ctx.translate(ctrX2, ctrY2);//-------------------------------- move reg to center
box
ctx.rotate(angle2 / 60);//----------------------------------rotate
ctx.translate(-ctrX2, -ctrY2);//-------------------------------- move reg back
same amt
//------------------------------------------------------- draw
ctx.fillStyle = "green";
ctx.fillRect(x2, y2, box, box);
ctx.fillStyle = "red";
ctx.fillRect(x2, y2, 10, 10);
ctx.fillStyle = "black";
ctx.fillRect(ctrX2-5, ctrY2-5, 10, 10);
ctx.setTransform(1,0,0,1,0,0);
ctx.fillStyle = "black";//............................. draw control point
ctx.fillRect(50, 50, 10, 10);
ctx.restore();
}
setInterval(rotate, 100);
</script>
答案 0 :(得分:0)
save()
/ restore()
保存并恢复您设置的上下文的属性全部;对于内存来说,这是有代价的,并且最终也会对性能造成影响,而重置矩阵会设置上下文的单个属性,这意味着不使用内存。
仅clip()
要求这样做,但是clip()
本身应通过使用合成避免。
此外,此方法在您的代码中隐含一种goto()
逻辑,并且由于没有明确说明当前状态是什么而使阅读变得更加困难,并且还易于遗漏一个{{ 1}},然后让您的代码造成内存泄漏。
要回答您的问题,您必须了解此操作的工作原理。
我已经说过restore()
保存了上下文的所有可设置属性,它将存储在堆栈中,然后save()
弹出要还原的最后一个。
这意味着要能够还原到以前的状态,您至少需要保存与还原所需次数相同的次数。
因此,您可以将所有restore()
行替换为
setTransform
或者您可以在游览功能(此处为3)中直接调用ctx.restore(); // apply popped state
ctx.save(); // push current (restored) state
多次,
但是无论如何,只要走save()
的方式即可。