Спецификация HTML 5 включает множество новых функций, одной из которых является тег canvas. HTML 5 Canvas (канва HTML 5) предоставляет простой и мощный способ вывода графики и рисования с использованием JavaScript. Для каждого элемента canvas можно использовать контекст, в котором нужно вызвать команды JavaScript для рисования на Canvas. Браузеры могут реализовывать несколько контекстов элемента canvas и предоставлять различные API для рисования. Следует также помнить, что рисование происходит в растровой форме, то есть, нарисовав на канве какую-либо фигуру, её нельзя будет изменить или удалить отдельно, — можно только стереть целую область канвы.
Большинство современных браузеров предоставляют возможности 2D-контекста (2D Canvas) — Opera, Firefox, Konqueror и Safari. Кроме того существуют экспериментальные сборки браузера Opera, которые включают поддержку 3D-контекста (3D Canvas), а также дополнение к Firefox, которое реализует поддержку 3D Canvas:
В этой статье вы узнаете, как использовать 2D-контекст элемента canvas, основные функции для работы с canvas, включая линии, примитивы фигур, изображения, текст и другие возможности. При изложении материала статьи предполагается, что вы владете основами JavaScript на достаточно высоком уровне.
Основы использования Canvas
Чтобы создать Canvas-контекст, достаточно просто добавить элемент <canvas> в HTML-документ:
<canvas id="myCanvas" width="300" height="150"> Альтернативное содержимое, которое будет показано, если браузер не поддерживает Canvas. </canvas>
Нужно добавить идентификатор к элементу canvas, чтобы потом обратиться к нему в JavaScript, также необходимо задать атрибуты width и height для определения ширины и высоты элемента canvas.
Для рисования внутри элемента canvas, нужно использовать JavaScript. Сначала нужно найти созданный тег canvas с помощью функции getElementById, а потом инициализировать нужный контекст. Как только это будет сделано, можно начинать рисование на канве, используя доступные API-команды выбранного контекста. Следующий скрипт рисует простой прямоугольник на канве (просмотреть пример использования Canvas [8]):
// Получить ссылку на элемент canvas по идентификатору.
var elem = document.getElementById('myCanvas');
// Всегда проверяйте свойства и методы на доступность для обратной совместимости со старыми браузерами
if (elem && elem.getContext) {
// Получить 2D контекст.
// Запомните: вы можете инициализировать только один контекст для каждого элемента
var context = elem.getContext('2d');
if (context) {
// Теперь мы рисуем прямоугольник, задав координаты (x,y), а также его ширину и высоту.
context.fillRect(0, 0, 150, 100);
}
}
Canvas 2D API
Заливки и границы фигур
С помощью свойств fillStyle и strokeStyle вы можете легко настроить цвета, используемые для заливки и линий объектов. Значения цветов, используемые в этих методах, такие же как и в CSS: шестнадцатеричные коды (#F5E6AB), rgb(), rgba() или даже hsla(), если браузер поддерживает такой способ задания цвета (например, он поддерживается в Opera 10.00 и более новых версиях).
Используя метод fillRect, вы можете нарисовать прямоугольник с заливкой. С помощью метода strokeRect вы можете нарисовать прямоугольник только с границами, без заливки. Если нужно очистить некоторую часть канвы, вы можете использовать метод clearRect. Три этих метода используют одинаковый набор аргументов: x, y, width, height. Первые два аргумента задают координаты (x,y), а следующие два — ширину и высоту прямоугольника.
Для изменения толщины линий можно использовать свойство lineWidth. Пример использования функций fillRect, strokeRect, clearRect [9]:
context.fillStyle = '#00f'; // blue context.strokeStyle = '#f00'; // red context.lineWidth = 4; // Draw some rectangles. context.fillRect (0, 0, 150, 50); context.strokeRect(0, 60, 150, 50); context.clearRect (30, 25, 90, 60); context.strokeRect(30, 25, 90, 60);
Этот пример приведет к следующему результату:

Окружность и круг
Чтобы нарисовать окружность, нужно выполнить такой код:
context.beginPath(); context.arc(75, 75, 10, 0, Math.PI*2, true); context.closePath(); context.fill(); // Если нужен круг, можно залить окружность
Кривые Безье
Для создания кривых Безье в HTML5 Canvas можно использовать метод bezierCurveTo(). Кривые Безье задаются с помощью начальной точки, двух контрольных точек и конечной точки. В отличие от квадратичных кривых, кривые Безье в HTML 5 Canvas определяются двумя контрольными точками вместо одной, позволяя создавать кривые с более сложным очертанием.
Метод bezierCurveTo() выглядит следующим образом:
context.bezierCurveTo(controlX1, controlY1, controlX2, controlY2, endX, endY);
Пример рисования кривой Безье в HTML 5 Canvas:
window.onload = function(){
var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
context.moveTo(188, 130);
var controlX1 = 140;
var controlY1 = 10;
var controlX2 = 388;
var controlY2 = 10;
var endX = 388;
var endY = 170;
context.bezierCurveTo(controlX1, controlY1, controlX2,
controlY2, endX, endY);
context.lineWidth = 10;
context.strokeStyle = "black"; // line color
context.stroke();
};
Исполнение такого кода приведет к следующему результату:

Схема построения кривой Безье:

Контуры
Контуры Canvas позволяют рисовать фигуры любой формы. Сначала нужно нарисовать "каркас", а потом можно использовать стили линий или заливки, если это необходимо. Чтобы начать рисование контура, используется метод beginPath(), потом рисуется контур, который можно составить из линий, кривых и других примитивов. Как только рисование фигуры окончено, можно вызвать методы назначения стиля линий и заливки, и только потом вызвать функцию closePath() для завершения рисования фигуры.
Следующий код демонстрирует рисование треугольника [10]:
// Задаем свойства заливки и линий. context.fillStyle = '#00f'; context.strokeStyle = '#f00'; context.lineWidth = 4; context.beginPath(); // Начинаем рисовать треугольник с верхней левой точки. context.moveTo(10, 10); // перемещаемся к координатам (x,y) context.lineTo(100, 10); context.lineTo(10, 100); context.lineTo(10, 10); // Заполняем фигуру заливкой и применяем линии // Фигура не будет отображена, пока не будет вызван хотя бы один из этих методов. context.fill(); context.stroke(); context.closePath();
Этот пример будет отображен в браузере следующим образом:

Вы также можете посмотреть более сложные примеры контуров с использованием линий, кривых и дуг [11].
Вставка изображений в Canvas
Метод drawImage позволяет вставлять другие изображения (img и canvas) на канву. В браузере Opera также существует возможность рисования SVG-изображений внутри элемента canvas. drawImage довольно сложный метод, который может принимать три, пять или девять аргументов:
- Три аргумента: Базовое использование метода
drawImageвключает один аргумент для указания изображения, которое необходимо вывести на канве, и два аргумента для задания координат. - Пять аргументов: Используются предыдущие три аргумента и еще два, задающие ширину и высоту вставляемого изображения (в случае если вы хотите изменить размеры изображения при вставке).
- Девять аргументов: Используются предыдущие пять аргументов и еще четыре: два для координат области внутри исходного изображения и два для ширины и высоты области внутри исходного изображения для обрезки изображения перед вставкой в Canvas.
Спецификация HTML 5 объясняет эти аргументы следующим образом:

Следующий пример [12] показывает использование всех трех вариантов обращения к этому методу:
// Три аргумента: элемент img или canvas, координаты для вывода на канву (x,y). context.drawImage(img_elem, dx, dy); // Пять аргументов: элемент img или canvas, координаты для вывода на канву (x,y), // ширина и высота для изменения размеров перед выводом context.drawImage(img_elem, dx, dy, dw, dh); // Девять аргументов: элемент img или canvas, координаты, ширина и высота для обрезки изображения, // координаты для вывода на канву (x,y), ширина и высота для изменения размеров перед выводом. context.drawImage(img_elem, sx, sy, sw, sh, dx, dy, dw, dh);
Так будет выглядеть этот пример в браузере:

Манипуляции над пикселями
2D Context API предоставляет три метода, которые позволяют выполнять попиксельное рисование: createImageData, getImageData и putImageData.
Пиксели хранятся в объектах типа ImageData. Каждый объект имеет три свойства: width, height и data. Свойство data имеет тип CanvasPixelArray и содержит массив элементов размером width*height*4 байт; это означает, что каждый пиксель содержит цвет в формате RGBA. Пиксели упорядочены слева направо, сверху вниз, построчно.
Чтобы лучше понять этот механизм, рассмотрим пример отрисовки блока из красных пикселей.
// Создадим объект ImageData.
var imgd = context.createImageData(50,50);
var pix = imgd.data;
// Пройдемся по всем пикселям и зададим полупрозрачный красный цвет
for (var i = 0; n = pix.length, i < n; i += 4) {
pix[i] = 255; // red channel
pix[i+3] = 127; // alpha channel
}
// Отрисовать объект ImageData в заданных координатах (x,y).
context.putImageData(imgd, 0, 0);
Примечание: пока не все современные браузеры реализуют метод createImageData. В таких браузерах необходимо получать объект ImageData, используя метод getImageData (Пример кода для таких браузеров [13]).
Благодаря возможностям метода ImageData можно сделать очень многое. Например, можно отфильтровать изображение или создать математическую визуализацию (фракталы и т.п.). Следующий код показывает, как создать простой фильтр для инвертирования цвета изображения [14]:
// Получить массив типа CanvasPixelArray по заданным координатам и размерам.
var imgd = context.getImageData(x, y, width, height);
var pix = imgd.data;
// Обойти все пиксели изображения и инвертировать цвет.
for (var i = 0, n = pix.length; i < n; i += 4) {
pix[i] = 255 - pix[i]; // красный канал
pix[i+1] = 255 - pix[i+1]; // зеленый канал
pix[i+2] = 255 - pix[i+2]; // синий канал
// i+3 - номер элемента, содержащий альфа канал
}
// Отрисовать объект ImageData в заданных координатах (x,y).
context.putImageData(imgd, x, y);
Ниже изображен результат работы фильтра инверсии цвета, примененного к изображению.

Текст
В настоящее время Text API доступен только в последних сборках движка WebKit, а также в Firefox 3.1 и выше.
Следующие свойства текста доступны для объекта контекста:
font: Определяет шрифт текста, так же как свойствоfont-familyв CSS)textAlign: Определяет горизонтальное выравнивание текста. Допустимые значения: start, end, left, right, center. Значение по умолчанию: start.textBaseline: Определяет вертикальное выравнивание текста. Допустимые значения: top, hanging, middle, alphabetic, ideographic, bottom. Значение по умолчанию: alphabetic.
Существуют два метода для вывода текста: fillText и strokeText. Первый отрисовывает текст, заполняя его заливкой стиля fillStyle, другой рисует обводку текста, используя стиль strokeStyle. Оба метода принимают три аргумента: собственно текст и координаты (x,y), в которых его необходимо вывести. Также существует четвертый необязательный аргумент — максимальная ширина. Этот аргумент необходим для умещения текста в заданную ширину.
Свойства выравнивания текста влияют на позиционирование текста относительно координат его вывода (x,y).
Следующий код приведет к выводу на Canvas слов "hello world" [15].
context.fillStyle = '#00f';
context.font = 'italic 30px sans-serif';
context.textBaseline = 'top';
context.fillText ('Hello world!', 0, 0);
context.font = 'bold 30px sans-serif';
context.strokeText('Hello world!', 0, 50);
Так этот пример будет выглядеть в браузере:

Тени
Shadow API предоставляет четыре свойства:
shadowColor: Определяет цвет тени. Значения допустимы в том же формате, что и в CSS.shadowBlur: Определяет степень размытия тени в пикселях. Эффект очень похож на гауссово размытие в Photoshop.shadowOffsetXиshadowOffsetY: Определяет сдвиг тени в пикселях (x, y).
Пример создание тени у объекта на Canvas [16]:
context.shadowOffsetX = 5; context.shadowOffsetY = 5; context.shadowBlur = 4; context.shadowColor = 'rgba(255, 0, 0, 0.5)'; context.fillStyle = '#00f'; context.fillRect(20, 20, 150, 100);
Так будет выглядеть пример тени в браузере:

Градиенты
Свойства fillStyle и strokeStyle также могут иметь объекты CanvasGradient вместо обычных цветов CSS — это позволяет использовать градиенты для линий и заливок.
Для создания объектов CanvasGradient можно использовать два метода: createLinearGradient и createRadialGradient. Первый метод создает линейный градиент, а второй — радиальный градиент.
Как только создан объект градиента, можно добавлять в него цвета с помощью метода addColorStop.
Следующий пример показывает, как использовать градиенты:
// Нужно указать начальные и конечные координаты (x,y) градиента var gradient1 = context.createLinearGradient(sx, sy, dx, dy); // Теперь можно добавлять цвета в градиент // Первый градиент определяет позицию для цвета в градиенте. // Допустимы значения от 0 (начало градиента) до 1 (конец градиента). gradient1.addColorStop(0, '#f00'); // красный gradient1.addColorStop(0.5, '#ff0'); // желтый gradient1.addColorStop(1, '#00f'); // синий // Для радиального градиента также нужно указать радиус // внутренней и внешней окружности градиента. // Координаты (x,y) определяют центры этих окружностей. var gradient2 = context.createRadialGradient(sx, sy, sr, dx, dy, dr);
Ниже показан более сложный пример [17], в котором использованы линейный градиент, тени и текст:

Примеры использования Canvas
Следующие проекты реализуют множество разных возможностей Canvas:
- Рисование графиков: полином Ньютона [18]
- 3D-шутер - "3D Walker" [19]
- Paint.Web - простой графический редактор [20]
- Полет звезд [21]
- Физика объектов на Canvas [22]
Выводы
Canvas — одна из самых интересных возможностей HTML 5, которую уже можно использовать во многих современных браузерах. Canvas предоставляет возможности для создания игр и пользовательских интерфейсов совершенно нового уровня. 2D context API включает в себя множество функций, часть из которых не была описана в этой статье, но я надеюсь, вы получили все знания, необходимые для начала работы с Canvas.
Статья основана на публикации "HTML 5 canvas - the basics" [23].

Комментарии
Вот не плохая статья о video и canvas в HTML5, возможно будет интересна www.clearboth.ru/article/video-canvas-magic.html
Еще добавьте как нарисовать кривые и окружность, и ваше статья будет восхитительна
По просьбам читателей: добавлены примеры создания окружности и кривой Безье.
А как отменить сглаживания отрисовки линий.
Так как бывает требуеться четко выразить тонкую линию
Вы можете написать собственную функцию рисования линий с помощью функций API
В Firefox должен работать код отключения сглаживания:
contextXYZ.mozImageSmoothingEnabled=false;В Chrome и Safari должен помочь код:
context.moveTo(x1, y1);
context.lineTo(x2, y2);
context.stroke();
Но не нужно использовать
context.beginPath()Canvas переводится как ХОЛСТ а не как "канва"!
Всем привет. Есть такой вопрос... Нарисовал на канвасе большое изображение, используется как фон (4900х3900 примерно). При помощи jquery уменьшаю его и обрезаю под экран клиента. Всё бы супер и классно. chromium,firefox,ie9,opera - делают всё супер быстро и красиво. Касяк возникает только с Google chrome (основанный на chromium). В кратце, на старых Chrom'ax всё тоже летает быстро (на старых отключён canvas 2d accelerator), а вот в новом (18 версия, где canvas 2d accelerator включили), нереально тормозит. Хотя по идеи accelerator должен был бы ускорять, а тут наоборот. Тестил 3d, с ним 18 версия работает быстрее. Что не так может быть с 2d? Кто-то может сталкивался? Может я что-то не то делаю ? Код имеет примерно следующий вид:
function drawcanvas(dark,light) { var canvas = document.getElementById('canvas'); if (canvas && canvas.getContext) { canvas.width = canvaswidth; canvas.height = canvasheight; var c = canvas.getContext('2d'); if(c) { c.beginPath();c.moveTo(1576,1028);c.lineTo(1966,1031);c.lineTo(3083,3515);c.lineTo(4162,1028);c.lineTo(4527,1028);c.lineTo(3267,3929);c.lineTo(2904,3929);c.lineTo(1576,1028);c.fillStyle=dark;c.fill();c.closePath(); c.beginPath();c.moveTo(0,1028);c.lineTo(435,1028);c.lineTo(1513,3508);c.lineTo(2593,1028);c.lineTo(2957,1028);c.lineTo(1698,3929);c.lineTo(1330,3929);c.lineTo(0,1028);c.fillStyle=light;c.fill();c.closePath(); //... } } else { setw(); //если не работает canvas 2d, подключать png версию. } }Может кто подсказать, как нарисовать фигуру по точкам (lineTo,curveTo), и после этого повернуть ее относительно ее центра (width/2,height/2)..
Статья очень устарела. Стоит ее освежить некоторыми подрбностями, которые уже реализованы.
Задрали эти примеры!!! Как их понять и зачем они?!! Где описание методов canvas??? Что делает функция fillRect(10,40,65,65)?.... Где взять нужные мне функции? Вы же не собираетесь написать за меня все программы (это невозможно) и поместить на сайт. А как мне их создать, если нигде не найти перечня свойств canvas?
Ура!! Наконец-то
Ребята! А можете с контрольными точками сделать пример, чтобы можно было визуально делать кривые, то есть "дергать за ниточки" так сказать.
Доступен перевод спецификации Canvas на русский: http://topolyan.com/w3c/html_canvas_2d_context_ru.html [24].
А можно фигуры в канвас сделать ссылками? Прямоугольник, например