Canvas (HTML)

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск
 Просмотр этого шаблона  HTML

Canvas (англ. canvas — «холст», рус. канва́с) — элемент HTML5, предназначенный для создания растрового двухмерного изображения при помощи скриптования, обычно на языке JavaScript[1]. Начало отсчета блока находится слева сверху. От него и строится каждый элемент блока[2]. Размер пространства координат не обязательно отражает размер фактической отображаемой площади[2]. По умолчанию его ширина равна тремстам пикселям, а высота ста пятидесяти[2].

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

Используется в WebGL для аппаратного ускорения 3D графики[3].

Компанией Google была выпущена JavaScript библиотека explorercanvas, которая позволяла работать с Canvas в браузерах IE7 и IE8.

Canvas может усложнить задачу роботам по распознаванию Капчи. При использовании canvas с сервера загружается не картинка, а набор точек (или алгоритм прорисовки), по которым браузер прорисовывает картинку (капчу).[4]

История[править | править вики-текст]

Впервые элемент canvas был представлен компанией Apple в движке WebKit для Mac OS X с целью последующего его использования в приложениях Dashboard и Safari[1].

Ситуацию с отсутствием canvas в IE исправила компания Google, выпустившая собственное расширение, написанное на JavaScript, под названием ExplorerCanvas[5].

На сегодняшний день canvas чаще используется для построения графиков, простой анимации и игр в браузерах[6]. Группа WHATWG предлагает использовать canvas как стандарт для создания графики в новых поколениях веб-приложений[7].

Организация Mozilla Foundation ведёт проект под названием Canvas 3D[8], целью которого является добавить низкоуровневую поддержку графических ускорителей для отображения трёхмерных изображений через HTML-элемент canvas. Наряду с этим существуют библиотеки, реализующие работу с трехмерными моделями, среди них three.

Поддержка[править | править вики-текст]

IE Firefox Safari Chrome Opera iPhone Android
9.0+ 3.0+ 3.0+ 3.0+ 10.0+ 1.0+ 1.0+

Возможности[править | править вики-текст]

canvas позволяет разместить на холсте: картинку, видео, текст. Залить всё это сплошным цветом, либо обвести контуры или даже добавить градиент[9]. Добавление теней похожих на свойства css3 box-shadow и text-shadow. И, наконец, отрисовка фигур с помощью указания контрольных точек. Причём, можно изменять как ширину линий, так и кисть рисовки линий, стиль соединений линий[10]

API[править | править вики-текст]

Ниже приводится полная документация в формате таблицы с методами или Параметрами слева и описанием справа[11].

Большинство библиотек использует API SVGMatrix объектов, а не этот, который остается, главным образом, по историческим причинам[2].

Параметры canvas[править | править вики-текст]

Параметры canvas
Метод / параметр Описание Пример
.width [ = value ] Возвращает ширину холста в пикселях
canvas.width = 900px
.height [ = value ] Возвращает высоту холста в пикселях
canvas.height = 900px

Получение canvas[править | править вики-текст]

Получение canvas
Метод / параметр Описание Пример
.getContext( '2d' ) Вернет объект двумерного контекста. 'webgl' вернет объект WebGLRenderingContext
var context = canvas.getContext( '2d' );
.probablySupportsContext( contextId ) Если .getContext() был вызван вернет false, true в противном случае
if (canvas.probablySupportsContext( contextId ))
{
    context = canvas.getContext('2d');
}
.setContext( context ) Устанавливает контекст канвы
context.setContext( context )
.transferControlToProxy() Вернет объект, позволяющий передать управление другому документу. Выдаст исключение, если использовались .getContext() и .setContext()
context.transferControlToProxy()

Работа с context[править | править вики-текст]

Работа с context
Метод / параметр Описание Пример
.canvas() Вернет canvas, если контекст был получен через getContext()
var canvas = context.canvas();
.commit() Отображает кадр из буфера
context.commit();
.save() Сохраняет текущие настройки в стек
context.save();
.restore() Достает из стека настройки отображения канвы
context.restore();
.lineWidth [ = value ] Возвращает текущую ширину линии
context.lineWidth = 100;
.lineCap [ = value ] Возвращает тип начертательного пера
context.lineCap = "butt";
.lineJoin [ = value ] Возвращает строку со стилем
context.lineJoin = "round"
.miterLimit [ = value ] Толщина соединения линий
context.miterLimit = 40
.setLineDash( template ) Устанавливает шаблон штрихов линии
context.setLineDash
.getLineDash() Возвращает установленный шаблон штрихов линии
context.lineJoin
.lineDashOffset [ = value ] Возвращает отступ от линии
context.lineDashOffset = 4;

Работа со шрифтом[править | править вики-текст]

Работа со шрифтом
Метод / параметр Описание Пример
.font [ = value ] Возвращает настройки шрифта, аналогично css правилу
context.font = "normal 16pt Sans-Serif";
.textAlign [ = value ] Возвращает выравнивание текста
context.textAlign = "center";
.textBaseline [ = value ] Возвращает настройки базовой линии
context.textBaseline = "top";
.direction [ = value ] Возвращает текущее направление текста
context.direction = "ltr";
.fillText() Рисует закрашенный текст
context.fillText()
.strokeText() Рисует контур текста
context.strokeText()
.addText(text, styles, transform, x, y [, maxWidth ]) Рисует указанный текст
context.addText("Hello, World!", "normal 16pt Sans", svgtrans, 90, 10)
.addPathByStrokingText(text, styles, transform, x, y [, maxWidth ]) Рисует указанный текст
context.addPathByStrokingText("Hello, World!", "normal 16pt Sans", svgtrans, 90, 10)

Отрисовка фигур[править | править вики-текст]

Отрисовка фигур
Метод / параметр Описание Пример
.moveTo( x, y ) Перемещает точку в указанное место
context.moveTo(20, 20)
.beginPath() Начать строить фигуру
context.beginPath()
.closePath() Замкуть контур фигуры
context.closePath()
.lineTo( x, y ) Связывает две точки между собой
context.lineTo(20, 20)
.rect( x, y, width, height ) Рисует прямоугольник
context.rect(20, 20, 300, 400)
.arc( x, y, radius, startAngle, endAngle [, anticlockwise ] ) Рисует окружность
context.arc(20, 20, 500, 0, 50)
.quadraticCurveTo( cpx, cpy, x, y ) Кривая Безье по двум точкам
context.quadraticCurveTo(20, 20, 40, 50)
.ellipse( x, y, radiusX, radiusY, rotation, startAngle, endAngle [, anticlockwise] ) Рисует эллипс
context.ellipse(20, 20, 40, 90, 9, 0, 50)
.BezierCurveTo( cp1x, cp1y, cp2x, cp2y, x, y ) Создает кривую Безье по трем точкам
context.BezierCurveTo(20, 20, 90, 90, 50, 50)
.ArcTo(x1, y1, x2, y2, radiusX [, radiusY, rotation ]) Рисует дуги по контрольным точкам
context.ArcTo(20, 20, 20, 20, 20)
.fillStyle [ = value ] Указывает стиль заливки контура фигуры
context.fillStyle = "black";
.strokeStyle [ = value ] Указывает стиль контура фигуры
context.strokeStyle = "black";
.clearRect( x, y, width, height ) Очищает прямоугольник (делает белым)
context.clearRect(20, 20, 90, 80)
.fillRect() Рисует закрашенный прямоугольник
context.fillRect()
.strokeRect() Рисует контур прямоугольника
context.strokeRect()
.fill() Закрасить все фигуры
context.fill();
.stroke() Обвести все фигуры
context.stroke();
.drawImage( img, x, y, width, height [, scaleWidth, scaleHeight] ) Нарисовать изображение
context.drawImage(img, 20, 20, 90, 90);

Пути[править | править вики-текст]

Пути
Метод / параметр Описание Пример
.addPath( path, transform ) Добавляет объект Path указанный в аргументе
context.addPath(path, transform);
.addPathByStrokingPath( path, styles, transform ) Добавляет объект Path указанный в аргументе с возможностью указание стиля отрисовки
context.addPathByStrokingPath(path, "black", transform );
.currentTransform [ = value ] Возвращает SVG-образную матрицу трансформации
var svg = context.currentTransform;
.translate( x, y ) Сдвигает изображение
context.translate(20, 20);
.setTransform( a, b, c, d, e, f ) Изменяет изображение
context.setTransform(1, 1, 40, 40, 5, 5)
.addColorStop( offset, color ) Добавляет конечный цвет заливки градиента с указанием смещения от начала
context.addColorStop(80, "#ccc");
.createLinearGradient( x0, y0, x1, y1 ) Cоздает объект линейного градиента
context.createLinearGradient(20, 20, 40, 40);
.createRadialGradient( x0, y0, r0, x1, y1, r1 ) Cоздает объект кругового градиента
context.createRadialGradient(0, 0, 20, 40, 40, 20);
.createPattern() Cоздает объект шаблона
var pat = context.createPattern();
.setTransform() Устанавливает трансформацию
context.setTransform();

Метрики[править | править вики-текст]

Метрики
Метод / параметр Описание Пример
.measureText() Возвращает объект с метриками текста
context.measureText();
.actualBoundingBoxLeft() Вернет горизонтальную координату левой стороны прямоугольника занимаемого текстом
context.actualBoundingBoxLeft();
.actualBoundingBoxRight() Вернет горизонтальную координату правой стороны прямоугольника занимаемого текстом
context.actualBoundingBoxRight();
.fontBoundingBoxAscent() Расстояние от горизонтальной линии (TextBaseline), до вершины прямоугольника ограничивающего текст
context.fontBoundingBoxAscent();
.fontBoundingBoxDescent() Расстояние от горизонтальной линии (TextBaseline), до низа прямоугольника ограничивающего текст
context.fontBoundingBoxDescent();
.actualBoundingBoxAscent() Расстояние от горизонтальной линии (TextBaseline), до вершины прямоугольника ограничивающего текст
context.actualBoundingBoxAscent();
.actualBoundingBoxDescent() Расстояние от горизонтальной линии (TextBaseline), до низа прямоугольника ограничивающего текст
context.actualBoundingBoxDescent();
.emHeightAscent() Расстояние от горизонтальной линии (TextBaseline), до верха прямоугольника ограничивающего текст в em единицах измерения.
context.emHeightAscent();
.emHeightDescent() Расстояние от горизонтальной линии (TextBaseline), до низа прямоугольника ограничивающего текст в em единицах измерения.
context.emHeightDescent();
.hangingBaseline() Расстояние от горизонтальной линии (TextBaseline), до хэндинг базовой линии текста в em единицах измерения.
context.hangingBaseline();
.alphabeticBaseline() Расстояние от горизонтальной линии (TextBaseline), до алфавитной базовой линии текста в em единицах измерения.
context.alphabeticBaseline();
.ideographicBaseline() Расстояние от горизонтальной линии (TextBaseline), до идеографической базовой линии текста в em единицах измерения.
context.ideographicBaseline();
.drawSystemFocusRing( [ path, ] element ) Если данный элемент ориентирован, рисует кольцо фокусировки вокруг текущего пути по умолчанию или заданный путь, следуя конвенций платформы для фокус-колец.
context.drawSystemFocusRing();
.drawCustomFocusRing( [ path, ] element )
context.drawCustomFocusRing();
.scrollPathIntoView() Позволяет управлять прокруткой
context.scrollPathIntoView();
.clip() Ограничивает область отсечения
context.clip();
.resetClip() Деконстатировать область отсечения
context.resetClip();
.isPointInPath() Возвращает истину, если данная точка находится в текущем пути по умолчанию или заданного пути
context.isPointInPath();
.isPointInStroke() Возвращает истину, если данная точка будет в регионе, охваченном инсульта текущего пути по умолчанию или заданный путь, учитывая текущий стиль инсульт.
context.isPointInStroke();
.addHitRegion() Добавляет область хит для растрового изображения.Аргументом является объект.
context.addHitRegion();
fillRule Правило заполнения для использования при определении, какие пиксели находятся внутри пути.
context.fillRule();
id id canvas
context.id();
parentID Идентификатор родительского области, для целей навигации по доступности инструментов и для курсора запасного варианта.
context.parentID();
cursor
context.cursor();
control
context.control();
label Добавляет label для региона
context.label();
role
context.role();
.removeHitRegion()
context.removeHitRegion();

Пиксельные манипуляции[править | править вики-текст]

Пиксельные манипуляции
Метод / параметр Описание Пример
createImageData
 
createImageDataHD
 
GetImageData
 
GetImageDataHD
 
— .width
 
— .height
 
— .resolution
 
— .data
 
.putImageData()
 
.putImageDataHD()
 
.globalAlpha()
 
.globalCompositeOperation()
 
.imageSmoothingEnabled()
 

Работа с тенями[править | править вики-текст]

Работа с тенями
Метод / параметр Описание Пример
.shadowColor()
 
.shadowOffsetX()
 
.shadowOffsetY()
 
.shadowBlur()
 
window.screen.canvasResolution
 
toDataURL
 
toDataURLHD
 
getImageData
 

Трансформация изображения[править | править вики-текст]

Трансформация изображения
Метод / параметр Описание Пример
.scale( x, y ) Искажает изображение увеличивая её на указанные x, y
 
.rotate( angle ) Поворачивает изображение
 
.transform( a, b, c, d, e, f ) Трансформирует изображение
 
.resetTransform() Обнуляет настройки искажений
 

Особенности[править | править вики-текст]

  • Изменение высоты или ширины холста сотрет всё его содержимое и все настройки, проще говоря он создастся заново[12];
  • Начало отсчёта (точка 0,0) находится в левом верхнем углу[13]. Но её можно сдвигать[14];
  • 3D контекста нет, есть отдельные разработки, но они не стандартизованы[15];
  • Цвет текста можно указывать аналогично css, впрочем, как и размер шрифта.

Примеры или паттерны оптимизации[править | править вики-текст]

В случае, если вам нет необходимости перерисовывать холст, но нужно производить манипуляции с ним, то вы можете «сфотографировать» весь холст и сохранить в переменную. И работать уже с этим рисунком, не заставляя канву отрисовываться после каждой манипуляции.

Если всё изображение не должно обновляться, а только часть его, то вы можете стирать определенную зону на холсте и рисовать её заново.

Браузеры могут оптимизировать анимации идущие одновременно, уменьшив число reflow и repaint до одного, что в свою очередь приведет к повышению точности анимации. Например анимации на JavaScript синхронизированные с CSS transitions или SVG SMIL. Плюс ко всему если выполняется анимация в табе, который невидим, браузеры не будут продолжать перерисовку, что приведет к меньшему использованию CPU, GPU, памяти и как следствие снизит расход батареи в мобильных устройствах[16]. Для этого используйте requestAnimationFrame.

Все текущие браузеры имеют фильтр размытия изображения, при его увеличении. Его стоит использовать, если вы часто попиксельно обрабатываете картинку. Путем уменьшения картинки, например, в два раза и последующего аппаратного увеличения её с помощью фильтра[17].

Если игра позволяет отдельно обрабатывать фон и элементы игры, то имеет смысл сделать два холста друг над другом[18].

Для очистки канвы лучшим средством будет использование clearRect[18], однако, если очищать только необходимые участки, то скорость возрастет ещё больше.

Критика[править | править вики-текст]

  • Нагружает процессор и оперативную память;
  • Из-за ограничения сборщика мусора, нет возможности очистить память;
  • Необходимо самому обрабатывать события с объектами[19];
  • Плохая производительность при большом разрешении[19];
  • Приходится вырисовывать отдельно каждый элемент[19].

Преимущества[править | править вики-текст]

  • В отличии от SVG гораздо удобнее иметь дело с большим числом элементов.
  • Имеет аппаратное ускорение[17][20]
  • Можно манипулировать каждым пикселем[19];
  • Можно применять фильтры обработки изображений[19];
  • Есть много библиотек[19].

Использование[править | править вики-текст]

Использование и операции с элементом возможны только через JavaScript.

<!doctype html>
<html lang="ru">
  <head>
    <title>canvas</title>
    <script src="example.js"></script>
  </head>
  <body>
    <canvas id="canvas">Этот элемент не поддерживается</canvas>
  </body>
</html>

Файл example.js

function onLoadHandler() {
  var canvas  = document.getElementById('canvas'),
      context = canvas.getContext('2d');
  /*
    Далее какие-либо действия над холстом
  */
}
window.onload = onLoadHandler;

Примеры[править | править вики-текст]

Библиотеки[править | править вики-текст]

  • libCanvas это легкий но тем не менее функциональный фреймворк canvas
  • Processing.js это порт языка визуализации Processing
  • EaselJS это библиотека с API похожим на Flash
  • PlotKit это библиотека для создания чартов и графики
  • Rekapi это API Canvas для создания анимации на кейфреймах
  • PhiloGL это фреймворк WebGL для визуализации данных, разработки игр и креативного кодирования.
  • JavaScript InfoVis Toolkit создает интерактивную 2D Canvas визуализацию данных для Web.
  • Frame-Engine это фреймворк для разработки приложений и игр.

Ссылки[править | править вики-текст]

Примеры работы
Для ознакомления

Примечания[править | править вики-текст]

  1. 1 2 Обучение canvas.
  2. 1 2 3 4 4.12.4 The canvas element — HTML Standard.
  3. Canvas — HTML | MDN.
  4. Пример построения капчи по точкам
  5. explorercanvas. Проверено 7 февраля 2013. Архивировано из первоисточника 12 февраля 2013.
  6. Google продвигает HTML5 как игровую платформу. Проверено 7 февраля 2013. Архивировано из первоисточника 12 февраля 2013.
  7. Спецификация от WHATWG. Проверено 7 февраля 2013. Архивировано из первоисточника 12 февраля 2013.
  8. Mozilla Canvas 3D. Проверено 7 февраля 2013.
  9. Градиенты. Проверено 7 февраля 2013. Архивировано из первоисточника 12 февраля 2013.
  10. Поработаем с линиями. Проверено 8 февраля 2013. Архивировано из первоисточника 12 февраля 2013.
  11. Documentation (англ.).
  12. Можно ли «перезагрузить» холст? // Спроси профессора Маркапа. Проверено 5 июля 2013. Архивировано из первоисточника 7 июля 2013.
  13. Координаты холста. Проверено 5 июля 2013. Архивировано из первоисточника 7 июля 2013.
  14. Canvas-трансформации доступным языком. Проверено 5 июля 2013. Архивировано из первоисточника 7 июля 2013.
  15. Спроси профессора Маркапа: В. Есть холст 3D?. Проверено 7 февраля 2013. Архивировано из первоисточника 12 февраля 2013.
  16. Продвинутые анимации с requestAnimationFrame. Проверено 8 февраля 2013. Архивировано из первоисточника 12 февраля 2013.
  17. 1 2 Как раскрыть мощь HTML5 Canvas для игр.
  18. 1 2 Improving HTML5 Canvas Performance — HTML5 Rocks.
  19. 1 2 3 4 5 6 What are the advantages/disadvantages of Canvas vs. DOM in JavaScript game development?. Проверено 3 ноября 2013.
  20. Canvas с аппаратным ускорением в Google Chrome.