Смещение, масштабирование и поворот координатной сетки
По умолчанию координатная сетка холста <canvas>
имеет начало координат в левом верхнем углу, ось абсцисс направлена вправо, ось ординат вниз, а масштабный коэффициент равен одному пикселю. JavaScript имеет ряд функций, которые позволяют манипулировать координатной сеткой.
Но прежде чем перейти к методам преобразования, рассмотрим две важные функции, которые необходимы, для быстрого сохранения и восстановления текущих настроек координатной сетки.
Метод save() - сохраняет все состояние холста.
Метод restore() восстанавливает последнее сохранённое состояние холста.
Состояние холста сохраняется в стеке. Каждый раз, когда вызывается метод save(), текущее состояние отрисовки записывается в стек.
Состояние отрисовки содержит:
- Трансформации, которые были применены (например, translate, rotate and scale – см. ниже).
- Текущее значение следующих атрибутов: strokeStyle, fillStyle, globalAlpha, lineWidth, lineCap, lineJoin, miterLimit, lineDashOffset, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor, globalCompositeOperation, font, textAlign, textBaseline, direction, imageSmoothingEnabled.
Перед выполнением каких-либо преобразований рекомендуется сохранить состояние холста. В большинстве случаев проще вызвать restore метод, чем выполнять обратный перевод для возврата в исходное состояние.
Параллельный перенос (смещение) координатной сетки:
translate(x, y) - перемещение холста на сетке. x и y - смещение по горизонтали и вертикали соответственно.
Поворот координатной сетки:
rotate(angle) - поворачивает холст по часовой стрелке вокруг начальной точки на угол anglе в радианах.
Масштабирование координатной сетки:
scale(x, y) - масштабирует единицы холста по x по горизонтали и по y по вертикали. Оба параметра являются действительными числами. Значения меньше 1,0 уменьшают размер блока, а значения выше 1,0 увеличивают размер блока.
По умолчанию одна единица на холсте равна одному пикселю. Если применить коэффициент масштабирования 0,5, результирующая единица измерения станет равной 0,5 пикселя, а фигуры будут отображаться в два раза меньше. Аналогичным образом установка коэффициента масштабирования на 2,0 увеличила бы размер единицы, и теперь одна единица становится двумя пикселями. Это приводит к тому, что фигуры рисуются в два раза больше.
Используя отрицательные числа, можно зеркально отразить оси.
Например,
ctx.translate(0, canvas.height); ctx.scale(1,-1);
позволит работать с привычной со школы декартовой системой координат, у которой начало в левом нижнем углу.
Пример использования всех трех методов:
var obj = document.getElementById('drawing'); // Получить объект холста if (obj.getContext){ var ctx = obj.getContext('2d'); ctx.translate(200,300); // сдвиг оси координат ctx.scale(10,10); // увеличение в 10 раз ctx.rotate(-Math.PI/6); // поворот против часовой стрелки на 30 градусов ctx.fillStyle = "rgb(0,0,200)"; ctx.fillRect (4, 4, 8, 6); }
Универсальный метод, основанный на матрице преобразований (см. Лекцию "Операции преобразования на плоскости"), позволяющий применить сразу несколько преобразований:
transform(a, b, c, d, e, f) - накладывает матрицу преобразований, заданную параметрами, на текущую матрицу. Матрица преобразования задаётся следующим образом:
$$\begin{pmatrix}
a & c & e \\
b & d & f \\
0 & 0 & 1 \\
\end{pmatrix}
$$
setTransform(a, b, c, d, e, f) - сбрасывает текущую матрицу преобразования, а затем вызывает transform() в соответствии с аргументами.
resetTransform() - сбрасывает текущую матрицу преобразования к значению по умолчанию. Аналогично вызову ctx.setTransform(1, 0, 0, 1, 0, 0).
Пример построения точно такого же преобразования, как показано выше, используя всего один метод setTransform:
var obj = document.getElementById('drawing'); // Получить объект холста if (obj.getContext){ var ctx = obj.getContext('2d'); // ctx.translate(200,300); // ctx.scale(10,10); // ctx.rotate(-Math.PI/6); ctx.setTransform(10*0.86, -0.5*10, 0.5*10, 10*0.86, 200, 300); ctx.fillStyle = "rgb(0,0,200)"; ctx.fillRect (4, 4, 8, 6); }