Представьте себе холст, как лист сетчатой бумаги на странице. Эта сетчатая бумага называется матрицей преобразования. Верхний левый - начало координат (x: 0, y: 0), при этом x идет вправо и y идет вниз по странице. Все, что вы рисуете, относительно этой точки и вдоль ее x и y. Таким образом, рисование текста на 200,200 составляет 200 пикселей вправо и 200 пикселей вниз от начала (вверху слева).
Если вы используете перевод, вращение, масштабирование, setTransform или преобразование, вы перемещаете лист сетчатой бумаги на странице. Скажем, вы переводите на 200 200. Вы переместили начало координат на 200 пикселей и на 200 пикселей. Теперь, если вы нарисуете текст на 200 200, он по-прежнему относится к началу сетки, которая теперь не находится в верхнем левом углу. Ваш текст заканчивается на 400 на 400 пикселей в верхнем левом углу. Если вы хотите нарисовать текст в том же месте, что и перед переводом, вам нужно изменить на координаты для учета перевода.
Поворот изменяет направление сетки. Вращение по Math.PI/2 (90deg) по часовой стрелке приводит к тому, что на лицевой поверхности сидит сбоку на странице. Перемещение в направлении x больше не идет слева направо, а сверху вниз.
И масштаб расширяет контракты сеткой бумаги. Весы, размер которых больше 1, увеличивают размер каждой сетки, масштабы меньше единицы уменьшают размер каждой сетки.
Использование комбинации перевода, масштабирования и поворота позволяет размещать сетку в любом месте страницы. Когда вы рисуете текст или что-либо, вы всегда рисуете его в соответствии с сеткой.
Чтобы привести пример, показывающий, как рисовать масштабированный переведенный текст с переворачиванием. Пожалуйста, найдите время, чтобы понять, что происходит. Я полностью прокомментировал это, если у вас есть вопросы, пожалуйста, спросите. (Пальцы скрещены, как я надеюсь, что это работает, как это первый раз, когда я пытался использовать StackOverflow код сниппета вещь)
// use matix
var useMatrix = false; // how to create the transformation
// mouse stuff
var mouse = {
x:0,
y:0,
};
function mouseMove(event){ // mouse event handler with firefox mod
mouse.x = event.offsetX;
mouse.y = event.offsetY;
if(mouse.x === undefined){ // if firefox
mouse.x = event.clientX;
mouse.y = event.clientY;
}
}
var ctx;
if(ctx === undefined){ // create the canvas if it does not exist
var can = document.getElementById("canvasID");
if(can !== null){
ctx = can.getContext("2d"); // get the context
can.addEventListener('mousemove',mouseMove); // add the mouse
}
}
// some stuff to animate some text
var angle = 0; //
var angleDelta = 0.1; // rate of change for angle
var scaleX = 1; // to hold scale x and y
var scaleY = 1;
var counter = 0; // counter used to change scale over time
var counterDelta = 0.1; // rate of scale change
var scaleFunction = function(){ // function to do scale change
scaleX = Math.sin(counter)*0.4 + 1;
scaleX = Math.cos(counter)*0.4 + 1;
counter += counterDelta;
}
// The drawing function will call the drawing callback after it has
// set the coordinate system to the desired position,rotation and scale.
// set coordinates to
// translate x,y
// rotate angle in radians
// 0 is no rotation
// Math.PI/2 is clockwise 90 deg
// -Math.PI/2 is antiClockwise 90 deg
// Math.PI is 180 deg
// scale sx along x
// sy along y
// ctx the context to draw to
// drawing the function that will draw
function drawAt(ctx,drawing,x,y,sx,sy,angle){
if(useMatrix){ // create the transform by hand
var xdx = Math.cos(angle); // get the direction of x along the page
var xdy = Math.sin(angle);
ctx.setTransform(// completely replace existing matrix
xdx * sx, // set the x direction and scale it by sx
xdy * sx,
-xdy * sy, // set the y direction @ 90deg of x and scale it by sy
xdx * sy,
x,y // set the origin at x and y
);
} else { // create the matrix by mutiplying existing matrix with translation, rotation and scale matricies.
// the order of these are important
ctx.translate(x,y); // multiply existing matrix with this translation
ctx.rotate(angle); // multiply the modified matrix with this rotation
ctx.scale(sx,sy); // multiply the modified matrix with this scale
}
drawing(ctx); // call draw
// restor the transform to default (identity matrix)
// reset x direction is vector (1,0) from left to right
// y (0,1) from top to bottom
// origin is 0,0 at the top left of page.
ctx.setTransform(1,0,0,1,0,0); // reset the transform to top left
}
// the function to draw. It does not need to now about where it is being draw.
function drawHello(ctx){ // say hello
ctx.font = "20px verdana"; // all drawing is relative to the origin
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("Hello planet Earth!",0,-22); // draw above in the y direct -22 pixels
ctx.fillText("This is an example to help",0,0); // draw at origin
ctx.fillText("understand the coordinate system",0,22); // next line is 22 pixels below the top
ctx.font = "10px verdana"; // change font size
ctx.fillStyle = "white"; // and colour
ctx.fillText("Move the mouse over the canvas.",0,44);
}
// clear screen update animation values, and draw the text and what not.
function update(){ // function to update the canvas
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); // clear the canvas
angle += angleDelta; // change the angle
scaleFunction(); // set the scales
useMatrix = ! useMatrix; // alternate transformation creation method.
ctx.fillStyle = "red"; // the red center
// first draw at the center of the canvas
drawAt(ctx,drawHello,ctx.canvas.width/2,ctx.canvas.height/2,1,1,0);
// now draw rotating ans scaling around the mouse
ctx.fillStyle = "black"; // black for the mouse
drawAt(ctx,drawHello,mouse.x,mouse.y,scaleX,scaleY,angle);
// set time out for the next update.
setTimeout(update,50); // refresh twenty times a second.
}
// only start if there is a canvas context to draw to.
if(ctx !== undefined){ // make sure there is something to draw to
update(); // start rendering;
}
.sofCanvas {
width:400px;
height:250px;
border: #000 solid;
background: #A4A4D1;
}
<canvas id="canvasID" class="sofCanvas" width=400 height=250>time to update your browser</canvas>
Спасибо mannn –