- PVSM.RU - https://www.pvsm.ru -

SVG или canvas?

SVG или canvas? - 1 [1]

SVG и canvas — это технологии, которые можно использовать для рисования чего-либо на веб-страницах. Поэтому их стоит сравнить и разобраться в том, когда стоит применять SVG, а когда — canvas. Даже весьма поверхностное понимание сути этих технологий позволяет сделать вполне осознанный выбор. Собственно говоря, вот — две типичных ситуации, в одной из которых стоит предпочесть SVG, а в другой — canvas:

  • Нужно нарисовать небольшую иконку? Это, безусловно, территория SVG.
  • Нужно создать интерактивную браузерную игру? Тут, определённо, нужна технология canvas.

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

SVG — векторная графика, описываемая декларативно

Если вы знаете о том, что вам нужно разместить на веб-странице векторное изображение, это значит, что вам подходит SVG. Векторные изображения обычно выглядят лучше аналогичных растровых, хранящихся, например, в JPG-файлах. Кроме того, файлы векторных изображений обычно меньше файлов растровых изображений.

В результате оказывается, что SVG очень часто используется для рисования логотипов [2]. Код, описывающий такие изображения, можно встроить прямо в HTML. Он выглядит как набор декларативных инструкций:

<svg viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="50" />
</svg>

Если вам нужно, чтобы изображения были бы гибкими и отзывчивыми, значит SVG — это ваш выбор.

Canvas — JavaScript-API для рисования

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

<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
  var canvas = document.getElementById('myCanvas');
  var context = canvas.getContext('2d');
  var centerX = canvas.width / 2;
  var centerY = canvas.height / 2;
  var radius = 70;

  context.beginPath();
  context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
  context.fillStyle = 'green';
  context.fill();
</script>

SVG-изображения хранятся в DOM

Если вы знакомы с событиями DOM, наподобие click и mouseDown, то знайте о том, что этими событиями можно пользоваться и при работе с SVG. В этом плане SVG-элемент <circle> не особенно сильно отличается от HTML-элемента <div>.

<svg viewBox="0 0 100 100">
  
  <circle cx="50" cy="50" r="50" />
  
  <script>
    document.querySelector('circle').addEventListener('click', e => {
      e.target.style.fill = "red";
    });
  </script>
  
</svg>

SVG лучше подходит для обеспечения доступности содержимого страниц

Элементу canvas вполне можно назначит его текстовую альтернативу:

<canvas aria-label="Hello ARIA World" role="img"></canvas>

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

Другими словами — можно создать SVG-изображение, с элементами которого смогут работать ассистивные технологии, помогающие своим пользователям ориентироваться на веб-страницах.

Текстовые данные, являющиеся частью изображений, это тоже тот случай, когда предпочтительнее использовать SVG. В SVG даже имеется специальный элемент — <text>. Он позволяет выводить чёткие символы текстов, его воспринимают ассистивные технологии [3]. В случае же использования для визуализации текстов элемента canvas, такие тексты нередко выводятся некачественно [4], выглядят размытыми.

Canvas лучше подходит для работы с изображениями на уровне отдельных пикселей

Ниже мы приведём несколько таблиц, составленных на основе сравнения SVG и canvas различными экспертами. В одном из таких сравнений, выполненном Сарой Драснер, сказано, что с помощью canvas можно заставить пиксели танцевать. Это, конечно, шутка, но, в сущности, так оно и есть.

Canvas отлично подходит для создания интерактивных изображений, содержащих множество сложных деталей, градиентных переходов цветов и прочего подобного. Именно по этой причине canvas используется при разработке гораздо большего количества браузерных игр, чем SVG. Хотя, конечно, всегда можно найти отклонения от общих тенденций. Вот [5], например, игра, графика которой создана средствами SVG.

SVG или canvas? - 2

SVG-игра

Обратите внимание на то, что её графическая составляющая очень проста и выглядит достаточно «векторно».

На SVG-изображения можно воздействовать с помощью CSS

Выше мы уже говорили о том, что SVG-элементы хранятся в DOM, и о том, что доступ к этим элементам можно получить из JavaScript-кода. В случае с CSS эта история повторяется:

<svg viewBox="0 0 100 100">
  
  <circle cx="50" cy="50" r="50" />
  
  <style>
    circle { fill: blue; }
  </style>
  
</svg>

Обратите внимание на то, что в примерах блоки <script> и <style> размещаются внутри блока <svg>. Это — совершенно нормально. Но если учесть то, что SVG-элемент находится в обычном HTML-коде, то окажется, что внутренние блоки <script> и <style> вполне можно из него убрать. Кроме того, если нужно, можно воздействовать на SVG-элемент с помощью внешних стилей и скриптов.

Вот [6] большой материал о свойствах SVG-элементов и CSS. Самое важное здесь это то, что всё, что можно делать с элементами страниц средствами CSS, относится и к SVG. Например — это использование псевдокласса :hover и анимирование элементов.

Вот [7] пример анимирования элемента <circle> средствами CSS.

<svg viewBox="0 0 100 100">
  
  <circle cx="50" cy="50" r="50" />
  
  <style>
    circle { fill: blue; animation: pulse 2s alternate infinite; }
    @keyframes pulse {
      100% {
        r: 30;
      }
    }
  </style>
  
  <script>
    document.querySelector('circle').addEventListener('click', e => {
      e.target.style.fill = "red";
    });
  </script>
  
</svg>

SVG или canvas? - 3

Анимирование элемента SVG-изображения средствами CSS

Комбинация SVG и canvas

С технической точки зрения технологии canvas и SVG нельзя назвать взаимоисключающими. Например, SVG-изображения можно выводить в элементы <canvas>. При этом, как можно видеть в данном [8] примере, SVG-изображения, выводимые в элемент <canvas>, вполне могут оставаться весьма чёткими и качественными.

SVG или canvas? - 4

Вывод SVG-изображения в элемент <canvas>

Теперь давайте рассмотрим несколько таблиц, в которых обобщены сравнения SVG и canvas, выполненные различными экспертами.

Сравнение SVG и canvas

▍Рут Джон

Вот [9] проект, на основе которого построена следующая таблица.

Возможность SVG Canvas
Векторная графика +
Растровая графика +
Доступ в DOM +
Доступность + ±
Вывод текста + +
Вывод градиентов и паттернов + +
Поддержка CSS-анимации +
Поддержка CSS-фильтров + +
Поддержка SVG-фильтров + +
Поддержка вывода файлов изображений и видеофайлов +
Экспорт содержимого элемента +
Управление отдельными пикселями +
Доступ из JavaScript +
Производительность анимации ± +
Поддержка вычислений, выполняемых за пределами главного потока +

▍Сара Драснер

Следующая таблица составлена на основе этого [10] твита.

DOM/Virtual DOM Canvas
Преимущества Отлично подходит для UI/UX-анимации. Танцуйте, пиксели!
Отлично подходит для вывода SVG-изображений, независимых от разрешения. Отлично подходит для вывода 3D-графики и для других подобных вариантов использования.
Легко отлаживать. Удобно управлять множеством движущихся объектов.
Недостатки Изображения создаются из множества отдельных объектов. Сложнее обеспечить доступность содержимого.
В свете предыдущего минуса оказывается, что при анимации SVG-изображений нужно проявлять осторожность. В стандартном виде canvas-изображения зависимы от разрешения.
Сложно организовать взаимодействие пользователя с отдельными элементами изображения.

▍Ширли Ву

В основу следующей таблицы положен этот [11] твит.

SVG Canvas
Преимущества Легче изучить. Очень высокая производительность.
Легче организовать реакцию на воздействия пользователя. Легче обновлять.
Легче анимировать.
Недостатки Возможна необходимость в использовании сложных DOM-структур. Сложнее изучить.
Низкая производительность при работе с большим количеством элементов. Сложнее обрабатывать воздействия пользователя.
Для анимации объектов нужно писать собственный код.

Многие считают, что для работы с большим количеством объектов (по словам Ширли — это когда их больше 1000) лучше подходит canvas.

SVG — это стандартный выбор. Canvas — это запасной вариант

Вот [12] ответ на мой твит по поводу вариантов использования SVG и canvas. Автор этого ответа говорит, что выбор между SVG и canvas нужно делать так: «Используйте canvas тогда, когда не можете использовать SVG». Среди ситуаций, в которых не получается нормально пользоваться SVG, можно отметить такие, в которых нужно анимировать тысячи объектов, работать с каждым конкретным пикселем изображения, и так далее.

Итоги

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

  • Нужно нарисовать небольшую иконку? Это, безусловно, территория SVG. Дело в том, что описание SVG-изображения хранится в DOM, в результате SVG отлично подходит для того, чтобы нарисовать что-то вроде значка на кнопке. Не стоит и говорить о том, что на SVG-изображения можно влиять средствами CSS, и, с помощью JavaScript, подключать к их элементам обработчики событий.
  • Нужно создать интерактивную браузерную игру? Тут, определённо, нужна технология canvas. Браузерная игра, наверняка, будет содержать множество движущихся элементов и сложных анимаций. Элементы игрового мира будут взаимодействовать друг с другом, что означает определённые требования к производительности. Для решения таких задач отлично подходит canvas.

Надо отметить, что между этими двумя крайними вариантами есть большая промежуточная зона. Я, например, как веб-разработчик и дизайнер, считаю, что SVG удобнее с практической точки зрения. Я даже не знаю, стал бы я делать некий реальный проект с использованием canvas. Пожалуй, отчасти это так из-за того, что я недостаточно хорошо знаком с canvas. А с SVG я знаком неплохо. Я эту технологию изучал, написал о ней книгу [13]. Как результат — я знаю об SVG достаточно для того, чтобы эта технология помогала бы мне делать то, что мне нужно.

Уважаемые читатели! В каких ситуациях вы используете SVG, а в каких — canvas?

SVG или canvas? - 5


SVG или canvas? - 6 [14]

Автор: ru_vds

Источник [15]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/razrabotka/337180

Ссылки в тексте:

[1] Image: https://habr.com/ru/company/ruvds/blog/476292/

[2] логотипов: http://responsivelogos.co.uk/

[3] ассистивные технологии: https://css-tricks.com/svg-text-typographic-designs/

[4] некачественно: https://twitter.com/_hmig/status/1179540290941718534

[5] Вот: https://play.esviji.com/

[6] Вот: https://css-tricks.com/svg-properties-and-css/

[7] Вот: https://codepen.io/chriscoyier/pen/ExxbpBE

[8] данном: https://codepen.io/osublake/pen/WzbKLQ

[9] Вот: https://codepen.io/Rumyra/pen/qBBWryJ

[10] этого: https://twitter.com/sarah_edo/status/1179542296653631488

[11] этот: https://twitter.com/sxywu/status/1179517055093104641

[12] Вот: https://twitter.com/bdc/status/1179509488803434496

[13] книгу: https://abookapart.com/products/practical-svg

[14] Image: https://ruvds.com/ru-rub/#order

[15] Источник: https://habr.com/ru/post/476292/?utm_source=habrahabr&utm_medium=rss&utm_campaign=476292