Используйте setTransform (1,0,0,1,0,0) против save () restore () - PullRequest
0 голосов
/ 24 февраля 2019

У меня есть этот код, работающий для вращения / перемещения двух блоков независимо, в то же время сохраняя третий стационарный для подтверждения статического базового преобразования.Я наконец смог заставить его работать с помощью setTransform (1,0,0,1,0,0) после неудачного применения save () restore () после каждой последовательности преобразования.Хотя он теперь работает, я все еще задаюсь вопросом, существует ли правильная последовательность сохранения / восстановления, которая решила проблему вместо сброса преобразования.

<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>

1 Ответ

0 голосов
/ 25 февраля 2019

Сброс матрицы преобразования - это путь.

save() / restore() сохраняет и восстанавливает все свойства вашего настраиваемого контекста;для памяти это имеет свою стоимость и, в конечном счете, также и для perfs, тогда как сброс матрицы устанавливает одно свойство контекста и не требует использования памяти.
Только clip() требует этого, но самого clip() следует избегатьс помощью композитинга.

В дополнение к этому этот метод подразумевает логику goto() в вашем коде и усложняет его чтение без четких заявлений о текущем состоянии, а также облегчает пропуск одного restore() и позвольте вашему коду создать утечку памяти.

Чтобы ответить на ваш вопрос, вы должны понимать, как работает эта операция.

Как я уже сказал save() сохраняет все настраиваемые свойстваваш контекст, он будет хранить его в стеке, где restore() будет затем извлекать последний, который будет восстановлен.

Это означает, что для того, чтобы иметь возможность восстановить предыдущее состояние, вам необходимо сохранитьпо крайней мере столько раз, сколько потребуется для восстановления.

Таким образом, вы можете либо заменить все свои setTransform строки на

ctx.restore(); // apply popped state
ctx.save(); // push current (restored) state

, либо вы можете вызывать напрямую столько раз save(), сколько вам потребуется в функции тура (здесь 3).

Но в любом случае, просто идите setTransform(1,0,0,1,0,0).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...