Спецификация 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):
// Получить ссылку на элемент 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:
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()
для завершения рисования фигуры.
Следующий код демонстрирует рисование треугольника:
// Задаем свойства заливки и линий. 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();
Этот пример будет отображен в браузере следующим образом:
Вы также можете посмотреть более сложные примеры контуров с использованием линий, кривых и дуг.
Вставка изображений в Canvas
Метод drawImage
позволяет вставлять другие изображения (img
и canvas
) на канву. В браузере Opera также существует возможность рисования SVG-изображений внутри элемента canvas
. drawImage
довольно сложный метод, который может принимать три, пять или девять аргументов:
- Три аргумента: Базовое использование метода
drawImage
включает один аргумент для указания изображения, которое необходимо вывести на канве, и два аргумента для задания координат. - Пять аргументов: Используются предыдущие три аргумента и еще два, задающие ширину и высоту вставляемого изображения (в случае если вы хотите изменить размеры изображения при вставке).
- Девять аргументов: Используются предыдущие пять аргументов и еще четыре: два для координат области внутри исходного изображения и два для ширины и высоты области внутри исходного изображения для обрезки изображения перед вставкой в Canvas.
Спецификация HTML 5 объясняет эти аргументы следующим образом:
Следующий пример показывает использование всех трех вариантов обращения к этому методу:
// Три аргумента: элемент 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
(Пример кода для таких браузеров).
Благодаря возможностям метода ImageData
можно сделать очень многое. Например, можно отфильтровать изображение или создать математическую визуализацию (фракталы и т.п.). Следующий код показывает, как создать простой фильтр для инвертирования цвета изображения:
// Получить массив типа 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".
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:
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);
Ниже показан более сложный пример, в котором использованы линейный градиент, тени и текст:
Примеры использования Canvas
Следующие проекты реализуют множество разных возможностей Canvas:
- Рисование графиков: полином Ньютона
- 3D-шутер - "3D Walker"
- Paint.Web - простой графический редактор
- Полет звезд
- Физика объектов на Canvas
Выводы
Canvas — одна из самых интересных возможностей HTML 5, которую уже можно использовать во многих современных браузерах. Canvas предоставляет возможности для создания игр и пользовательских интерфейсов совершенно нового уровня. 2D context API включает в себя множество функций, часть из которых не была описана в этой статье, но я надеюсь, вы получили все знания, необходимые для начала работы с Canvas.
Статья основана на публикации "HTML 5 canvas - the basics".
Комментарии
Вот не плохая статья о 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? Кто-то может сталкивался? Может я что-то не то делаю ? Код имеет примерно следующий вид:
Может кто подсказать, как нарисовать фигуру по точкам (lineTo,curveTo), и после этого повернуть ее относительно ее центра (width/2,height/2)..
Статья очень устарела. Стоит ее освежить некоторыми подрбностями, которые уже реализованы.
Задрали эти примеры!!! Как их понять и зачем они?!! Где описание методов canvas??? Что делает функция fillRect(10,40,65,65)?.... Где взять нужные мне функции? Вы же не собираетесь написать за меня все программы (это невозможно) и поместить на сайт. А как мне их создать, если нигде не найти перечня свойств canvas?
Ура!! Наконец-то
Ребята! А можете с контрольными точками сделать пример, чтобы можно было визуально делать кривые, то есть "дергать за ниточки" так сказать.
Доступен перевод спецификации Canvas на русский: http://topolyan.com/w3c/html_canvas_2d_context_ru.html.
А можно фигуры в канвас сделать ссылками? Прямоугольник, например