Года два назад в интернете начали появляться статьи, в которых сравнивали SVG и Canvas. В итоге сейчас не составляет особого труда найти сайт, на котором популярно объясняются плюсы и минусы использования SVG-изображений или отрисовки напрямую в Canvas.
Здесь я хотел обозначить совсем другую задачу – отобразить картинку в SVG-формате с помощью API Canvas-a. Другими словами, тема статьи не “SVG против Canvas”, а как рисовать SVG картинки внутри Canvas. Подобного рода задача возникнет, например, в случае, если у вас уже есть небольшой набор не слишком сложных SVG-файлов, и вы хотели бы их использовать, при этом ваш графический javascript-овый движок базируется на Canvas-e.
Можно выделить два основных похода:
1. Первый подход.
Парсить SVG файл JavaScript-ом и руками рисовать его в канву.
Один из самых популярных движков, которые реализуют подобный функционал это: http://code.google.com/p/canvg/
2. Второй подход.
На самом деле, многие браузеры умеют рисовать SVG файлы непосредственно в канву методом drawImage. Точно также как обычные растровые изображения (PNG, JPG и т.д.) – https://developer.mozilla.org/en-US/docs/Canvas_tutorial/Using_images.
Проблемы заключаются как всегда в том, что разные браузеры могут делать это по-разному.
В итоге пришлось провести небольшую работу для проверки отображение SVG внутри Canvas-a для различных браузеров. На момент публикации этой статьи получилась следующая картинка:
Попробуем запустить следующий пример:
<!DOCTYPE html> <html> <head> <title>svg on canvas</title> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> </head> <body> <canvas id='example' width='150' height='100'></canvas> <script> var canvas = document.getElementById("example"); var context = canvas.getContext("2d"); context.fillRect(10, 10, canvas.width - 20, canvas.height - 20); var image = new Image(); image.src = "./star.svg"; image.onload = function() { context.drawImage(image, 43, 18); }; context.drawImage(image, 43, 18); </script> </body> </html>
SVG-изображение: star.svg
В итоге получим следующую картинку:
Chrome, Safari, IE 9
Firefox
В Firefox мой пример отрисовался, но с некоторыми более сложными SVG-изображениями не справился.
Opera 12.02
Наиболее забавная ситуация обстоит с браузером Opera.
Многие поисковые системы показывают большое количество ссылок на сайты, которые содержат в себе фразу:
“В браузере Opera можно также рисовать изображения SVG внутри холста. Это достаточно сложный метод… и т.д.”
На самом деле, для текущей версии Opera это не совсем верно (версия 12.02, OS Windows 7) !
Opera не всегда может рисовать SVG изображения внутри Canvas (код описания ошибки: CORE-26856)
В августе 2012 выпущен тестовый релиз с множеством исправлений.
Скачать его можно здесь: http://my.opera.com/desktopteam/blog/2012/08/03/summer-core-update
Если запускать в нём, то рисунок покажется:
Кроме отрисовки в Opera есть проблема, связанная с тем, что для SVG изображений не срабатывает событие onload.
var img = new Image(); img.onload = function() { alert('onload'); } img.src = "a.svg";
Напоследок хотелось сказать самое главное – соблюдайте осторожность при работе с SVG-картинами!
На протяжении нескольких последних лет в браузерах находят различные уязвимости в безопасности, связанные как раз с отображением SVG внутри браузера. Конечно, многие браузеры с целью безопасности накладывают ограничения на работу с SVG, тем не менее не стоит полностью полагаться на них, поэтому желательно на этапе проектирования архитектуры учитывать различные аспекты, связанные с безопасной работой с SVG-изображениями.