Тег <canvas>
описывает холст на котором мы можем рисовать. Он имеет следующие параметры:
width
— ширина;height
— высота.Создадим холст, укажем его размеры и зальем зеленым цветом:
<canvas id="canvas" width="400" height="300"></canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
ctx.fillStyle = 'green';
ctx.fillRect(0, 0, canvas.width, canvas.height);
</script>
После создания холста нужно получить его контекст рисования. Для этого используется метод getContext()
, которому нужно передать значение '2d'
:
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
В результате переменная ctx
будет ссылаться на экземпляр класса CanvasRenderingContext2D
, который содержит свойства и методы, позволяющие рисовать на холсте.
Получить ссылку на объект холста позволяет свойство canvas
. Получим размеры холста:
console.log(ctx.canvas.width); // 400
console.log(ctx.canvas.height); // 300
Управлять цветом заливки позволяет свойство fillStyle
. Можно присвоить следующие значения:
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
ctx.fillStyle = 'green';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = '#ff0000';
ctx.fillRect(10, 10, 30, 30);
ctx.fillStyle = 'rgb(127, 127, 127)';
ctx.fillRect(50, 10, 30, 30);
ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
ctx.fillRect(90, 10, 30, 30);
let lg = ctx.createLinearGradient(0, 0, 40, 0);
lg.addColorStop(0, 'black');
lg.addColorStop(1, 'white');
ctx.fillStyle = lg;
ctx.fillRect(10, 50, 30, 30);
let rg = ctx.createRadialGradient(110, 110, 30, 150, 150, 170);
rg.addColorStop(0, 'black');
rg.addColorStop(1, 'white');
ctx.fillStyle = rg;
ctx.fillRect(50, 50, 30, 30);
Если характеристики заливки не заданы, то используется черный цвет.
Управлять цветом обводки позволяет свойство strokeStyle
. Можно присвоить следующие значения:
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
ctx.strokeStyle = 'green';
ctx.strokeRect(0, 0, canvas.width, canvas.height);
ctx.strokeStyle = '#ff0000';
ctx.strokeRect(10, 10, 30, 30);
ctx.strokeStyle = 'rgb(127, 127, 127)';
ctx.strokeRect(50, 10, 30, 30);
ctx.strokeStyle = 'rgba(0, 0, 0, 0.8)';
ctx.strokeRect(90, 10, 30, 30);
Если цвет обводки не задан, то используется черный цвет.
Дополнительные характеристики задаются с помощью следующих свойств:
lineWidth
— задает ширину (толщину) обводки. Значение по умолчанию: 1.0
. Пример:ctx.strokeStyle = '#000000';
ctx.lineWidth = 5;
ctx.strokeRect(10, 90, 30, 30);
lineCap
— задает форму окончания линии. Можно указать следующие значения в виде строки:square
— квадратные концы (прибавляются к длине линии); значение по умолчанию;butt
— концы никак не оформляются;round
— закругленные концы (прибавляются к длине линии).Пример:
ctx.beginPath();
ctx.strokeStyle = '#000000';
ctx.lineWidth = 15;
ctx.lineCap = 'round';
ctx.moveTo(150, 30);
ctx.lineTo(350, 30);
ctx.stroke();
lineJoin
— задает форму окончания в месте соединения двух линий обводки. Можно указать следующие значения в виде строки::miter
— обычные углы (значение по умолчанию);bevel
— скошенные углы;round
— закругленные углы.Пример:
ctx.beginPath();
ctx.strokeStyle = '#000000';
ctx.lineWidth = 15;
ctx.lineJoin = 'bevel';
ctx.moveTo(270, 150);
ctx.lineTo(170, 200);
ctx.lineTo(270, 200);
ctx.stroke();
miterLimit
— задает ограничение длины угла при использовании стиля miter
. Значение по умолчанию: 10
. Если значение превышено, то угол будет скошенным.Следующие методы и свойства делают линию пунктирной:
setLineDash(<Массив>)
— задает значения для пунктирной линии. Значения указываются в виде массива. Четные индексы задают длину штриха, а нечетные — длину пропуска. Пример рисования пунктирной линии:ctx.beginPath();
ctx.strokeStyle = '#000000';
ctx.lineWidth = 8;
ctx.setLineDash([15, 10]);
ctx.moveTo(10, 250);
ctx.lineTo(390, 250);
ctx.stroke();
Чтобы сделать следующую линию опять сплошной достаточно передать в метод пустой массив;
getLineDash()
— возвращает массив со значениями для пунктирной линии;lineDashOffset
— задает смещение начала пунктирной обводки. Значение по умолчанию: 0
.Итак, свойства fillStyle
и strokeStyle
в качестве значения могут принимать объекты линейного или радиального градиентов. Давайте научимся создавать эти объекты.
Создать объект линейного градиента позволяет метод createLinearGradient()
. Формат метода:
<CanvasGradient> = createLinearGradient(<X1>, <Y1>, <X2>, <Y2>)
Далее с помощью метода addColorStop()
объекта CanvasGradient
нужно задать точки останова и соответствующие им цвета. Формат метода:
<CanvasGradient>.addColorStop(<Точка останова>, <Цвет>)
В первом параметре указывается значение от 0.0
до 1.0
. Во втором параметре задается цвет. Пример создания линейного градиента от черного до белого цветов по горизонтали:
<canvas id="canvas" width="400" height="300"></canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let lg = ctx.createLinearGradient(0, 0, 400, 0);
lg.addColorStop(0, 'black');
lg.addColorStop(1, 'white');
ctx.fillStyle = lg;
ctx.fillRect(0, 0, canvas.width, canvas.height);
</script>
Создать объект радиального градиента позволяет метод createRadialGradient()
. Формат метода:
<CanvasGradient> = createRadialGradient(<X1>, <Y1>, <R1>,
<X2>, <Y2>, <R2>)
Первые три параметра определяют координаты и радиус внутреннего круга, а последние три — координаты и радиус внешнего круга.
Далее с помощью метода addColorStop()
объекта CanvasGradient
нужно задать точки останова и соответствующие им цвета. Формат метода:
<CanvasGradient>.addColorStop(<Точка останова>, <Цвет>)
В первом параметре указывается значение от 0.0
(внутренний круг) до 1.0
(внешний круг). Во втором параметре задается цвет. Пример создания радиального градиента от черного до белого цветов:
<canvas id="canvas" width="400" height="300"></canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let rg = ctx.createRadialGradient(110, 110, 30, 150, 150, 150);
rg.addColorStop(0, 'black');
rg.addColorStop(1, 'white');
ctx.fillStyle = rg;
ctx.fillRect(0, 0, canvas.width, canvas.height);
</script>
Создать объект текстуры позволяет метод createPattern()
. Формат метода:
<Объект текстуры> = createPattern(<Изображение>, <Режим повтора>)
В первом параметре указывается объект изображения, например, ссылка на элемент IMG
или экземпляр класса Image
. Во втором параметре задается режим повтора изображения в виде строки:
repeat
— повтор по горизонтали и вертикали;repeat-x
— повтор только по горизонтали;repeat-y
— повтор только по вертикали;no-repeat
— без повтора.Пример:
<canvas id="canvas" width="800" height="800"></canvas>
<img src="texture.jpg" alt="" id="img1">
<script>
window.onload = function() {
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let img = document.getElementById('img1');
ctx.fillStyle = ctx.createPattern(img, 'repeat');
ctx.fillRect(0, 0, canvas.width, canvas.height);
};
</script>
Если используется экземпляр класса Image
, то нужно дождаться загрузки текстуры:
<canvas id="canvas" width="800" height="800"></canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let img = new Image();
img.onload = function () {
ctx.fillStyle = ctx.createPattern(img, 'repeat');
ctx.fillRect(0, 0, canvas.width, canvas.height);
};
img.src = 'texture.jpg';
</script>
Управлять рисованием траектории позволяют следующие методы:
beginPath()
— начинает новую траекторию;moveTo(<X>, <Y>)
— позволяет переместить текущую позицию в точку с указанными координатами;closePath()
— позволяет замкнуть текущую траекторию;stroke()
— прорисовывает текущую траекторию, используя характеристики обводки;fill([<Правила>])
— прорисовывает текущую траекторию, используя характеристики заливки. В качестве параметра можно указать алгоритмы заливки nonzero
(значение по умолчанию) или evenodd
в виде строк.Пример рисования треугольника с обводкой и заливкой:
ctx.fillStyle = 'green';
ctx.strokeStyle = 'red';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.lineTo(20, 100);
ctx.lineTo(100, 100);
ctx.closePath();
ctx.stroke();
ctx.fill();
lineTo()
— добавляет прямую линию к текущей траектории:ctx.lineTo(20, 100);
arcTo()
— добавляет дугу к текущей траектории. Формат метода:arcTo(<X1>, <Y1>, <X2>, <Y2>, <radius>)
Пример рисования дуги:
ctx.strokeStyle = 'black';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(120, 120);
ctx.arcTo(200, 0, 300, 100, 100);
ctx.stroke();
arc()
— добавляет дугу к текущей траектории. Формат метода:arc(<centerX>, <centerY>, <radius>, <startAngle>,
<endAngle>[, <Направление>])
Параметры <centerX>
и <centerY>
задают координаты центра круга, параметр <radius>
— радиус круга, параметр <startAngle>
— начальный угол в радианах, а параметр <endAngle>
— конечный угол в радианах. Если параметр <Направление>
имеет значение true
, то дуга рисуется против часовой стрелки, а если false
— по часовой стрелке.
Формула преобразования градусов в радианы:
radians = (Math.PI / 180) * degrees;
Пример:
ctx.strokeStyle = 'black';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(300, 150);
ctx.arc(200, 150, 100, 0, (Math.PI / 180) * 135);
ctx.stroke();
bezierCurveTo()
— добавляет кубическую кривую Безье к текущей траектории. Формат метода:bezierCurveTo(<xc1>, <yc1>, <xc2>, <yc2>, <X1>, <Y1>)
Параметры <xc1>
и <yc1>
задают координаты первой опорной точки, параметры <xc2>
и <yc2>
— координаты второй опорной точки, а параметры <X1>
и <Y1>
— координаты конечной точки. Пример:
ctx.strokeStyle = 'black';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(295, 225);
ctx.bezierCurveTo(200, 390, 200, 200, 350, 300);
ctx.stroke();
quadraticCurveTo()
— добавляет квадратичную кривую к текущей траектории. Формат метода:quadraticCurveTo(<xc>, <yc>, <X1>, <Y1>)
Параметры <xc>
и <yc>
задают координаты опорной точки, а параметры <X1>
и <Y1>
— координаты конечной точки. Пример:
ctx.strokeStyle = 'green';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.moveTo(50, 400);
ctx.quadraticCurveTo(200, 300, 350, 400);
ctx.stroke();
rect()
— добавляет к траектории прямоугольник. Этот метод удобно использовать совместно с методом clip()
для добавления маски. Формат метода:rect(<X>, <Y>, <Ширина>, <Высота>)
Пример:
ctx.strokeStyle = 'green';
ctx.lineWidth = 5;
ctx.beginPath();
ctx.rect(300, 50, 80, 80);
ctx.stroke();
clip()
— создает маску на основе текущего пути. Область внутри пути будет видна, а вне — скрыта.Иногда бывает необходимо выяснить, входит ли точка с заданными координатами в состав траектории. Сделать это можно с помощью метода isPointInPath(<X>, <Y>[, <fillRule>])
. Метод возвращает true
, если точка с такими координатами входит в состав траектории, и false
— в противном случае.
Нарисовать на холсте прямоугольники позволяют следующие методы:
fillRect()
— рисует прямоугольник, используя характеристики заливки. Формат метода:fillRect(<X>, <Y>, <Ширина>, <Высота>)
Параметры <X>
и <Y>
задают координаты левого верхнего угла прямоугольника, а параметры <Ширина>
и <Высота>
— ширину и высоту. Пример:
ctx.fillStyle = 'green';
ctx.fillRect(50, 50, 200, 100);
strokeRect()
— рисует прямоугольник, используя характеристики обводки. Формат метода:strokeRect(<X>, <Y>, <Ширина>, <Высота>)
Пример:
ctx.strokeStyle = 'blue';
ctx.lineWidth = 5;
ctx.strokeRect(50, 200, 80, 80);
Управлять характеристиками текста позволяют следующие свойства:
font
— задает характеристики шрифта:ctx.font = '16pt Verdana, Tahoma, sans-serif';
ctx.fillStyle = 'green';
ctx.fillText('Electron', 50, 50);
Получим значение по умолчанию:
console.log(ctx.font); // 10px sans-serif
textAlign
— задает горизонтальное выравнивание текста относительно начальной точки. Возможные значения в виде строки: start
, end
, left
, right
или center
. Получим значение по умолчанию:console.log(ctx.textAlign); // start
Пример:
ctx.font = '20pt Arial';
ctx.fillStyle = 'red';
ctx.textAlign = 'center';
ctx.fillText('Electron', 250, 50);
textBaseline
— задает вертикальное выравнивание текста относительно начальной точки. Возможные значения в виде строки: alphabetic
, ideographic
, top
, middle
, hanging
или bottom
. Получим значение по умолчанию:console.log(ctx.textBaseline); // alphabetic
Пример выравнивания по верху:
ctx.textBaseline = 'top';
ctx.fillText('Electron', 250, 100);
Вывести текст позволяют следующие методы:
fillText()
— выводит текст, используя характеристики заливки. Формат метода:fillText(<text>, <X>, <Y>[, <maxWidth>])
Параметр <text>
задает выводимый текст, параметры <X>
и <X>
— координаты начальной точки, а параметр <maxWidth>
— максимальную ширину поля. Пример ограничения ширины поля:
ctx.font = '16pt Verdana, Tahoma, sans-serif';
ctx.fillStyle = 'blue';
ctx.fillText('Electron', 50, 100, 50);
Если текст не помещается в указанную ширину, то он будет сжат таким образом, чтобы поместиться. В результате текст может стать абсолютно не читаемым. Если необходимо ограничить ширину и при этом чтобы текст не сжимался, а просто обрезался, то следует наложить маску;
strokeText()
— выводит текст, используя характеристики обводки. Формат метода:strokeText(<text>, <X>, <Y>[, <maxWidth>])
Пример:
ctx.strokeStyle = 'blue';
ctx.lineWidth = 3;
ctx.textAlign = 'start';
ctx.font = '48pt Verdana';
ctx.strokeText('Electron', 50, 200);
Узнать информацию о характеристиках блока, в который будет вписан текст, позволяет метод measureText(<Текст>)
. Он возвращает объект TextMetrics
. С помощью свойства width
этого объекта, мы можем получить ширину текста в пикселах:
let text = 'Electron';
ctx.font = '48pt Verdana';
console.log(ctx.measureText(text).width); // 261.375
Вывести изображение на холст позволяет метод drawImage()
. Форматы метода:
drawImage(<img>, <X>, <Y>)
drawImage(<img>, <X>, <Y>, <w>, <h>)
drawImage(<img>, <sx>, <sy>, <sw>, <sh>,
<dx>, <dy>, <dw>, <dh>)
Первый формат выводит изображение полностью в позицию с координатами <X>
и <Y>
. В первом параметре указывается объект изображения, например, ссылка на элемент IMG
или экземпляр класса Image
. Пример указания ссылки на элемент IMG
:
<canvas id="canvas" width="800" height="800"></canvas>
<img src="photo.jpg" alt="" id="img1">
<script>
window.onload = function() {
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
let img = document.getElementById('img1');
ctx.drawImage(img, 0, 0);
};
</script>
Второй формат позволяет ограничить область вывода шириной (параметр <w>
) и высотой (параметр <h>
). При этом изображение может быть уменьшено или увеличено таким образом, чтобы вписаться в область. Если пропорции области не совпадают с пропорциями изображения, то изображение будет растянуто или сжато без соблюдения пропорций. Пример:
ctx.drawImage(img, 0, 400, 250, 166);
Третий формат берет прямоугольную область (<sx>, <sy>, <sw>, <sh>)
с изображения и вписывает ее в прямоугольную область (<dx>, <dy>, <dw>, <dh>)
на холсте. Пример указания экземпляра класса Image
:
let img2 = new Image();
img2.onload = function() {
ctx.drawImage(img2, 200, 50, 300, 300,
300, 400, 300, 300);
};
img2.src = 'photo.jpg';
Стереть какую-либо прямоугольную область на холсте позволяет метод clearRect()
. Формат метода:
clearRect(<X>, <Y>, <Ширина>, <Высота>)
Пример очистки всего холста:
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
Значения основных характеристик можно сохранить в стек, выполнить какую-либо операцию рисования, а затем восстановить эти значения из стека. Для этого предназначены следующие методы:
save()
— сохраняет значения основных характеристик (в частности характеристики заливки, обводки, шрифта и др.) в стек. Полный список сохраняемых характеристик можно найти в документации;restore()
— восстанавливает значения основных характеристик из стека.Ограничим область вывода длинного текста маской:
ctx.save();
ctx.beginPath();
ctx.rect(0, 0, 270, 200);
ctx.clip();
ctx.font = '48pt Verdana';
ctx.fillText('Electron', 50, 50);
ctx.restore();
Вначале мы сохранили значения в стек, применили маску к тексту, а затем восстановили значения из стека. Если убрать последнюю инструкцию восстановления значений, то все последующие операции рисования будут отображаться только внутри маски, а не на всей поверхности холста.
Применить различные преобразования позволяют следующие свойства и методы:
globalAlpha
— задает степень непрозрачности (вещественное число от 0.0
(полностью прозрачный) до 1.0
(полностью непрозрачный)). Значение по умолчанию: 1.0
. Пример:ctx.save();
ctx.fillStyle = 'green';
ctx.globalAlpha = 0.5;
ctx.fillRect(10, 10, 20, 20);
ctx.restore();
scale(<dx>, <dy>)
— изменяет масштабирование. Пример увеличения масштаба в два раза:ctx.save();
ctx.scale(2.0, 2.0);
ctx.fillRect(50, 10, 20, 20);
ctx.restore();
rotate(<Угол в радианах>)
— применяет трансформацию вращения. Пример вращения прямоугольника на 45 градусов относительно левого верхнего угла холста:ctx.save();
ctx.fillStyle = 'blue';
ctx.rotate((Math.PI / 180) * 45);
ctx.fillRect(50, -20, 40, 40);
ctx.restore();
Формула преобразования градусов в радианы:
radians = (Math.PI / 180) * degrees;
translate(<tx>, <ty>)
— сдвигает систему координат. Пример вращения прямоугольника на 45 градусов относительно точки вставки:ctx.save();
ctx.fillStyle = 'green';
ctx.translate(200, 200);
ctx.rotate((Math.PI / 180) * 45);
ctx.fillRect(0, 0, 40, 40);
ctx.restore();
Существует также несколько методов, позволяющих работать с матрицей трансформации. За подробной информацией обращайтесь к документации.
При наложении фигур по умолчанию пиксели верхней фигуры перекроют пиксели нижней фигуры. Такое поведение задается режимом наложения source-over
. С помощью свойства globalCompositeOperation
можно указать другой режим наложения. Возможны следующие значения в виде строки: source-over
, source-in
, source-out
, source-atop
, destination-over
, destination-in
, destination-out
, destination-atop
, lighter
, copy
, xor
, multiply
, screen
, overlay
, darken
, lighten
, color-dodge
, color-burn
, hard-light
, soft-light
, difference
, exclusion
, hue
, saturation
, color
, luminosity
. Пример указания значения:
ctx.fillStyle = 'blue';
ctx.fillRect(0, 50, 400, 200);
ctx.fillStyle = 'red';
ctx.globalCompositeOperation = 'source-in';
ctx.fillRect(100, 0, 200, 300);
Управлять характеристиками тени позволяют следующие свойства:
shadowBlur
— степень размытия тени (значение по умолчанию: 0
);shadowColor
— цвет тени (значение по умолчанию: черный цвет);shadowOffsetX
— смещение тени по горизонтали (значение по умолчанию: 0
);shadowOffsetY
— смещение тени по вертикали (значение по умолчанию: 0
).Пример создания квадрата с тенью:
<canvas id="canvas" width="400" height="300"></canvas>
<script>
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
ctx.shadowBlur = 15;
ctx.shadowColor = 'black';
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
ctx.fillStyle = 'blue';
ctx.fillRect(50, 50, 100, 100);
</script>
Выполнить манипуляции отдельными пикселами позволяют следующие методы:
getImageData()
— возвращает объект ImageData
, содержащий данные в виде массива с указанного фрагмента холста. Формат метода:getImageData(<X>, <Y>, <Ширина>, <Высота>)
Пример копирования всех данных с холста:
let data1 = ctx.getImageData(0, 0, canvas.width, canvas.height);
console.log(data1.width, data1.height);
createImageData()
— возвращает объект ImageData
, содержащий данные в виде массива (все пикселы будут иметь прозрачный черный цвет). Форматы метода:createImageData(<Ширина>, <Высота>)
createImageData(<ImageData>)
Пример:
let data2 = ctx.createImageData(100, 100);
console.log(data2.width, data2.height); // 100 100
console.log(data2.data[0], data2.data[1],
data2.data[2], data2.data[3]); // 0 0 0 0
При использовании второго формата копируются только размеры изображения, но сами данные при этом не копируются:
data2 = ctx.createImageData(data1);
console.log(data2.width, data2.height); // 400 300
console.log(data2.data[0], data2.data[1],
data2.data[2], data2.data[3]); // 0 0 0 0
putImageData()
— выводит данные из объекта <ImageData>
на холст. Формат метода:putImageData(<ImageData>, <X1>, <Y1>[,
<X2>, <Y2>, <Ширина>, <Высота>])
Параметры <X1>
и <Y1>
задают начальную позицию вставки на холсте. Параметры <X2>
и <Y2>
определяют начальные координаты внутри объекта <ImageData>
, а параметры <Ширина>
и <Высота>
— размеры копируемой области.
Класс ImageData
содержит следующие свойства:
width
— ширина изображения;height
— высота изображения;data
— одномерный массив с данными (объект Uint8ClampedArray
). Каждый пиксел кодируется четырьмя числами от 0
до 255
. Первое число задает долю красного цвета, второе — долю зеленого цвета, третье — долю синего цвета, а четвертое — альфа-канал. Нумерация пикселов в массиве идет слева направо и сверху вниз, т. е. по строкам. Получить размер массива позволяет свойство length
.Создадим пустой массив, заполним его красным цветом, а затем выведем на холст:
let canvas = document.getElementById('canvas');
let ctx = canvas.getContext('2d');
// ...
data2 = ctx.createImageData(canvas.width, canvas.height);
console.log(data2.width, data2.height); // 400 300
console.log(data2.data[0], data2.data[1], data2.data[2], data2.data[3]);
// 0 0 0 0
for (let i = 0; i < data2.data.length; i += 4) {
data2.data[i + 0] = 255; // R
data2.data[i + 1] = 0; // G
data2.data[i + 2] = 0; // B
data2.data[i + 3] = 255; // A
}
let canvas2 = document.getElementById('canvas2');
let ctx2 = canvas2.getContext('2d');
ctx2.putImageData(data2, 0, 0);
Метод toDataURL()
объекта холста возвращает URL с закодированными данными изображения в указанном формате. Формат метода:
toDataURL([<Тип>[, <Качество JPEG>]])
В первом параметре можно указать MIME-тип изображения. Если параметр не указан, то используется значение image/png
:
let dataPNG = canvas.toDataURL();
console.log(dataPNG);
// data:image/png;base64,iVBORw0KGgoAAAANSUhEU...
Во втором параметре можно указать качество JPEG-изображения в виде вещественного числа от 0
до 1
. Значение по умолчанию: 0.92
. Пример:
let dataJPEG = canvas.toDataURL('image/jpeg', 0.92);
console.log(dataJPEG);
// data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAA...
При использовании формата JPEG следует учитывать, что сжатие выполняется с потерями, поэтому можно получить различные артефакты на изображении. Кроме того, формат JPEG не поддерживает прозрачность.
Метод toBlob()
объекта холста возвращает объект Blob
с данными изображения в указанном формате. Формат метода:
toBlob(<Функция>[, <Тип>[, <Качество JPEG>]])
В первом параметре указывается ссылка на функцию, которая будет вызвана при завершении операции. Через параметр внутри функции будет доступен объект Blob
. Во втором параметре можно указать MIME-тип изображения. Если параметр не указан, то используется значение image/png
. В третьем параметре можно указать качество JPEG-изображения в виде вещественного числа от 0
до 1
. Пример:
canvas.toBlob( function(blob) {
console.log(blob);
// Blob {size: 2826, type: "image/jpeg"}
}, 'image/jpeg', 0.92);
Для преобразования объекта Blob
в объект ArrayBuffer
используется метод arrayBuffer()
, который возвращает объект Promise<ArrayBuffer>
. Чтобы из объекта ArrayBuffer
получить объект Buffer
, следует воспользоваться статическим методом from()
. Пример сохранения изображения с холста в файл при нажатии кнопки:
let btn1 = document.getElementById('btn1');
btn1.addEventListener('click', (e) => {
const fs = require('fs');
const path = require('path');
canvas.toBlob( async function(blob) {
let buf = Buffer.from(await blob.arrayBuffer());
let p = path.join(__dirname, 'test.png');
try {
fs.writeFileSync(p, buf, {encoding: null});
console.log('Сохранено');
} catch (e) {
console.log(e);
}
}, 'image/png');
});
При необходимости мы можем загрузить изображение из файла и нарисовать его на холсте, используя метод drawImage()
, например, при нажатии кнопки:
let btn3 = document.getElementById('btn3');
btn3.addEventListener('click', (e) => {
const fs = require('fs');
const path = require('path');
let p = path.join(__dirname, 'test.png');
if ( !fs.existsSync(p) ) {
console.log('Файл не найден');
return;
}
let img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
img.src = p;
});