W3docs

HTML тег <canvas>

Тег HTML <canvas> задаёт область для рисования графики, фигур, текста и анимаций с помощью JavaScript. Размеры, доступность и canvas vs SVG.

Тег <canvas> — один из элементов HTML5. Он определяет область на веб-странице, в которой с помощью скриптов (как правило JavaScript) можно создавать различные объекты, изображения, анимации и фотокомпозиции. Для рисования графики необходимо использовать скрипт, поскольку тег <canvas> является лишь контейнером для неё.

При работе с canvas важно различать два часто путаемых понятия: элемент canvas и контекст элемента. Элемент — это то, что встроено в HTML (узел DOM). Контекст canvas — это объект с собственными свойствами и методами для рендеринга. Контекст бывает 2D и 3D. Элемент canvas может иметь только один контекст.

Внутри тега <canvas> следует размещать альтернативное содержимое, чтобы старые браузеры без поддержки canvas, браузеры с отключённым JavaScript и программы чтения с экрана могли отображать что-то осмысленное (см. раздел Доступность ниже).

Можно использовать CSS для изменения отображаемого размера canvas, однако лучше задавать разрешение с помощью атрибутов width и height на элементе <canvas> — в HTML или через JavaScript — чтобы избежать размытого или растянутого растрового изображения.

По умолчанию элемент <canvas> имеет размер 300×150 пикселей.

Canvas vs. SVG: что выбрать?

И <canvas>, и <svg> рисуют графику в браузере, однако работают принципиально по-разному:

  • Canvas основан на пикселях (немедленный режим). После того как вы что-то нарисовали, это становится плоским растровым изображением — браузер не хранит в памяти отдельные фигуры. У нарисованного содержимого нет DOM, поэтому нельзя прикреплять обработчики событий к отдельным фигурам; чтобы «переместить» круг, нужно очистить весь холст и перерисовать сцену заново на каждом кадре.
  • SVG основан на фигурах (сохранённый режим). Каждый элемент остаётся в DOM, может быть стилизован через CSS, управляем скриптами и не зависит от разрешения экрана (остаётся чётким при любом масштабе).

Используйте canvas, когда часто перерисовываете содержимое или работаете с большим количеством объектов: игры, эффекты частиц, визуализация данных в реальном времени, обработка изображений. Используйте SVG, когда у вас умеренное количество фигур, которые должны быть интерактивными, доступными или масштабируемыми без потерь: иконки, графики, диаграммы. Грубое правило: canvas лучше при большом количестве быстро меняющихся пикселей, SVG — при меньшем числе фигур, которые остаются интерактивными.

Размеры: атрибуты width/height и CSS

Это самая распространённая ловушка при работе с canvas. Холст имеет два размера:

  • Атрибуты width и height задают размер буфера рисования (его разрешение в пикселях).
  • CSS width/height задают отображаемый размер на странице.

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

<!-- Good: drawing buffer matches what you draw -->
<canvas width="400" height="200"></canvas>

<!-- Risky: CSS stretches a default 300x150 bitmap to 600x300, blurring it -->
<canvas style="width: 600px; height: 300px;"></canvas>

Для чёткого отображения на экранах с высоким DPI («Retina») умножьте размер буфера на window.devicePixelRatio (например, задайте атрибуты как cssWidth * devicePixelRatio), а затем вызовите ctx.scale(dpr, dpr) перед рисованием.

Синтаксис

Тег <canvas> является парным. Содержимое записывается между открывающим (<canvas>) и закрывающим (</canvas>) тегами.

Пример использования HTML-тега <canvas>:

Скрипт ниже получает элемент с помощью document.getElementById() и вызывает getContext('2d') для получения 2D-контекста рисования — объекта, который содержит все методы и свойства для рисования. Установка fillStyle выбирает цвет заливки, а fillRect(x, y, width, height) рисует закрашенный прямоугольник, верхний левый угол которого находится в точке (x, y). Координаты canvas начинаются с (0, 0) в верхнем левом углу: x увеличивается вправо, y — вниз.

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head> 
  <body>
    <canvas id="canvasExample">Your browser doesn’t support the HTML5 canvas element.</canvas>
    <script>
      const c = document.getElementById('canvasExample');
      const ctx = c.getContext('2d');
      ctx.fillStyle = '#1c87c9';
      ctx.fillRect(10, 50, 80, 80);
    </script>
  </body>
</html>

Результат

canvas exemple

Пример использования HTML-тега <canvas> для текста:

Для рисования текста задайте свойство font (тот же синтаксис, что и у сокращённого CSS-свойства font) и fillStyle для цвета, затем вызовите fillText(text, x, y). Точка (x, y) здесь — это позиция базовой линии текста, а не его верхнего левого угла. Обратите внимание, что width и height заданы как атрибуты элемента, чтобы буфер рисования соответствовал области, в которую мы рисуем.

<!DOCTYPE HTML>
<html>
  <head>
    <title>Title of the document</title>
  </head> 
  <body>
    <canvas id="canvasExample" width="400" height="200"></canvas>
    <script>
      const canvas = document.getElementById('canvasExample');
      const context = canvas.getContext('2d');
      context.font = '30pt Calibri';
      context.fillStyle = '#1c87c9';
      context.fillText('Canvas Example !', 50, 100);
    </script>
  </body>
</html>

Пример использования HTML-тега <canvas> для рисования линии:

Линии и другие пути рисуются в три шага. moveTo(x, y) поднимает «перо» и помещает его в начальную точку без рисования. lineTo(x, y) добавляет прямой отрезок от текущей точки к новой — но ничего ещё не отрисовывается. Только stroke() фактически отображает путь, используя текущий strokeStyle (цвет контура). Когда вы рисуете несколько отдельных путей, начинайте каждый с beginPath(); иначе новые отрезки добавляются к предыдущему пути. Используйте fill()fillStyle) вместо stroke(), когда хотите залить путь, а не обвести контуром.

<!DOCTYPE html>
<html>
  <body>
    <canvas width="300" height="150" style="border:1px solid #cccccc;" id="canvasExample">
      Your browser does not support the HTML5 canvas tag.
    </canvas>
    <script>
      const c = document.getElementById("canvasExample");
      const ctx = c.getContext("2d");
      ctx.beginPath();
      ctx.moveTo(0, 0);
      ctx.lineTo(300, 150);
      ctx.strokeStyle = '#1c87c9';
      ctx.stroke();
    </script>
  </body>
</html>

Типичные варианты использования

Помимо простых фигур, 2D-контекст позволяет создавать богатую графику:

  • Анимация — очищайте холст и перерисовывайте его внутри цикла requestAnimationFrame() для плавного покадрового движения.
  • Изображенияctx.drawImage(img, x, y) рисует <img>, другой canvas или кадр видео, что является основой фоторедакторов и фильтров.
  • ГрадиентыcreateLinearGradient() и createRadialGradient() создают градиентные заливки и обводки.
  • Игры и визуализация данных — canvas является предпочтительным выбором, когда нужно перерисовывать много объектов на каждом кадре; именно поэтому библиотеки для графиков и игр строятся на его основе.

Всё это требует JavaScript, поэтому хорошее понимание HTML DOM поможет максимально эффективно использовать canvas.

Доступность

Вывод canvas — это просто пиксели: программы чтения с экрана и другие вспомогательные технологии не могут «увидеть» нарисованное. Чтобы сделать содержимое canvas доступным:

  • Предоставьте осмысленное резервное содержимое между тегами. Всё, что находится внутри <canvas>...</canvas>, отображается в браузерах без поддержки canvas и передаётся вспомогательным технологиям, поэтому опишите рисунок вместо общего сообщения «не поддерживается».
  • Для статического рисунка добавьте role="img" и aria-label (или aria-labelledby) с его описанием, например: <canvas role="img" aria-label="Bar chart of 2024 sales">.
  • Для интерактивных canvas-элементов дублируйте элементы управления и состояние в реальных DOM-элементах (кнопки, live-регионы), поскольку нарисованные фигуры сами по себе не получают фокус и недоступны для чтения.

Атрибуты

АтрибутЗначениеОписание
heightпикселиЗадаёт высоту элемента в пикселях.
widthпикселиЗадаёт ширину элемента в пикселях.

Тег <canvas> поддерживает глобальные атрибуты и атрибуты событий.

Практика

Практика
Какой метод возвращает объект, у которого вызываются команды рисования, такие как fillRect() и stroke()?
Какой метод возвращает объект, у которого вызываются команды рисования, такие как fillRect() и stroke()?
Практика
Вы рисуете в canvas размером 300x150, но задаёте его размер 600px через CSS. Что произойдёт?
Вы рисуете в canvas размером 300x150, но задаёте его размер 600px через CSS. Что произойдёт?
Was this page helpful?