Вы не можете нарисовать повернутый объект на холсте, не "вращая" весь холст.
К сожалению, именно так работает холст.Подумайте об этом так:
Вы можете рисовать только в одной точке пространства {x:0,y:0}
, и холст находится прямо под этой точкой, как физический лист бумаги.
Тогда, если вы хотитерисуя на {x:0,y:10}
, вы перемещаете весь холст на 10 пикселей вверх, поэтому теперь точка, с которой вы рисуете, стала {x:0,y:10}
, если вы считаете сверху / слева от холста, но для рисования это {x:0,y:0}
.
// red rect at {x:0,y:40}
ctx.fillStyle = "rgba(255,0,0,0.3)";
ctx.translate(0, 40) // means that {x:0,y:10} "is new" {x:0,y:0}
ctx.fillRect(0, 0, 40, 20);
Если вы хотите повернуть, вы поворачиваете холст, так что то, что вы хотите нарисовать, будет отображаться при его вращении:
// reset all transformations
ctx.setTransform(1, 0, 0, 1, 0, 0);
// green rect at {x:0,y:0} rotated 45deg
ctx.fillStyle = "rgba(0,255,0,0.3)";
ctx.rotate(45 * Math.PI / 180);
ctx.fillRect(0, 0, 40, 20);
Но оно вращается вокруг своего верхнего / левого угла.Я полагаю, это ваша проблема?
Чтобы правильно повернуть объект (с центром в качестве оси вращения), вам нужно разместить холст так, чтобы центр объекта стал {x:0,y:0}
.Затем поверните и нарисуйте объект так, чтобы его центр находился на {x:0,y:0}
, для большинства объектов это означает, что вы рисуете их на {x:-width/2,y:-height/2}
.
Например, если вы хотите синий прямоугольник на {x:50,y:50}
, повернутый на 45 градусов с{width:40,height:20}
// reset all transformations
ctx.setTransform(1, 0, 0, 1, 0, 0);
// blue rect at {x:50,y:50} rotated 45deg
var rectWidth = 40;
var rectHeight = 20;
ctx.fillStyle = "rgba(0,0,255,0.3)";
ctx.translate(50, 50);
ctx.rotate(45 * Math.PI / 180);
ctx.fillRect(-rectWidth/2, -rectHeight/2, rectWidth, rectHeight);
См. Полный пример: https://codepen.io/anon/pen/QYGXzp?editors=0010