Drawing shapes
const ctx = canvas.getContext("2d", {
alpha: false,
}); - создание 2d контекста с настройками
Drawing rectangles
ctx.fillRect(x, y, width, height) - рисует закрашенный прямоугольник.
ctx.strokeRect(x, y, width, height) - рисует прямоугольник.
ctx.clearRect(x, y, width, height) - заменяет выбранную область цветом по умолчанию (прозначным либо черным).
Paths
Path - список точек, соединенных линиями, которые могут иметь разные формы.
Создание path
ctx.beginPath() - создает новый path. Будущие команды по отрисовке будут относиться к этому path.
Методы для отрисовки path
ctx.moveTo(x, y) - переносит карандаш (кисть) в заданную точку.
ctx.lineTo(x, y) - проводит прямую линию из текущей точки к заданной.
ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise) - рисует дугу окружности с центром в заданной точке. Углы задаются в радианах (Math.PI - это 180 градусов).
ctx.arcTo(x1, y1, x2, y2, radius) - рисует дугу окружности с заданным радиусом по двум опорным точкам.
ctx.closePath() - чертит прямую линию из текущей точки в начальную координату текущего path.
ctx.rect(x, y, width, height) - вызывает ctx.moveTo(x, y) и добавляет к текущему пути прямоугольник.
Отображение path на холсте
ctx.stroke() - обводит текущий path линией с заданными stroke стилями.
ctx.fill(fillRule) - вызывает ctx.closePath() и закрашивает содержимое контура path.
fillRule = ['nonzero'] | 'evenodd'- правило заполнение контура
Applying styles
Line styles
ctx.strokeStyle - задает цвет color контура фигуры при выполнении ctx.stroke().
ctx.fillStyle - задает цвет color окрашивания фигуры при выполнении ctx.fill().
-
color- строковое представление CSS-цвета. Цвет по умолчанию - черный. Можно установить цвет с альфа-каналом, например'rgb(100 100 100 / 0.7)'. Прозрачность также можно задать свойствомctx.globalAlpha
ctx.lineCap - задает тип type концов линии.
type = ['butt'] | 'round' | 'square'
ctx.lineJoin - задает тип value соединения линий.
value = ['miter'] | 'bevel' | 'round'
ctx.setLineDash(sequence) - задает стиль для пунктирной линии.
sequence- массив, задающий длину линий и расстояние между вpx, например,[3, 10, 7, 10]
ctx.lineDashOffset - задает смещение пунктирной линии.
Shadows
ctx.shadowOffsetX - задает смещение тени по горизонтали, по умолчанию 0.
ctx.shadowOffsetY - задает смещение тени по вертикали, по умолчанию 0.
ctx.shadowBlur - задает величину размытия тени, по умолчанию 0.
ctx.shadowColor - задает цвет тени, по умолчанию прозрачный.
Drawing text
ctx.fillText(text, x, y [, maxWidth]) - отрисовывает текст по указанным координатам.
ctx.strokeText(text, x, y [, maxWidth]) - отрисовывает контур текста по указанным координатам.
ctx.font - задает стиль отрисованного текста, по умолчанию '10px sans-serif'.
ctx.textAlign - задает выравнивание align текста по горизонтали относительно координаты x.
align = ['start'] | 'end' | 'left' | 'right' | 'center'
ctx.textBaseline - задает выравнивание align текста по вертикали относительно координаты y.
align = 'top' | 'hanging' | 'middle' | ['alphabetic'] | 'ideographic' | 'bottom'
Text measurements
ctx.measureText(text) - возвращает объект, содержащий ширину текста и другие параметры до его отрисовки.
const text = ctx.measureText("hello canvas");
console.log(text.width); // 55.5908203125
Using images
Создание изображения
const img = new Image();
img.src = "myImage.png";
img.onload = () => { ... }; // после загрузки изображения, можно приступать к его отрисовке
Отрисовка изображения
Для отрисовки используется метод drawImage, который может вызываться в 3 разных вариантах:
ctx.drawImage(image, x, y) - отрисовывает изображение по заданным координатам.
ctx.drawImage(image, x, y, width, height) - отрисовывает изображение с заданной шириной и высотой.
ctx.drawImage(image, sx, sy, sWidth, sHeight, x, y, width, height) - отрисовывает часть изображения.
image- изображениеx,y- координаты для отрисовкиwidth,height- ширина и высота отрисовываемого изображенияsx,sy- координаты части исходного изображенияsWidth,sHeight- ширина и высота части исходного изображения
Transformations
Сохранение и восстановление состояния
Состояния canvas хранятся в стеке. Каждый раз при вызове ctx.save() текущее состояние добавляется в стек (аналог метода push). А при вызове ctx.restore() - достается из стека (аналог метода pop). Состояние включает в себя текущие трансформации, stokeStyle, fillStyle, lineWidth и другие атрибуты.
ctx.save() - сохраняет состояние в стек.
ctx.restore() - восставнавливает последнее состояние в стеке и удаляет его из стека.
Смещение
ctx.translate(x, y) - перемещает начало координат canvas на заданную величину. Перед вызовом рекомендуется сохранить состояние, а после выполнения всех операций его восстановить.
Вращение
ctx.rotate(rad) - вращает координатную сетку canvas по часовой стрелке на заданное число радиан относительно начала координат.
Чтобы повернуть прямоугольник относительно центра, сначала необходимо выполнить ctx.translate(xCenter, yCenter), затем ctx.rotate(Math.PI / 180 * angle), затем вернуть начало координат через ctx.translate(-xCenter, -yCenter) и отрисовать прямоугольник через ctx.drawRect.
Масштабирование
ctx.scale(x, y) - увеличивает canvas в x раз по горизонтали и в y раз по вертикали.
Используя отрицательные x, y можно выполнить зеркальное отражение оси.
Матрица трансформации
ctx.transform(a, b, c, d, e, f) - позволяет задать сразу несколько трансформаций, в том числе искажение skewing. Значения по умолчанию: (1, 0, 0, 1, 0, 0).
a- горизонтальное масштабированиеb- горизонтальное искажение (skewing)c- вертикальное искажение (skewing)d- вертикальное масштабированиеe- горизонтальное смещениеf- вертикальное смещение
Compositing and clipping
globalCompositeOperation
Свойство устанавливает то, как новое изображение будет нарисовано поверх существующего содержимого.
ctx.globalCompositeOperation - задает тип операции, который будет использован в режиме наложения. Имеет любое из следующих значений:
'source-over'- значение по умолчанию, при котором новые фигуры отображаются поверх существующего содержимого холста'source-in'- новая фигура отображается только в том месте, где и она, и целевой холст накладываются друг на друга, все остальное становится прозрачным'source-out'- новая фигура рисуется там, где она не перекрывает существующее содержимое холста'source-atop'- новая фигура рисуется только там, где она перекрывает существующее содержимое холста'destination-over'- новые фигуры рисуются позади существующего содержимого холста'destination-in'- существующее содержимое холста сохраняется там, где новая фигура и существующее содержимое холста пересекаются. Все остальное становится прозрачным'destination-out' - существующий контент сохраняется там, где он не перекрывает новую форму'destination-atop'- существующее содержимое холста сохраняется только там, где оно перекрывает новую фигуру. Новая фигура отображается позади содержимого холста'lighter'- цвет определяется путем сложения цветов там, где обе фигуры пересекаются'copy'- показывать только новую фигуру'xor'- фигуры становятся прозрачными там, где они накладываются друг на друга'multiply'- пиксели верхнего слоя умножаются на соответствующий пиксель нижнего слоя. В результате изображение получается более темным'screen'- пиксели инвертируются, перемножаются и снова инвертируются. В результате получается более светлое изображение (похож наlighter)'overlay'- комбинация значенийmultiplyиscreen. Темные участки становятся темнее, а светлые - светлее'darken'- сохраняет самые темные пиксели обоих слоев (похож наmultiply)'lighten'- сохраняет самые светлые пиксели обоих слоев (похож наlighter)'color-dodge'- разделяет нижний слой на перевернутый верхний слой'color-burn'- делит перевернутый нижний слой на верхний, а затем инвертирует результат'hard-light'- комбинация значенийmultiplyиscreenкак в значенииoverlay, но с перестановкой верхнего и нижнего слоев'soft-light'- более мягкая версия значенияhard-light. Чистый черный или белый цвет не приводит к получению абсолютно черного или белого цвета'difference'- вычитает нижний слой из верхнего или наоборот, чтобы всегда получать положительное значение'exclusion'- как значениеdifference, но с меньшим контрастом'hue'- сохраняет яркость и насыщенность цвета нижнего слоя, при этом беря оттенок верхнего слоя.luma,saturation- не меняются,hue- меняется'saturation'- сохраняет яркость и оттенок цвета нижнего слоя, при этом беря насыщенность верхнего слоя.luma,hue- не меняются,saturation- меняется'luminosity'- сохраняет оттенок и насыщенность цвета нижнего слоя, при этом беря яркость верхнего слоя.hue,saturation- не меняются,luma- меняется'color'- сохраняет яркость цвета нижнего слоя, при этом беря насыщенность верхнего слоя.luma- не меняется,saturation- меняется
Clipping
ctx.clip() - превращает текущий path в маску, используется вместо ctx.closePath().
Маска хранится в состоянии canvas.
Для инвертирования маски (отрисовки содержимого снаружи) нет специального свойства. Однако можно сделать маской фигуру с отверстием внутри.
Чтобы отрисовать фигуру с отверстием, внешняя и внутреняя фигуры должны быть нарисованы в разных направлениях.
Прямоугольник, нарисованный через ctx.rect() предполагает направление по часовой стрелке.
Пример такой маски:
ctx.beginPath();
ctx.rect(-75, -75, 150, 150); // Outer rectangle
ctx.arc(0, 0, 60, 0, Math.PI * 2, true); // Hole anticlockwise
ctx.clip();
Basic animations
Последовательность шагов:
- Если фигуры не будут занимать все пространство, очистить холст через
ctx.clearRect(). - Сохранить текущий state (если будут применяться новые стили, трансформации и тд).
- Отрисовать анимированные фигуры.
- Восстановить сохраненный state.
Pixel manipulation
ImageData - объект, который позволяет напрямую работать с пикселями. Имеет следующие read-only свойства:
width- количество пикселей в ширинуheight- количество пикселей в высотуdata- одноразмерный массивUint8ClampedArray, в котором каждые 4 элемента со значениями от0до255содержат информацию об одном пикселе (RGBA). Порядок пикселей - слева направо, затем сверху вниз. Массив содержитheight * width * 4байтов данных (и столько же элементов)
Создание пустого массива
const myImageData = ctx.createImageData(width, height) - создание объекта ImageData с указанными размерами. Всем пикселям предварительно задан прозрачный черный цвет rgb(0 0 0 / 0%), то есть массив хранит одни нули.
const myImageData = ctx.createImageData(anotherImageData) - создание объекта ImageData с размерами anotherImageData и пикселями прозрачного черного цвета.
Получение пиксельных данных из контекста
const myImageData = ctx.getImageData(x, y, width, height) - возвращает объект ImageData с пиксельными данными заданной области холста.
Отрисовка пиксельных данных в контексте
ctx.putImageData(myImageData, x, y) - отрисовывает пиксели из myImageData начиная с координат x и y.
Сохранение изображений
Метод toDataURL() объекта canvas возвращает представление изображения в виде строки data URL.
canvas.toDataURL('image/png') - значение по умолчанию.
canvas.toDataURL('image/jpeg', quality) - JPG формат, позволяет задать необязательный параметр quality со значением от 0 до 1, где 0 - изображение в плохом качестве, но небольшое по размеру.
Пример использования:
const link = document.createElement("a");
link.href = canvas.toDataURL("image/png");
link.download = "canvas_image.png"; // Имя файла
document.body.append(link);
link.click();
link.remove();