HTML 5 Canvas для начинающих

Версия для печатиВерсия для печати

Спецификация 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);

Этот пример приведет к следующему результату:

Пример использования fillRect, strokeRect, clearRect &mdash; результат в браузере

Окружность и круг

Чтобы нарисовать окружность, нужно выполнить такой код:

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();
};

Исполнение такого кода приведет к следующему результату:

Кривая Безье

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

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

Контуры

Контуры 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 объясняет эти аргументы следующим образом:

Аргументы метода drawImage

Следующий пример показывает использование всех трех вариантов обращения к этому методу:

// Три аргумента: элемент 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);

Так будет выглядеть этот пример в браузере:

Пример использования метода drawImage для вставки картинки в канву

Манипуляции над пикселями

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);

Ниже изображен результат работы фильтра инверсии цвета, примененного к изображению.

Фильтр инвертирования цвета с помощью Canvas

Текст

В настоящее время 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);

Так этот пример будет выглядеть в браузере:

Пример вывода текста на Canvas

Тени

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);

Так будет выглядеть пример тени в браузере:

Пример тени в Canvas - синий прямоугольник с красной тенью

Градиенты

Свойства 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".

 

Ваша оценка: Нет Средняя: 9.2 (93 голосов)

Комментарии

Вот не плохая статья о 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.

А можно фигуры в канвас сделать ссылками? Прямоугольник, например

На правах рекламы: Картонная тара - на лучших условиях от proletarii.ru.