Тег <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-seriftextAlign — задает горизонтальное выравнивание текста относительно начальной точки. Возможные значения в виде строки: 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 0putImageData() — выводит данные из объекта <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;
});