Познаю html5 canvas. Делюсь.
Напомню, что в html5 есть тег canvas, позволяющий отображать графику в браузере без подключения каких-либо дополнительных плагинов и управляемый через JavaScript API. Недавно я, в очередной раз наткнувшись на него, решил посмотреть, что же это за зверь и как его готовить. В этом посте хочу поделиться собранной информацией и опытом. Статья нацелена в основном на тех, кто только "где-то слышал о canvas, и вроде даже видел пару примеров", но ещё не успел пощупать и понять зачем оно вообще надо.
Плюсы.
Как уже было сказано в предисловии, для отображения canvas'а необходим лишь современный браузер, ничего дополнительного пользователю подключать не придется. А для разработки под него - только редактор и знания javascript. Так же, нахожу большим плюсом то, что описывая с помощью javascript графику, мы можем пользоваться всеми данными, доступными на странице: размеры окна, информация о браузере, клиентские события, DOM...
Производительность.
Собсно, вот. Пошаманив, можно достичь 900+ FPS. Отгадка в тестовой версии Opera 11.50 с GPU ускорением. То есть, производительность на хорошем уровне, и будет расти с развитием технологий.
Javascript API.
Для доступа к двухмерному контексту рисования canvas'а, нам нужно лишь вызвать метод getContext() DOM-елемента. Вот так, например:
var context = document.getElementById('canvas_tag_id').getContext('2d');
Методы и свойства можно посмотреть тут.
Рисование.
Отмечу, что набор рисования минимален, только необходимые базовые вещи. Из фигур это: дуга, прямоугольник, линии, кривые. Например, чтобы нарисовать окружность, нужно нарисовать замкнутую дугу.
Для вращения нарисованной фигуры, вы должны повернуть весь холст (прямого способа повернуть фигуру нет), нарисовать нужную фигуру и затем повернуть холст обратно. Вы можете также смещать начальные координаты холста. Есть методы для сохранения положения холста и возвращения его к сохраненному состоянию. Имеется поддержка отображения текста, добавления изображений.
Метод clearRect() очищает прямоугольную область холста.
Надо сказать, что API не совсем удобно - параметров у метода может быть и 9 штук:
context.drawImage(imageObj, sourceX, sourceY, sourceWidth,sourceHeight, destX, destY, destWidth, destHeight);
разбираться в таком коде, конечно, не очень приятно. Имхо, куда удобнее было бы передавать объект:
context.drawImage({
img: imageObj,
x: sourceX,
y: sourceY,
sw: sourceWidth,
sh: sourceHeight,
dx: destX,
dy: destY,
dw: destWidth,
dh: destHeight
)};
Эту проблему решают фреймворки, обзор их приводить не стану, сами погуглите, если нужно, или напишите свой.
Анимация.
Наверное, самая большая важная и интересная сторона canvas'а.
Если вы делали анимацию c помощью Adobe Flash, то помните, что можете просто изменять положение объекта на сцене или его внешний вид, изменяя соответствующие параметры. Здесь же придется перерисовывать всё заново, то есть, например, для анимации движения, вам каждый кадр нужно очищать старое положения и рисовать новое.
Так как есть нативная поддержка рисования всего изображения или только определенной его области - анимация на спрайтах реализовывается просто и быстро.
Очистка всего холста с помощью clearRect() - дорогой процесс, и если вы будете чистить весь холст каждый кадр, то сразу же упретесь в вопрос производительности. Поэтому, главное правило здесь - перерисовывайте только то, что изменилось. Популярным решением является наложение нескольких прозрачных холстов друг на друга, для отрисовки статичных элементов на заднем холсте и часто изменяющихся на переднем. Опять же, фреймворки могут послужить вам хорошими помощниками в этом, но могут и наоборот совершать лишние очистки холста при неправильном использовании.
Физика.
Имеются физические движки на javascript, на хабре можно найти список.
3D.
Да, можно рисовать и в 3D. В сети есть множество примеров. Описывать в рамках поста не буду.
Что у меня получилось.
Посмотрев на этот и этот примеры, мне тоже захотелось "заанимировать" какие-нибудь мелкие частицы. На следующий день у меня что-то уже получилось, но это жрало до 70% моего процессора, и я взялся за оптимизацию. Отказавшись от обоих опробованных фреймворков, и потратив все новогодние праздники, мне удалось чего-то добиться. Правда оно вешает напрочь firefox под ubuntu, при этом в остальных браузерах, в том числе и в виндовой версии ФФ, нагрузки вполне приемлемы. Об этом, оказалось, написано в багтрекере мозиллы.
А вот и ссылка.
P.S. Если почитать интернет, то почти под каждой статьей о canvas - разгорается холивар canvas vs. svg, но я прошу читателей сделать этот пост исключением.
|
Спасибо за статью. Исправь мелкую опечатку в строке
var context = document.getElementById('canvas_tag_id').detContext('2d')
опечатка в названии метода .getContext()