Pull to refresh

HTML5 Canvas: rotate и translate на примере

Reading time 2 min
Views 43K
Здравствуйте, уважаемые Хаброюзеры! В своём дебютном посте, я хотел бы рассказать о такой замечательной и интересной штуке, как HTML5 Canvas, а точнее о функциях контекста, которые по моему мнению, освещены меньше всего — transform и rotate.
Когда я начинал свои эксперименты и копания в области новомодного канваса, в рунете была всего одна статья внятно объясняющая, как нужно вертеть рисунки на холсте. Более-менее понять смысл загадочного Java Script'a я смог только «полопатив» исходники Tululoo HTML5 Game Maker.

Итак, со вступлением закончил, давайте пожалуй начнем. А начнем мы пожалуй, со вращения…

rotate()

Эта функция в качестве единственного аргумента принимает угол в радианах. Все что отрисовывается после выполнения этого метода будет повернуто на заданный угол относительно начала координат. Понятно? Нет? Плохо… Давайте будем рассматривать ситуация на конкретном примере: нужно нарисовать прямоугольник заданного размера, в заданных координатах, причем фигура должна быть повернута вокруг своей оси на опять-таки заданный угол.
Давайте начнем с такого кода:
function inRad(num) {
	//я ведь говорил, что функция принимает угол в радианах?
	return num * Math.PI / 180;
}

//описываем наш прямоугольник
var rectX = 100, rectY = 100, rectW = 100, rectH = 100, rectAngle = 45;

//получаем канвас и контекст
var cnv = document.getElementById('canvas');
var ctx = cnv.getContext('2d');	

//рисуем «фон»
ctx.fillStyle = '#8080FF';
ctx.fillRect(0, 0, 300, 300);

//самое интересное — крутим контекст и...
ctx.rotate(inRad(45));
//...рисуем наш прямоугольник
ctx.fillStyle = '#804000';
ctx.fillRect(rectX, rectY, rectW, rectH);

Вот результат:

Не совсем соответствует ожиданиям, верно? А всё почему? А потому что: « Все что отрисовывается после выполнения этого метода будет повернуто на заданный угол относительно начала координат», а по условию задачи нужно: «фигура должна быть повернута вокруг своей оси». Вывод — нужно изменить точку вокруг которой будет происходит вращение, а точнее точку начала координат. Звучит несколько хаотично, ведь все мы привыкли, что (0; 0) находится в верхнем левом углу… Так мы подошли к следующему пункту нашей статьи.

translate()

Надеюсь все уже догнали, что translate изменяет позицию точки начала координат, если нет, то говорю — translate изменяет позицию точки начала координат:) Тоесть точки, вокруг которой в данном случае происходит вращение. Не буду долго мучать — выкладываю исправленный код нашего задания:
function inRad(num) {
	return num * Math.PI / 180;
}

var rectX = 100, rectY = 100, rectW = 100, rectH = 100, rectAngle = 45;

var cnv = document.getElementById('canvas');
var ctx = cnv.getContext('2d');	

ctx.fillStyle = '#8080FF';
ctx.fillRect(0, 0, 300, 300);

ctx.translate(rectX, rectY);
ctx.rotate(inRad(45));
ctx.fillStyle = '#804000';
ctx.fillRect(-rectW/2, -rectH/2, rectW, rectH);

Что за странные аргументы у fillRect? А это вам пища для ума:)
Сохраняем скрипт, дабл клик по index.html и та-да! Итог мучений:


Надеюсь хоть кому-нибудь статья поможет пролить свет на этот загадочный канвас со всеми вытекающими.
P. S.: Следующий урок(и) намерен посвятить созданию нормального спрайтового движка с сортировкой по глубине. Стоит ли писать? Читать кто будет?
Продолжение.
Tags:
Hubs:
-1
Comments 7
Comments Comments 7

Articles