Вращение
Перемещение
Сохранение и восстановление контекста
Масштабирование
Функция setTransform()
Вращение вызывается функцией rotate().
<canvas id="rotate_demo" width="300" height="250" style = "border:2px solid black"></canvas>
<script>
var canvas = document.getElementById("rotate_demo");
var context = canvas.getContext("2d");
var angle = 40; // угол поворота
context.fillStyle = "silver";
context.fillRect(0, 0, canvas.width, canvas.height);
context.translate(canvas.width / 2, canvas.height / 2);
drawBezier(angle, "darkturquoise");
drawBezier(angle, "deeppink");
drawBezier(angle, "gold");
drawBezier(angle, "mediumvioletred");
drawBezier(angle, "yellow");
drawBezier(angle, "teal");
drawBezier(angle, "chartreuse");
drawBezier(angle, "magenta");
drawBezier(angle, "red");
function drawBezier(angle, color)
{
context.fillStyle = color;
context.lineWidth = 7;
context.shadowOffsetX = 3;
context.shadowOffsetY = 3;
context.shadowBlur = 5;
context.shadowColor = "gray";
var xStart = 0;
var yStart = 0;
var xControl1 = 90;
var yControl1 = 20;
var xControl2 = -60;
var yControl2 = 60;
var xEnd = 60;
var yEnd = 60;
// переводим градусы в радианы
var angleInRadians = angle * Math.PI/180;
context.rotate(angleInRadians);
context.beginPath();
context.moveTo(xStart, yStart);
context.bezierCurveTo(xControl1, yControl1,
xControl2, yControl2,
xEnd, yEnd);
context.fill();
}
</script>
Объекты на холсте можно перемещать с помощью функции translate(). Сама функция применяется к контексту холста и имеет два параметра - новые значения координат для перемещения. В примере нарисуем серый квадрат в точке 0,0. Затем остальные квадраты будем рисовать в новых позициях. При этом предыдущий сдвиг запоминается и перемещение происходит относительно новой позиции.
<canvas id="translate_demo" width="500" height="170" style = "border:2px solid black">Ваш браузер не поддерживает canvas</canvas>
<script>
var canvas = document.getElementById("translate_demo");
var context = canvas.getContext("2d");
// Размер стороны квадрата
var size = 40;
drawSquare( 0, 0, "gray" );
drawSquare( size, size, "red" );
drawSquare( size, size, "orange");
drawSquare( size, -size, "blue" );
drawSquare( size, 0, "pink" );
drawSquare( size, -size, "purple");
drawSquare( 2 * size, size, "green" );
function drawSquare(translateH, translateV, color)
{
context.fillStyle = color;
context.translate(translateH, translateV);
context.fillRect(0, 0, size, size);
}
</script>
В некоторых ситуациях подобное поведение, когда состояние сдвига запоминается, бывает неудобным. Чтобы решить проблемы, используют пару функций save() и restore().
Если какое-то свойство контекста изменить, то оно повлияет на все последующие. Есть два метода контекста save() и restore(), которые сохраняют и восстанавливают последнее сохраненное состояние. Мы можем не сбрасывать все свойства на начальные, а просто вызывать эти функции.
context.save();
context.textAlign = 'center';
context.font = "bold italic 30px sans-serif";
context.strokeText("Hello Kitty", 300, 300);
context.restore();
context.fillText("Hello Kitty", 400, 400);
Функции можно вызывать несколько раз в разных местах. Все состояния будут запоминаться в массиве и восстанавливаться при вызове парной функции restore(). Главное, не запутаться в них.
Масштабирование производится через функцию scale(). Для примера воспользуемся сохранением и восстановлением контекста.
<canvas id="scale_demo" width="500" height="170" style = "border:2px solid black">Ваш браузер не поддерживает canvas</canvas>
<script>
var canvas = document.getElementById("scale_demo");
var context = canvas.getContext("2d");
drawSquare(25, 25, 1.4, 1.4, "gray", true);
drawSquare(25, 25, 1.0, 1.1, "red", true);
drawSquare(25, 25, 0.7, 0.7, "orange", true);
drawSquare(100, 25, 1.4, 1.4, "blue", false );
drawSquare(100, 25, 1.0, 1.1, "pink", true);
drawSquare(100, 25, 0.7, 0.7, "purple", false);
function drawSquare(xPos, yPos, scaleH, scaleV, color, save)
{
if (save) {
context.save();
}
context.fillStyle = color;
var size = 40;
context.translate(xPos, yPos);
context.scale(scaleH, scaleV);
context.fillRect(0, 0, size, size);
if(save){
context.restore();
}
}
</script>
Собственный метод drawSquare() имеет последний параметр save, который указывает, нужно ли запоминать состояние контекста. При рисовании первых трёх квадратов мы запоминали состояние контекста и все фигуры рисовались относительно одной точки (0.0). Затем выводим синий квадрат уже со смещением, присвоив значение false для запоминания контекста. Следующий розовый квадрат также смещается от текущей точки синего квадрата, а затем фиолетовый квадрат никуда не смещается, а только масштабируется.
Сочетание функций translate() и scale() позволяет сделать зеркальное отображение.
<canvas id="mirror_demo" width="300" height="240" style ="border:2px solid black">Ваш браузер не поддерживает canvas</canvas>
<script>
window.onload = function() {
var canvas = document.getElementById('mirror_demo');
var context = canvas.getContext('2d');
var image = new Image();
var xPos = 75;
var yPos = 15;
var imageWidth = 90;
var imageHeight = 90;
var reflectY = (2 * yPos) + (2 * imageHeight + 1.5);
image.onload = function() {
context.drawImage(image, xPos, yPos, imageWidth, imageHeight);
context.translate(0, reflectY);
context.scale(1, -1);
context.drawImage(image, xPos, yPos, imageWidth, imageHeight);
};
image.src = '../images/star.jpg';
}
</script>
Вызов context.scale(1, -1) поворачивает изображение по вертикали.
Специальная функция setTransform() позволяет объединить несколько видов трансформации.
setTransform(scaleX, skewY, skewX, scaleY, translateX, translateY)
В шести параметрах функции вы указываете коэффициенты масштабирования, сдвига и перемещения.