[Перевод] SVG или canvas?
Поэтому их стоит сравнить и разобраться в том, когда стоит применять SVG, а когда — canvas. SVG и canvas — это технологии, которые можно использовать для рисования чего-либо на веб-страницах. Собственно говоря, вот — две типичных ситуации, в одной из которых стоит предпочесть SVG, а в другой — canvas: Даже весьма поверхностное понимание сути этих технологий позволяет сделать вполне осознанный выбор.
- Нужно нарисовать небольшую иконку? Это, безусловно, территория SVG.
- Нужно создать интерактивную браузерную игру? Тут, определённо, нужна технология canvas.
Автор статьи, перевод которой мы сегодня публикуем, говорит, что знает о том, что пока не раскрыл причины такого выбора. Но он надеется, что эти причины станут совершенно очевидными после того, как он поделится некоторыми подробностями об SVG и canvas.
SVG — векторная графика, описываемая декларативно
Если вы знаете о том, что вам нужно разместить на веб-странице векторное изображение, это значит, что вам подходит SVG. Векторные изображения обычно выглядят лучше аналогичных растровых, хранящихся, например, в JPG-файлах. Кроме того, файлы векторных изображений обычно меньше файлов растровых изображений.
Код, описывающий такие изображения, можно встроить прямо в HTML. В результате оказывается, что SVG очень часто используется для рисования логотипов. Он выглядит как набор декларативных инструкций:
<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 => ); </script> </svg>
SVG лучше подходит для обеспечения доступности содержимого страниц
Элементу canvas вполне можно назначит его текстовую альтернативу:
<canvas aria-label="Hello ARIA World" role="img"></canvas>
То же самое можно сделать и для SVG-элемента. Но, так как SVG-изображения и их внутренние механизмы хранятся прямо в DOM, SVG обычно рассматривают как технологию, используемую в тех случаях, когда создают проекты, отличающиеся доступностью для людей с ограниченными возможностями.
Другими словами — можно создать SVG-изображение, с элементами которого смогут работать ассистивные технологии, помогающие своим пользователям ориентироваться на веб-страницах.
В SVG даже имеется специальный элемент — <text>
. Текстовые данные, являющиеся частью изображений, это тоже тот случай, когда предпочтительнее использовать SVG. В случае же использования для визуализации текстов элемента canvas, такие тексты нередко выводятся некачественно, выглядят размытыми. Он позволяет выводить чёткие символы текстов, его воспринимают ассистивные технологии.
Canvas лучше подходит для работы с изображениями на уровне отдельных пикселей
Ниже мы приведём несколько таблиц, составленных на основе сравнения SVG и canvas различными экспертами. В одном из таких сравнений, выполненном Сарой Драснер, сказано, что с помощью canvas можно заставить пиксели танцевать. Это, конечно, шутка, но, в сущности, так оно и есть.
Именно по этой причине canvas используется при разработке гораздо большего количества браузерных игр, чем SVG. Canvas отлично подходит для создания интерактивных изображений, содержащих множество сложных деталей, градиентных переходов цветов и прочего подобного. Вот, например, игра, графика которой создана средствами SVG. Хотя, конечно, всегда можно найти отклонения от общих тенденций.
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-элемент с помощью внешних стилей и скриптов.
Самое важное здесь это то, что всё, что можно делать с элементами страниц средствами CSS, относится и к SVG. Вот большой материал о свойствах SVG-элементов и CSS. Например — это использование псевдокласса :hover
и анимирование элементов.
Вот пример анимирования элемента <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-изображения средствами CSS
Комбинация SVG и canvas
С технической точки зрения технологии canvas и SVG нельзя назвать взаимоисключающими. Например, SVG-изображения можно выводить в элементы <canvas>
. При этом, как можно видеть в данном примере, SVG-изображения, выводимые в элемент <canvas>
, вполне могут оставаться весьма чёткими и качественными.
Вывод SVG-изображения в элемент <canvas>
Теперь давайте рассмотрим несколько таблиц, в которых обобщены сравнения SVG и canvas, выполненные различными экспертами.
Сравнение SVG и canvas
▍Рут Джон
Вот проект, на основе которого построена следующая таблица.
▍Сара Драснер
Следующая таблица составлена на основе этого твита.
▍Ширли Ву
В основу следующей таблицы положен этот твит.
Многие считают, что для работы с большим количеством объектов (по словам Ширли — это когда их больше 1000) лучше подходит canvas.
SVG — это стандартный выбор. Canvas — это запасной вариант
Вот ответ на мой твит по поводу вариантов использования SVG и canvas. Автор этого ответа говорит, что выбор между SVG и canvas нужно делать так: «Используйте canvas тогда, когда не можете использовать SVG». Среди ситуаций, в которых не получается нормально пользоваться SVG, можно отметить такие, в которых нужно анимировать тысячи объектов, работать с каждым конкретным пикселем изображения, и так далее.
Итоги
В начале этого материала мы привели два типичных варианта использования SVG и canvas. Вернёмся к ним и расширим их описания с учётом того, что мы только что узнали.
- Нужно нарисовать небольшую иконку? Это, безусловно, территория SVG. Дело в том, что описание SVG-изображения хранится в DOM, в результате SVG отлично подходит для того, чтобы нарисовать что-то вроде значка на кнопке. Не стоит и говорить о том, что на SVG-изображения можно влиять средствами CSS, и, с помощью JavaScript, подключать к их элементам обработчики событий.
- Нужно создать интерактивную браузерную игру? Тут, определённо, нужна технология canvas. Браузерная игра, наверняка, будет содержать множество движущихся элементов и сложных анимаций. Элементы игрового мира будут взаимодействовать друг с другом, что означает определённые требования к производительности. Для решения таких задач отлично подходит canvas.
Надо отметить, что между этими двумя крайними вариантами есть большая промежуточная зона. Я, например, как веб-разработчик и дизайнер, считаю, что SVG удобнее с практической точки зрения. Я даже не знаю, стал бы я делать некий реальный проект с использованием canvas. Пожалуй, отчасти это так из-за того, что я недостаточно хорошо знаком с canvas. А с SVG я знаком неплохо. Я эту технологию изучал, написал о ней книгу. Как результат — я знаю об SVG достаточно для того, чтобы эта технология помогала бы мне делать то, что мне нужно.
Уважаемые читатели! В каких ситуациях вы используете SVG, а в каких — canvas?