Разное

Javascript canvas: Canvas tutorial — Web APIs

04.04.2023

Содержание

Javascript свойства и методы элемента canvas

HTML5 тег <canvas> используется для отображения графики на лету при помощи скриптов (обычно JavaScript).

Тем не менее, сам по себе элемент <canvas> не имеет инструментария для рисования. Это всего лишь контейнер для графики. Чтобы в действительности что-то нарисовать в элементе <canvas>, необходимо использовать соответствующий скрипт.

Метод getContext() возвращает объект, предоставляющий методы и свойства для рисования в элементе <canvas>.

В данном справочнике приводится информация о свойствах и методах объекта getContext(«2d»), который может использоваться для вывода в элементе <canvas> текста, линий, прямоугольников, кругов и др.

Internet Explorer 9, Firefox, Opera, Chrome и Safari поддерживают элемент <canvas> и его свойства и методы. Internet Explorer 8 и более ранние версии не поддерживают элемент <canvas>.

Пиксельные манипуляции

Свойство/МетодОписание
dataВозвращает объект, содержащий данные изображения заданного объекта ImageData
heightВозвращает высоту объекта ImageData
widthВозвращает ширину объекта ImageData
createImageData()Создает новый, пустой объект ImageData
getImageData()Возвращает объект ImageData, который копирует пиксельные данные заданной прямоугольной области холста
putImageData()Помещает данные изображения (из заданного объекта ImageData) обратно в элемент <canvas>

Цвета, стили, тени

Свойство/МетодОписание
fillStyle
Устанавливает/возвращает цвет, градиент или шаблон, используемый для заливки графического объекта
shadowBlurУстанавливает/возвращает уровень размытости для теней
shadowColorУстанавливает/возвращает цвет для теней
shadowOffsetXУстанавливает/возвращает горизонтальное расстояние тени от фигуры
shadowOffsetY
Устанавливает/возвращает вертикальное расстояние тени от фигуры
strokeStyleУстанавливает/возвращает цвет, градиент или шаблон, используемый для обводки фигуры
addColorStop()Определяет цвета и позицию остановки в объекте градиента
createLinearGradient()Создает линейный градиент (для использования с содержимым элемента <canvas>)
createPattern()Размножает заданный элемент в заданном направлении
createRadialGradient()Создает радиальный/круговой градиент (для использования на содержимом элемента <canvas>)

Текст

Свойство/МетодОписание
fontУстанавливает/возвращает свойства шрифта для текстового содержимого
textAlignУстанавливает/возвращает выравнивание для текстового содержимого
textBaselineУстанавливает/возвращает базовую линию, используемую при выводе текста
fillText()Рисует текст с заливкой
measureText()Возвращает объект, содержащий ширину заданного текста
strokeText()Рисует текст без заливки

Компоновка

Свойство/МетодОписание
globalAlphaУстанавливает/возвращает текущее значение прозрачности или альфа-канала графического объекта
globalCompositeOperationУстанавливает/возвращает то, как исходное (новое) изображение нарисовано на целевом (существующем) изображении

Стили линий

Свойство/МетодОписание
lineCapУстанавливает/возвращает стиль концов нарисованной линии
lineJoinУстанавливает/возвращает тип угла, созданного пересечением двух линий
lineWidthУстанавливает/возвращает ширину текущей линии
miterLimitУстанавливает/возвращает максимальную длину среза

Контуры

Свойство/МетодОписание
arc()Создает дугу/кривую (используется для создания окружностей или их части)
arcTo()
Создает дугу/кривую между двумя касательными
beginPath()Начинает контур или сбрасывает текущий контур
bezierCurveTo()Создает кубическую кривую Безье
clip()Обрезает область любой формы и размера, находящуюся вне указанного контура
closePath()Замыкает контур соединяя последнюю точку с первой
fill()Делает заливку текущей фигуры (контура)
isPointInPath()Возвращает значение true, если заданная точка находится внутри текущего контура, в обратном случае возвращается значение false
lineTo()Добавляет новую точку контура и создает линию к этой точке от последней заданной точки
moveTo()Передвигает точку контура в заданные координаты не рисуя линию
quadraticCurveTo()Создает квадратичную кривую Безье
stroke()В действительности рисует определенный вами контур

Прямоугольники

Свойство/МетодОписание
clearRect()
Очищает заданную область пикселей внутри данного прямоугольника
fillRect()Рисует «залитый» прямоугольник
rect()Создает прямоугольник
strokeRect()Рисует прямоугольник (без заливки)

Вывод изображений

Свойство/МетодОписание
drawImage()Рисует изображение, содержимое другого элемента <canvas> или видео

Трансформации

Свойство/МетодОписание
rotate()Поворачивает текущий графический объект
scale()Изменяет масштаб текущего графического объекта
setTransform()Сбрасывает текущую матрицу трансформации в начальное состояние, а затем вызывает метод transform() с теми же параметрами
transform()Применяет заданную матрицу трансформации
translate()Ретранслирует позицию (0,0) в новое место

Другое

МетодОписание
save()Сохраняет состояние текущего контекста
restore()Возвращает ранее сохраненное состояние и атрибуты
createEvent() 
getContext() 
toDataURL() 
холст

— нпм

node-canvas — это реализация Canvas, поддерживаемая Cairo, для Node. js.

Установка

 $ npm install canvas 

По умолчанию будут загружены бинарные файлы для macOS, Linux и Windows. Если вы хотите выполнить сборку из исходного кода, используйте npm install --build-from-source и см. раздел Компиляция ниже.

Минимальная требуемая версия Node.js: 6.0.0 .

Компиляция

Если у вас нет поддерживаемой ОС или архитектуры процессора или вы используете --build-from-source модуль будет скомпилирован в вашей системе. Для этого требуется несколько зависимостей, включая Cairo и Pango.

Подробную информацию об установке см. на вики. Ниже приведены однострочные инструкции по установке для распространенных ОС. Обратите внимание, что libgif/giflib, librsvg и libjpeg являются необязательными и требуются только в том случае, если вам нужна поддержка GIF, SVG и JPEG соответственно. Требуется Cairo v1.10.0 или более поздней версии.

ОС Команда
ОС Х Использование Homebrew:
brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman
Убунту sudo apt-get install build-essential libcairo2-dev libpango1. 0-dev libjpeg-dev libgif-dev librsvg2-dev
Федора sudo yum install gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel
Солярис pkgin install cairo pango pkg-config xproto renderproto kbproto xextproto
OpenBSD doas pkg_add Каир Панго png jpeg giflib
Окна Посмотреть вики
Прочие Посмотреть вики

Mac OS X v10.11+: Если вы недавно обновились до Mac OS X v10.11+ и у вас возникли проблемы при компиляции, выполните следующую команду: xcode-select --install . Узнайте больше о проблеме на Stack Overflow. Если у вас установлен xcode 10.0 или выше, для сборки из исходного кода вам потребуется NPM 6.4.1 или выше.

Краткий пример

 const { createCanvas, loadImage } = require('canvas')
константный холст = createCanvas(200, 200)
const ctx = canvas. getContext('2d')
// Пишем "Отлично!"
ctx.font = 'Воздействие 30px'
ctx.rotate (0,1)
ctx.fillText('Отлично!', 50, 100)
// Рисуем линию под текстом
var text = ctx.measureText('Отлично!')
ctx.strokeStyle = 'rgba (0,0,0,0,5)'
ctx.beginPath()
ctx.lineTo(50, 102)
ctx.lineTo(50 + text.width, 102)
ctx.stroke()
// Рисуем кота в салатовом шлеме
loadImage('examples/images/lime-cat.jpg').then((image) => {
  ctx.drawImage(изображение, 50, 0, 70, 70)
  console.log('')
}) 

Обновление с 1.x до 2.x

Руководство по обновлению с 1.x до 2.x см. в журнале изменений.

Документацию по версии 1.x см. в ветке v1.x.

Документация

Этот проект представляет собой реализацию API веб-холста и максимально точно реализует этот API. Документацию по API см. на странице Mozilla Web Canvas API. (См. Статус совместимости для текущего соответствия API.) Все служебные методы и нестандартные API задокументированы ниже.

Вспомогательные методы

  • createCanvas()
  • создатьДанныеИзображения()
  • загрузитьИзображение()
  • регистрШрифт()

Нестандартные API

  • Image#src
  • Image#dataMode
  • Canvas#toBuffer()
  • Холст#createPNGStream()
  • Canvas#createJPEGStream()
  • Холст#createPDFStream()
  • Canvas#toDataURL()
  • CanvasRenderingContext2D#patternQuality
  • CanvasRenderingContext2D#качество
  • CanvasRenderingContext2D#textDrawingMode
  • CanvasRenderingContext2D#globalCompositeOperation = «насыщение»
  • CanvasRenderingContext2D#сглаживание

createCanvas()

 createCanvas(width: number, height: number, type?: 'PDF'|'SVG') => Canvas 

Создает экземпляр Canvas. Этот метод работает как в Node.js, так и в веб-браузерах, где нет конструктора Canvas. (См. browser.js для реализации, которая работает в браузерах.)

 const { createCanvas } = требуется ('холст')
const mycanvas = createCanvas(200, 200)
const myPDFcanvas = createCanvas(600, 800, 'pdf') // см. раздел «Поддержка PDF» 

createImageData()

 createImageData(ширина: число, высота: число) => ImageData
createImageData(данные: Uint8ClampedArray, ширина: число, высота?: число) => ImageData
// для альтернативных форматов пикселей:
createImageData(данные: Uint16Array, ширина: число, высота?: число) => ImageData 

Создает экземпляр ImageData. Этот метод работает как в Node.js, так и в веб-браузерах.

 const { createImageData } = требуется ('холст')
константная ширина = 20, высота = 20
const arraySize = ширина * высота * 4
const mydata = createImageData(новый Uint8ClampedArray(arraySize), ширина) 

loadImage()

 loadImage() => Обещание<Изображение> 

Удобный способ загрузки изображений. Этот метод работает как в Node.js, так и в веб-браузерах.

 const { loadImage } = требуется ('холст')
const myimg = loadImage('http://server.com/image.png')
myimg.then(() => {
  // делаем что-то с изображением
}).поймать(ошибка => {
  console.log('о нет!', ошибка)
})
// или с асинхронным/ожиданием:
const myimg = await loadImage('http://server.com/image.png')
// делаем что-то с изображением 

регистрШрифт()

 registerFont (путь: строка, {семейство: строка, вес?: строка, стиль?: строка}) => недействительным 

Чтобы использовать файл шрифта, который не установлен в качестве системного шрифта, используйте registerFont() для регистрации шрифта в Canvas. Это необходимо сделать до создания холста.

 const { registerFont, createCanvas } = требуется ('холст')
registerFont('comicsans.ttf', {семейство: 'Comic Sans'})
константный холст = createCanvas(500, 500)
const ctx = canvas.getContext('2d')
ctx. font = '12px "Comic Sans"'
ctx.fillText('Все ненавидят этот шрифт :(', 250, 10) 

Второй аргумент — это объект со свойствами, напоминающими свойства CSS, указанные в правилах @font-face . Необходимо указать не менее семейства . вес и стиль являются необязательными и по умолчанию равны «обычный» .

Источник изображения №

 img.src: строка|Буфер 

Как и в браузерах, img.src может быть установлен на data: URI или удаленный URL. Кроме того, node-canvas позволяет установить src на локальный путь к файлу или экземпляр Buffer .

 const {Изображение} = требуется ('холст')
// Из буфера:
fs.readFile('images/squid.png', (ошибка, кальмар) => {
  если (ошибиться) бросить ошибку
  const img = новое изображение()
  img.onload = () => ctx.drawImage(img, 0, 0)
  img.onerror = ошибка => {выбросить ошибку}
  img. src = кальмар
})
// Из локального пути к файлу:
const img = новое изображение()
img.onload = () => ctx.drawImage(img, 0, 0)
img.onerror = ошибка => {выбросить ошибку}
img.src = 'images/squid.png'
// С удаленного URL:
img.src = 'http://picsum.photos/200/300'
// ... как указано выше
// Из `data:` URI:
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
// ... см. выше 

Примечание. В некоторых случаях img.src= в настоящее время является синхронным. Однако вы всегда должны использовать img.onload и img.onerror , поскольку мы намерены сделать img.src= всегда асинхронным, как в браузерах. См. https://github.com/Automattic/node-canvas/issues/1007.

Режим изображения#данных

 img.dataMode: число 

Применяется только к изображениям JPEG, нарисованным на полотнах PDF.

Настройка img.dataMode = Image.MODE_MIME или Image.MODE_MIME|Image.MODE_IMAGE включает отслеживание данных MIME для изображений. Когда данные MIME отслеживаются, холсты PDF могут встраивать файлы JPEG непосредственно в выходные данные, а не перекодировать их в PNG. Это может значительно уменьшить размер файла и ускорить рендеринг.

 const { Изображение, createCanvas } = требуется ('холст')
const canvas = createCanvas(w, h, 'pdf')
const img = новое изображение()
img.dataMode = Image.MODE_IMAGE // Отслеживаются только данные изображения
img.dataMode = Image.MODE_MIME // Отслеживаются только MIME-данные
img.dataMode = Image.MODE_MIME | Image.MODE_IMAGE // Оба отслеживаются 

При работе с холстом, отличным от PDF, данные изображения должны отслеживаться; в противном случае вывод будет мусором.

Включение отслеживания MIME-данных не дает никаких преимуществ (только замедление), если только вы не создаете PDF-файл.

Canvas#toBuffer()

 canvas. toBuffer((err: Error|null, result: Buffer) => void, mimeType?: string, config?: any) => void
canvas.toBuffer(mimeType?: string, config?: any) => Buffer 

Создает объект Buffer , представляющий изображение, содержащееся на холсте.

  • обратный вызов Если указан, буфер будет предоставлен в обратном вызове, а не возвращен функцией. Вызывается с ошибкой в ​​качестве первого аргумента, если кодирование завершилось неудачно, или с результирующим буфером в качестве второго аргумента, если кодирование завершилось успешно. Не поддерживается для mimeType raw или для холстов PDF или SVG.
  • mimeType Строка, указывающая формат изображения. Допустимые параметры: image/png , image/jpeg (если node-canvas был создан с поддержкой JPEG), raw (незакодированные данные в порядке BGRA в системах с прямым порядком байтов (в большинстве), ARGB в системах с прямым порядком байтов; сверху вниз), application/pdf (для холстов PDF) и image/svg+xml (для холстов SVG). По умолчанию используется image/png для холстов изображений или соответствующий тип для холстов PDF или SVG.
  • конфигурация
    • Для image/jpeg , объект, указывающий качество (от 0 до 1), следует ли использовать прогрессивное сжатие и/или следует ли использовать субдискретизацию цветности: {качество: 0,75, прогрессивный: ложь, цветовая субдискретизация: истина} . Все свойства являются необязательными.

    • Для image/png , объект, указывающий уровень сжатия ZLIB (от 0 до 9), фильтр(ы) сжатия, палитру (только индексированные PNG), индекс фоновой палитры (только индексированные PNG) и/или разрешение (ppi): {compressionLevel: 6, фильтры: canvas.PNG_ALL_FILTERS, палитра: не определена, backgroundIndex: 0, разрешение: не определено} . Все свойства являются необязательными.

      Обратите внимание, что формат PNG кодирует разрешение в пикселях на метр, поэтому, если вы укажете 96 , файл будет кодировать 3780 ppm (~96,01 ppi). Разрешение не определено по умолчанию, чтобы соответствовать обычному поведению браузера.

    • Для application/pdf , объект, определяющий необязательные метаданные документа: {название: строка, автор: строка, тема: строка, ключевые слова: строка, создатель: строка, Дата создания: Дата, Дата модификации: Дата} . Все свойства являются необязательными и по умолчанию равны 9.0011 undefined , за исключением Дата создания , которая по умолчанию равна текущей дате. Для добавления метаданных требуется Cairo 1.16.0 или более поздняя версия.

      Описание этих свойств см. на стр. 550 документа PDF 32000-1:2008.

      Обратите внимание, что для ключевых слов нет стандартного разделителя . Рекомендуется использовать пробел, поскольку он широко используется другими приложениями, и Cairo заключит список ключевых слов в кавычки, если используется запятая или точка с запятой.

Возвращаемое значение

Если обратный вызов не предусмотрен, создается буфер . Если обратный вызов предоставляется, нет.

Примеры
 // По умолчанию: buf содержит изображение в формате PNG
константа buf = canvas.toBuffer()
// PNG-кодировка, уровень сжатия zlib 3 для более быстрого сжатия, но больших файлов, без фильтрации
const buf2 = canvas.toBuffer('image/png', {compressionLevel: 3, фильтры: canvas.PNG_FILTER_NONE})
// JPEG-кодирование, качество 50%
const buf3 = canvas.toBuffer('image/jpeg', {качество: 0,5})
// Асинхронный PNG
canvas.toBuffer((ошибка, buf) => {
  if (err) throw err // ошибка кодирования
  // buf — изображение в формате PNG
})
canvas.toBuffer((ошибка, buf) => {
  if (err) throw err // ошибка кодирования
  // buf — изображение в формате JPEG с номером 95% качество
}, 'изображение/jpeg', {качество: 0,95})
// Значения пикселей BGRA, родной порядок байтов
const buf4 = canvas.toBuffer('сырой')
const {шаг, ширина} = холст
// В памяти это `canvas.height * canvas.stride` в байтах.
// Верхний ряд пикселей в порядке BGRA на оборудовании с прямым порядком байтов,
// слева направо, это:
const topPixelsBGRALeftToRight = buf4. slice(0, ширина * 4)
// И третья строка:
const row3 = buf4.slice(2 * шаг, 2 * шаг + ширина * 4)
// холсты SVG и PDF
const myCanvas = createCanvas(w, h, 'pdf')
myCanvas.toBuffer() // возвращает буфер, содержащий холст в формате PDF
// С необязательными метаданными:
myCanvas.toBuffer('приложение/pdf', {
  название: 'моя картина',
  ключевые слова: «демонстрация node.js в Каире»,
  Дата создания: новая Дата ()
}) 

Canvas#createPNGStream()

 canvas.createPNGStream(config?: any) => ReadableStream 

Создает ReadableStream , который выдает данные в формате PNG.

  • config Объект, указывающий уровень сжатия ZLIB (от 0 до 9), фильтр(ы) сжатия, палитру (только индексированные PNG) и/или индекс фоновой палитры (только индексированные PNG): {compressionLevel: 6, фильтры: canvas.PNG_ALL_FILTERS, палитра: не определена, backgroundIndex: 0, разрешение: не определено} . Все свойства являются необязательными.
Примеры
 const fs = require('fs')
const out = fs.createWriteStream(__dirname + '/test.png')
постоянный поток = canvas.createPNGStream()
поток.труба(выход)
out.on('finish', () => console.log('Файл PNG был создан.')) 

Чтобы кодировать индексированные PNG из холстов с pixelFormat: 'A8' или 'A1' , предоставьте объект параметров:

 константная палитра = новый Uint8ClampedArray([
  //r g b a
    0, 50, 50, 255, // индекс 1
   10, 90, 90, 255, // индекс 2
  127, 127, 255, 255
  // ...
])
холст.createPNGStream({
  палитра: палитра,
  backgroundIndex: 0 // необязательный, по умолчанию 0
}) 

Canvas#createJPEGStream()

 canvas.createJPEGStream(config?: any) => ReadableStream 

Создает ReadableStream , который выдает данные в формате JPEG.

Примечание. На данный момент createJPEGStream() является синхронным внутри. То есть он работает в основном потоке, а не в пуле потоков libuv.

  • config объект, указывающий качество (от 0 до 1), следует ли использовать прогрессивное сжатие и/или следует ли использовать субдискретизацию цветности: {качество: 0,75, прогрессивный: false, chromaSubsampling: true} . Все свойства являются необязательными.
Примеры
 const fs = require('fs')
const out = fs.createWriteStream(__dirname + '/test.jpeg')
постоянный поток = canvas.createJPEGStream()
поток.труба(выход)
out.on('finish', () => console.log('Файл JPEG создан.'))
// Отключите 2x2 chromaSubsampling для более глубоких цветов и используйте более высокое качество
постоянный поток = canvas.createJPEGStream({
  качество: 0,95,
  chromaSubsampling: ложь
}) 

Canvas#createPDFStream()

 canvas.createPDFStream(config?: any) => ReadableStream 
  • config объект, определяющий необязательные метаданные документа: {название: строка, автор: строка, тема: строка, ключевые слова: строка, создатель: строка, createDate: дата, modDate: дата} . См. toBuffer() для получения дополнительной информации. Для добавления метаданных требуется Cairo 1.16.0 или более поздняя версия.

Применяется только к холстам PDF. Создает ReadableStream , который выдает закодированный PDF-файл. canvas.toBuffer() также создает закодированный PDF-файл, но createPDFStream() можно использовать для уменьшения использования памяти.

Canvas#toDataURL()

Это стандартный API, но поддерживается несколько нестандартных вызовов. Полный список поддерживаемых вызовов:

 dataUrl = canvas.toDataURL() // по умолчанию PNG
dataUrl = canvas.toDataURL('изображение/png')
dataUrl = canvas.toDataURL('изображение/jpeg')
dataUrl = canvas.toDataURL('image/jpeg', качество) // качество от 0 до 1
canvas.toDataURL((err, png) => { }) // по умолчанию PNG
canvas.toDataURL('image/png', (ошибка, png) => {})
canvas.toDataURL('image/jpeg', (err, jpeg) => { }) // синхронизация JPEG не поддерживается
canvas. toDataURL('image/jpeg', {...opts}, (err, jpeg) => { }) // допустимые параметры см. в Canvas#createJPEGStream
canvas.toDataURL('image/jpeg', качество, (ошибка, jpeg) => { }) // спецификация; качество от 0 до 1 

CanvasRenderingContext2D#patternQuality

 context.patternQuality: 'быстрый'|'хороший'|'лучший'|'ближайший'|'билинейный' 

По умолчанию «хорошо» . Влияет на качество рендеринга шаблона (градиента, изображения и т. д.).

CanvasRenderingContext2D#качество

 context.quality: 'быстрый'|'хороший'|'лучший'|'ближайший'|'билинейный' 

По умолчанию «хорошо» . Подобно patternQuality , но применяется к преобразованиям, влияющим не только на шаблоны.

CanvasRenderingContext2D#textDrawingMode

 context.textDrawingMode: 'путь'|'глиф' 

По умолчанию 'путь' . Эффект зависит от типа холста:

  • Стандарт (изображение) глиф и путь оба приводят к растровому тексту. Режим глифа быстрее, чем путь , но может привести к тексту более низкого качества, особенно при повороте или переводе.

  • PDF глиф вставит текст вместо путей в PDF. Это быстрее для кодирования, быстрее для открытия с помощью программ просмотра PDF, дает меньший размер файла и делает текст доступным для выбора. Подмножество шрифта, необходимое для отображения глифов, будет встроено в PDF-файл. Обычно это режим, который вы хотите использовать с холстами PDF.

  • SVG глиф делает , а не причиной создания элементов, как можно было бы ожидать (ошибка Каира). Скорее glyph создаст раздел с для каждого глифа, затем эти глифы будут повторно использованы через элементы . Режим path создает элемент для каждой текстовой строки. Режим глиф быстрее и дает меньший размер файла.

В режиме глиф методы ctx.strokeText() и ctx.fillText() ведут себя одинаково (кроме использования стилей обводки и заливки соответственно).

Это свойство отслеживается как часть состояния холста при сохранении/восстановлении.

CanvasRenderingContext2D#globalCompositeOperation = ‘насыщение’

В дополнение ко всем стандартным глобальным составным операциям, определенным в спецификации Canvas, также доступна операция «насыщение».

CanvasRenderingContext2D#сглаживание

 context.antialias: 'по умолчанию'|'нет'|'серый'|'субпиксель' 

Устанавливает режим сглаживания.

Поддержка вывода PDF

node-canvas может создавать PDF-документы вместо изображений. Тип холста должен быть установлен при создании холста следующим образом:

 const canvas = createCanvas(200, 500, 'pdf') 

Затем доступен дополнительный метод . addPage() для создания многостраничных PDF-файлов:

 // На первой странице
ctx.font = 'Гельветика 22px'
ctx.fillText('Привет, мир', 50, 80)
ctx.addPage ()
// Теперь на второй странице
ctx.font = 'Гельветика 22px'
ctx.fillText('Привет, мир 2', 50, 80)
canvas.toBuffer() // возвращает файл PDF
canvas.createPDFStream() // возвращает ReadableStream, который генерирует PDF
// С необязательными метаданными документа (требуется Cairo 1.16.0):
canvas.toBuffer('приложение/pdf', {
  название: 'моя картина',
  ключевые слова: «демонстрация node.js в Каире»,
  Дата создания: новая Дата ()
}) 

Также можно создавать страницы разных размеров, передавая width и height методу .addPage() :

 ctx.font = '22px Helvetica'
ctx.fillText('Привет, мир', 50, 80)
ctx.addPage (400, 800)
ctx.fillText('Hello World 2', 50, 80) 

См. также:

  • Image#dataMode для встраивания файлов JPEG в файлы PDF
  • Canvas#createPDFStream() для создания потоков PDF
  • CanvasRenderingContext2D#textDrawingMode для встраивания текста вместо путей

Поддержка вывода SVG

node-canvas может создавать документы SVG вместо изображений. Тип холста должен быть установлен при создании холста следующим образом:

 const canvas = createCanvas(200, 500, 'svg')
// Используйте обычные примитивы.
fs.writeFileSync('out.svg', canvas.toBuffer()) 

Поддержка изображений SVG

Если librsvg доступен при установленном node-canvas, node-canvas может отображать изображения SVG в контексте вашего холста. В настоящее время это работает путем растеризации изображения SVG (т. е. рисование изображения SVG на холсте SVG не сохранит данные SVG).

 const img = новое изображение()
img.onload = () => ctx.drawImage(img, 0, 0)
img.onerror = ошибка => {выбросить ошибку}
img.src = './example.svg' 

Форматы пикселей изображения (экспериментальные)

node-canvas имеет экспериментальную поддержку дополнительных форматов пикселей, примерно следуя предложению цветового пространства Canvas.

 константный холст = createCanvas(200, 200)
const ctx = canvas.getContext('2d', { pixelFormat: 'A8' }) 

По умолчанию холсты создаются в RGBA32 , который соответствует собственному поведению HTML Canvas. Каждый пиксель 32 бита. API-интерфейсы JavaScript, использующие пиксельные данные ( getImageData , putImageData ), сохраняют цвета в порядке {красный, зеленый, синий, альфа} без предварительного умножения альфа-канала. (API C++ хранит цвета в порядке {альфа, красный, зеленый, синий} в исходном порядке байтов с предварительным умножением альфа-канала.)

Эти дополнительные форматы пикселей имеют экспериментальную поддержку:

  • RGB24 Аналогично RGBA32 , но 8 альфа-битов всегда непрозрачны. Этот формат всегда используется, если для атрибута контекста alpha установлено значение false (т.е. canvas.getContext('2d', {alpha: false}) ). Этот формат может быть быстрее, чем RGBA32 , потому что прозрачность не нужно вычислять.
  • A8 Каждый пиксель состоит из 8 бит. Этот формат можно использовать либо для создания изображений в градациях серого (обрабатывая каждый байт как альфа-значение), либо для создания индексированных PNG (обрабатывая каждый байт как индекс палитры) (см. пример с использованием альфа-значений с fillStyle и пример с использованием imageData ).
  • RGB16_565 Каждый пиксель имеет длину 16 бит, с красным в старших 5 битах, зеленым в средних 6 битах и ​​синим в младших 5 битах, в соответствии с исходным порядком байтов платформы. Некоторые аппаратные устройства и буферы кадров используют этот формат. Обратите внимание, что PNG не поддерживает этот формат; при создании PNG изображение будет преобразовано в 24-битный RGB. Таким образом, этот формат является неоптимальным для создания файлов PNG. ImageData экземпляров для этого режима используют Uint16Array вместо Uint8ClampedArray .
  • A1 Каждый пиксель имеет 1 бит, а пиксели упакованы вместе в 32-битные количества. Порядок битов соответствует порядку байтов платформа: на машине с прямым порядком байтов первый пиксель является наименее значащим битом. Этот формат можно использовать для создания одноцветных изображений. Поддержка этого формата неполная, см. примечание ниже.
  • RGB30 Каждый пиксель состоит из 30 битов, красный в верхних 10, зеленый в средних 10 и синий в младших 10. (Требуется Cairo 1.12 или более поздняя версия.) Поддержка этого формата неполная, см. примечание ниже.

Примечания и предостережения:

  • Использование формата, отличного от стандартного, может повлиять на поведение API, использующих пиксельные данные:

    • context2d.createImageData Размер возвращаемого массива зависит от количества битов на пиксель для базового формата данных изображения в соответствии с приведенными выше описаниями.
    • context2d.getImageData Формат возвращаемого массива зависит от базового режима изображения в соответствии с приведенными выше описаниями. Помните о порядке следования байтов платформы, который можно определить с помощью node.js 9.0011 os.endianness() функция.
    • context2d.putImageData То же, что и выше.
  • A1 и RGB30 еще не поддерживают getImageData или putImageData . Есть пример использования и/или мнение по работе с этими форматами? Откройте вопрос и дайте нам знать! (См. № 935.)

  • A1 , A8 , RGB30 и RGB16_565 с размытием теней могут привести к сбою или некорректному отображению.

  • Конструкторы ImageData(width, height) и ImageData(Uint8ClampedArray, width) предполагают 4 байта на пиксель. Чтобы создать экземпляр ImageData с другим количеством байтов на пиксель, используйте new ImageData(new Uint8ClampedArray(size), width, height) или new ImageData(new Uint16ClampedArray(size), width, height) .

Тестирование

Сначала убедитесь, что вы собрали последнюю версию. Получите все необходимые зависимости (см. компиляцию выше) и запустите:

 npm install --build-from-source
 

Для визуальных тестов: npm запустите тестовый сервер и укажите в браузере http://localhost:4000.

Для модульных тестов: npm run test .

Тесты

Тесты находятся в каталоге тестов .

Примеры

Строка примеров в каталоге примеров . Большинство из них создают изображение png с тем же именем, а другие, такие как live-clock.js , запускают HTTP-сервер для просмотра в браузере.

Авторы оригинала

  • Т.Дж. Холовайчук (tj)
  • Натан Райлих (TooTallNate)
  • Род Вагг (рвагг)
  • Юрий Зайцев (kangax)

Лицензия

node-canvas

(Лицензия MIT)

Copyright (c) LearnBoost, 2010 г., и участники

Copyright (c) Automattic, Inc., 2014 г. и участники com>

Настоящим предоставляется бесплатное разрешение любому лицу, получившему копию это программное обеспечение и связанные с ним файлы документации («Программное обеспечение»), чтобы иметь дело с Программное обеспечение без ограничений, включая, помимо прочего, права на использовать, копировать, изменять, объединять, публиковать, распространять, сублицензировать и/или продавать копии Программное обеспечение и разрешать лицам, которым предоставляется Программное обеспечение, делать это, при следующих условиях:

Приведенное выше уведомление об авторских правах и это уведомление о разрешении должны быть включены во все копии или существенные части Программного обеспечения.

ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕТСЯ, ВКЛЮЧАЯ, ПОМИМО ПРОЧЕГО, ГАРАНТИИ КОММЕРЧЕСКОЙ ЦЕННОСТИ, ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННОЙ ЦЕЛИ И НЕНАРУШЕНИЯ ПРАВ. НИ ПРИ КАКИХ ОБСТОЯТЕЛЬСТВАХ АВТОРЫ ИЛИ ОБЛАДАТЕЛИ АВТОРСКИМ ПРАВОМ НЕСУТ ОТВЕТСТВЕННОСТЬ ЗА ЛЮБЫЕ ПРЕТЕНЗИИ, УЩЕРБ ИЛИ ДРУГУЮ ОТВЕТСТВЕННОСТЬ, ПО ДОГОВОРУ, ДЕЛИКТУ ИЛИ ИНЫМ ОБРАЗОМ, ВОЗНИКАЮЩИМ ИЗ, ИЗ ИЛИ В СОЕДИНЕНИЕ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕ ИЛИ ДРУГИЕ ОПЕРАЦИИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.

Анализатор BMP

См. лицензию

Учебное пособие по HTML Canvas API

Руководство по Canvas API, одному из способов, предлагаемых браузерами для рисования на экране.

Совет: также ознакомьтесь с моими руководствами о том, как распечатать холст по URL-адресу данных, как записать текст в HTML-холст, как загрузить изображение в HTML-холст и как создать и сохранить изображение с помощью Node.js и Canvas.

HTML-холст — это HTML-тег , который представляет собой элемент, на который мы можем рисовать с помощью Canvas API.

Создать холст

Создать холст так же просто, как перетащить в пустой файл HTML:

Вы ничего не видите на странице, потому что холст невидим элемент. Давайте добавим границу:

Chrome автоматически добавляет отступ в 8 пикселей к элементу body . Вот почему наша граница выглядит как рамка, и вы можете удалить это поле, установив

 body {
  маржа: 0;
} 

Пока оставим значение по умолчанию.

Наш холст теперь доступен из JavaScript с помощью DOM Selectors API, поэтому мы можем использовать document.querySelector() :

 const canvas = document.querySelector('canvas') 

Изменить цвет фона холста

Вы делаете это в CSS:

 холст {
  цвет фона: голубой;
} 

Изменение размера холста

Вы можете установить ширину и высоту в CSS:

 холст {
  граница: 1px сплошной черный;
  ширина: 100%;
  высота: 100%;
} 

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

Если вы поместите холст как элемент первого уровня в HTML, приведенный выше код расширит холст, чтобы он соответствовал всему телу.

Тело не заполняет весь размер окна. Вместо этого, чтобы заполнить всю страницу, нам нужно использовать JavaScript:

 canvas.width = window.innerWidth
canvas.height = window.innerHeight 

Если вы теперь удалите поле тела и установите фон холста с помощью CSS, мы сможем заполнить всю нашу страницу холстом и начать рисовать на нем:

Если размер окна изменяется, нам также необходимо пересчитать ширину холста, используя debounce , чтобы избежать слишком большого количества вызовов изменения размера нашего холста (событие resize может вызываться сотни раз, когда вы перемещаете окно с помощью мышь, например):

 const debounce = (func) => {
  пусть таймер
  возврат (событие) => {
    если (таймер) {clearTimeout(таймер)}
    таймер = setTimeout (функция, 100, событие)
  }
}
window. addEventListener('resize', debounce(() => {
  холст.ширина = окно.внутренняя ширина
  холст.высота = окно.внутренняя высота
})) 

Получить контекст с холста

Мы хотим рисовать на холсте.

Для этого нам нужно получить контекст:

 const c = canvas.getContext('2d') 

Некоторые присваивают контекст переменной с именем c , некоторые ctx — это обычный способ сократить «контекст»

Метод getContext() возвращает контекст рисования на холсте в соответствии с типом, который вы передаете в качестве параметра.

Допустимые значения:

  • 2d , тот, который мы будем использовать
  • webgl для использования WebGL версии 1
  • webgl2 для использования WebGL версии 2
  • Bitmaprenderer для использования с ImageBitmap

В зависимости от типа контекста можно передать второй параметр функции getContext() , чтобы указать дополнительные параметры.

В случае контекста 2d у нас в основном есть один параметр, который мы можем использовать во всех браузерах, и это alpha , логическое значение, которое по умолчанию равно true. Если установлено значение false, браузер знает, что у холста нет прозрачного фона, и может ускорить рендеринг.

Рисовать элементы на холсте

С помощью контекста теперь мы можем рисовать элементы.

У нас есть несколько способов сделать это. Можем нарисовать:

  • текст
  • строк
  • прямоугольники
  • путей
  • изображений

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

Начнем с самого простого: прямоугольника.

Для этой цели служит метод fillRect(x, y, width, height) : начиная с позиции x 100 и y 100:

Вы можете раскрасить прямоугольник, используя метод fillStyle() , передав любую допустимую строку цвета CSS:

 c. fillStyle = 'white'
c.fillRect(100, 100, 100, 100) 

Теперь вы можете проявить творческий подход и нарисовать много вещей таким образом:

 for (let i = 0; i < 60; i++) {
  для (пусть j = 0; j < 60; j++) {
    c.fillStyle = `rgb(${i * 5}, ${j * 5}, ${(i+j) * 50})`
    c.fillRect(j * 20, i * 20, 10, 10)
  }
} 

или

 для (пусть i = 0; i < 60; i++) {
  для (пусть j = 0; j < 60; j++) {
    c.fillStyle = `rgb(${i * 5}, ${j * 5}, ${(i+j) * 50})`
    c.fillRect(j * 20, я * 20, 20, 20)
  }
} 

Элементы чертежа

Как уже упоминалось, вы можете рисовать многое:

  • текст
  • строк
  • прямоугольники
  • путей
  • изображений

Давайте просто посмотрим на некоторые из них, прямоугольники и текст, чтобы понять, как все работает. Вы можете найти API для всего остального, что вам нужно здесь.

Изменение цвета

Используйте свойства fillStyle и strokeStyle для изменения цвета заливки и обводки любой фигуры. Они принимают любой допустимый цвет CSS, включая строки и вычисления RGB:

 c.strokeStyle = `rgb(255, 255, 255)`
c.fillStyle = `white` 

Прямоугольники

У вас есть 3 метода:

  • clearRect(x, y, ширина, высота)
  • fillRect(x, y, ширина, высота)
  • strokeRect(x, y, ширина, высота)

Мы видели fillRect() в предыдущем разделе. strokeRect() аналогичен тому, как он вызывается, но вместо заполнения прямоугольника он просто рисует штрих, используя текущий стиль штриха (который можно изменить с помощью кнопки 9).0011 strokeStyle свойство контекста):

 const c = canvas.getContext('2d')
для (пусть я = 0; я < 61; я ++) {
  для (пусть j = 0; j < 61; j++) {
    c.strokeStyle = `rgb(${i * 5}, ${j * 5}, ${(i+j) * 50})`
    c.strokeRect(j * 20, i * 20, 20, 20)
  }
} 

clearRect() делает область прозрачной:

Text

Рисование текста похоже на прямоугольники. У вас есть 2 метода

  • fillText(text, x, y)
  • strokeText(текст, x, y)

, которые позволяют писать текст на холсте.

x и y относятся к левому нижнему углу.

Вы изменяете семейство и размер шрифта, используя свойство font холста:

 c.font = '148px Courier New' 

Существуют и другие свойства, связанные с текстом, которые вы можете изменить (* = по умолчанию) :

  • textAlign (начало*, конец, слева, справа, по центру)
  • textBaseline (верхний, висящий, средний, буквенный*, идеографический, нижний)
  • направление (ltr, rtl, наследование*)

Lines

Чтобы нарисовать линию, вы сначала вызываете метод beginPath() , затем указываете начальную точку с помощью moveTo(x, y) , а затем вызываете lineTo(x, y) , чтобы сделать линия к этому новому набору координат. Наконец, вы вызываете stroke() :

 c.beginPath()
c.moveTo(10, 10)
c.lineTo(300, 300)
с.ход() 

Линия будет окрашена в соответствии со значением свойства c.strokeStyle .

Более сложный пример

Этот код создает холст, который генерирует 800 кругов:

Каждый круг точно содержится в холсте, и его радиус рандомизирован.

При каждом изменении размера окна элементы генерируются заново.

Вы можете поэкспериментировать с Codepen.

 const canvas = document.querySelector('холст')
холст.ширина = окно.внутренняя ширина
холст.высота = окно.внутренняя высота
const c = canvas.getContext('2d')
константа круговКоунт = 800
константа colorArray = [
  '#046975',
  '#2EA1D4',
  '#3BCC2A',
  '#FFDF59',
  '#FF1D47'
]
const debounce = (func) => {
  пусть таймер
  возврат (событие) => {
    если (таймер) {clearTimeout(таймер)}
    таймер = setTimeout (функция, 100, событие)
  }
}
window.addEventListener('resize', debounce(() => {
  холст. ширина = окно.внутренняя ширина
  холст.высота = окно.внутренняя высота
  в этом()
}))
константа инициализации = () => {
  for (пусть я = 0; я 

Другой пример: анимация элементов на холсте

На основе приведенного выше примера мы анимируем элементы с помощью цикла. Каждый круг имеет свою «жизнь» и движется в границах холста. Когда граница достигнута, она возвращается обратно:

См. забаву Pen HTML Canvas с кругами, а не интерактивность от Flavio Copes (@flaviocopes) на CodePen.

Мы достигаем этого, используя requestAnimationFrame() и слегка перемещая изображение при каждой итерации рендеринга кадра.

Взаимодействие с элементами на холсте

Вот приведенный выше пример, расширенный для взаимодействия с кругами с помощью мыши.

Когда вы наводите курсор на холст, элементы рядом с мышью увеличиваются в размерах и возвращаются к нормальному состоянию, когда вы перемещаетесь в другое место:

См. забавное представление Pen HTML Canvas с кругами от Flavio Copes (@flaviocopes) на CodePen .

Как это работает? Ну, сначала я отслеживаю позицию мыши, используя 2 переменные:

 пусть mousex = не определено
пусть мышка = не определено
window.addEventListener('mousemove', (e) => {
  мышьx = ех
  мышка = ey
}) 

Затем мы используем эти переменные внутри метода update() класса Circle, чтобы определить, должен ли радиус увеличиваться (или уменьшаться):

 if (mousex - this.x < DistanceFromMouse && mousex - this.x > -distanceFromMouse && mousey - this.y < DistanceFromMouse && mousey - this.y > -distanceFromMouse) {
  если (this.radius < maxRadius) this.radius += 1
} еще {
  если (this.radius > this.minRadius) this.radius -= 1
} 

DistanceFromMouse — это значение, выраженное в пикселях (установленное на 200), которое определяет, как далеко мы хотим, чтобы круги реагировали на мышь.

Производительность

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *