Canvas (англ.canvas — «холст», рус.канва́с) — элемент HTML5, предназначенный для создания растрового двухмерного изображения при помощи скриптов, на языке JavaScript[1]. Начало отсчёта блока находится слева сверху. От него и строится каждый элемент блока[2]. Размер пространства координат не обязательно отражает размер фактической отображаемой площади[2]. По умолчанию его ширина равна 300 пикселям, а высота 150[2].
Используется, как правило, для отрисовки графиков для статей и игрового поля в некоторых браузерных играх. Но также может использоваться для встраивания видео в страницу и создания полноценного плеера.
Используется в WebGL для аппаратного ускорения 3D-графики[3].
Компанией Google была выпущена JavaScript-библиотека explorercanvasАрхивировано 11 февраля 2013 года., которая позволяла работать с Canvas в браузерах IE7 и IE8.
Canvas может усложнить задачу роботам по распознаванию Капчи. При использовании canvas с сервера загружается не картинка, а набор точек (или алгоритм прорисовки), по которым браузер прорисовывает картинку (капчу)[4].
Ситуацию с отсутствием canvas в IE исправила компания Google, выпустившая собственное расширение, написанное на JavaScript, под названием ExplorerCanvas[5].
На сегодняшний день canvas чаще используется для построения графиков, простой анимации и игр в браузерах[6]. Группа WHATWG предлагает использовать canvas как стандарт для создания графики в новых поколениях веб-приложений[7].
Организация Mozilla Foundation ведёт проект под названием Canvas 3D[8], целью которого является добавить низкоуровневую поддержку графических ускорителей для отображения трёхмерных изображений через HTML-элемент canvas. Наряду с этим существуют библиотеки, реализующие работу с трёхмерными моделями, среди них threeАрхивная копия от 9 мая 2017 на Wayback Machine.
Поддержка
IE
Firefox
Safari
Chrome
Opera
iOS
Android
9.0+
3.0+
3.0+
3.0+
10.0+
3.0+
1.0+
Возможности
canvas позволяет разместить на холсте: картинку, видео, текст. Залить всё это сплошным цветом, либо обвести контуры или даже добавить градиент[9]. Добавление теней похожих на свойства css3 box-shadow и text-shadow. И, наконец, отрисовка фигур с помощью указания контрольных точек. Причём можно изменять как ширину линий, так и кисть рисовки линий, стиль соединений линий[10].
Особенности
Изменение высоты или ширины холста сотрет всё его содержимое и все настройки, проще говоря он создастся заново[11];
Начало отсчёта (точка 0,0) находится в левом верхнем углу[12]. Но её можно сдвигать[13];
3D-контекста нет, есть отдельные разработки, но они не стандартизованы[14];
Цвет текста можно указывать аналогично CSS, впрочем, как и размер шрифта.
Примеры или паттерны оптимизации
В случае, если вам нет необходимости перерисовывать холст, но нужно производить манипуляции с ним, то вы можете «сфотографировать» весь холст и сохранить в переменную. И работать уже с этим рисунком, не заставляя канвас отрисовываться после каждой манипуляции.
Если обновляться должно не всё изображение, а только его часть, то вы можете стирать определенную зону на холсте и рисовать её заново.
Браузеры могут оптимизировать анимации, идущие одновременно, уменьшив число reflow и repaint до одного, что в свою очередь приведёт к повышению точности анимации. Например анимации на JavaScript, синхронизированные с CSS transitions или SVG SMIL. Плюс ко всему если выполняется анимация в табе, который невидим, браузеры не будут продолжать перерисовку, что приведёт к меньшему использованию CPU, GPU, памяти и как следствие снизит расход батареи в мобильных устройствах[15]. Для этого используйте requestAnimationFrame.
Все текущие браузеры имеют фильтр размытия изображения при его увеличении. Его стоит использовать, если вы часто попиксельно обрабатываете картинку. Путём уменьшения картинки, например, в два раза и последующего аппаратного увеличения её с помощью фильтра[16].
Если игра позволяет отдельно обрабатывать фон и элементы игры, то имеет смысл сделать два холста друг над другом[17].
Для очистки канвы лучшим средством будет использование clearRect[17], однако, если очищать только необходимые участки, то скорость возрастет ещё больше.
Критика
Чрезмерно нагружает процессор и оперативную память;
Из-за ограничения сборщика мусора нет возможности очистить память;
Необходимо самому обрабатывать события с объектами[18];
Плохая производительность при высоком разрешении[18];
Приходится отрисовывать отдельно каждый элемент[18].
Возможность создания на страницах специальных «маячков», т. н. Canvas Fingerprinting, для отслеживания пользователей в сети.
Преимущества
В отличие от SVG гораздо удобнее иметь дело с большим числом элементов;
Использование и операции с элементом возможны только через JavaScript.
<!doctype html><htmllang="ru"><head><title>canvas</title><scriptsrc="example.js"></script></head><body><canvasid="canvas">Этот элемент не поддерживается</canvas></body></html>
Файл example.js
varcanvas=document.getElementById('canvas'),context=canvas.getContext('2d');functiononLoadHandler(){/* Далее какие-либо действия над холстом */}window.onload=onLoadHandler;
<html><head><title>Дерево Пифагора</title><scripttype="text/javascript">// функция рисует под углом angle линию из указанной точки длиной lnfunctiondrawLine(x,y,ln,angle){context.moveTo(x,y);context.lineTo(Math.round(x+ln*Math.cos(angle)),Math.round(y-ln*Math.sin(angle)));}// Функция рисует деревоfunctiondrawTree(x,y,ln,minLn,angle){if(ln>minLn){ln=ln*0.75;drawLine(x,y,ln,angle);x=Math.round(x+ln*Math.cos(angle));y=Math.round(y-ln*Math.sin(angle));drawTree(x,y,ln,minLn,angle+Math.PI/4);drawTree(x,y,ln,minLn,angle-Math.PI/6);// если поставить угол Math.PI/4 , то выйдет классическое дерево}}// Инициализация переменныхfunctioninit(){varcanvas=document.getElementById("tree"),x=100+(canvas.width/2),y=170+canvas.height,// положении стволаln=120,// начальная длина линииminLn=5;// минимальная длина линииcanvas.width=480;// Ширина холстаcanvas.height=320;// высота холста context=canvas.getContext('2d');context.fillStyle='#ddf';// цвет фонаcontext.strokeStyle='#020';//цвет линийcontext.fillRect(0,0,canvas.width,canvas.height);context.lineWidth=2;// ширина линийcontext.beginPath();drawTree(x,y,ln,minLn,Math.PI/2);context.stroke();}window.onload=init;</script></head><body><canvasid="tree"></canvas></body></html>
Библиотеки
libCanvas — лёгкий, но тем не менее функциональный фреймворк canvas
Processing.js — порт языка визуализации Processing
EaselJS — библиотека с API похожим на Flash
PlotKit — библиотека для создания чартов и графики
Rekapi — API Canvas для создания анимации на кейфреймах
PhiloGL — фреймворк WebGL для визуализации данных, разработки игр и креативного кодирования.
JavaScript InfoVis Toolkit — создаёт интерактивную 2D Canvas визуализацию данных для Web.
Frame-Engine — фреймворк для разработки приложений и игр.