Малювання файлу SVG на полотні HTML5


131

Чи існує спосіб за замовчуванням намалювати файл SVG на полотні HTML5? Google Chrome підтримує завантаження SVG як зображення (та просто використання drawImage), але консоль розробника попереджає про це resource interpreted as image but transferred with MIME type image/svg+xml.

Я знаю, що можливо було б перетворити SVG в канви (наприклад, у цьому питанні ), але я сподіваюся, що це не потрібно. Мені не байдуже старі браузери (тому якщо FireFox 4 та IE 9 щось підтримають, це досить добре).


4
Це питання має відповідь з живим демо stackoverflow.com/questions/5495952 / ...
Дрю Лесуеер

Відповіді:


122

EDIT 16 грудня 2019 року

Path2D підтримується всіма основними браузерами в даний час

EDIT 5 листопада 2014 року

Тепер ви можете використовувати ctx.drawImageдля малювання HTMLImageElements, які мають джерело .svg у деяких браузерах, але не у всіх . Chrome, IE11 і Safari працюють, Firefox працює з деякими помилками (але вночі їх виправляє).

var img = new Image();
img.onload = function() {
    ctx.drawImage(img, 0, 0);
}
img.src = "http://upload.wikimedia.org/wikipedia/commons/d/d2/Svg_example_square.svg";

Живий приклад тут . Ви повинні побачити зелений квадрат на полотні. Другий зелений квадрат на сторінці - це той самий <svg>елемент, який вставлений у DOM для довідки.

Ви також можете використовувати нові об'єкти Path2D, щоб намалювати SVG (рядкові) контури. Іншими словами, ви можете написати:

var path = new Path2D('M 100,100 h 50 v 50 h 50');
ctx.stroke(path);

Живий приклад цього тут.


Стара відповідь нащадків:

Немає нічого рідного, що дозволяє вам на самому світі використовувати шляхи SVG на полотні. Ви повинні перетворити себе або використовувати бібліотеку, щоб зробити це за вас.

Я б запропонував заглянути в canvg:

http://code.google.com/p/canvg/

http://canvg.googlecode.com/svn/trunk/examples/index.htm


4
Для чого це потрібно? SVG, здається, ідеально малює на полотні просто drawImage. Але я все одно отримую це попередження. Звідки воно походить?
shoosh

1
Саймоне, те, що ти кажеш, не вірно. А по-друге, це підтверджена помилка в Chrome.
Mathias Lykkegaard Lorenzen

4
Вікімедіа вам не подобається використовувати SVG, здається. Я обмінявся на snapsvg.io/assets/images/logo.svg як перший доступний SVG, який я знайшов. Працював у ФФ. jsfiddle.net/Na6X5/331
Томас

1
Ви можете також використовувати дані адреси URI для того , щоб зробити це: jsfiddle.net/020k543w
шарнірний

9
Примітка: через давній помилка FireFox, на жаль, SVG, у яких відсутні теги ширини та висоти, взагалі не відображатиметься на полотні. Також ширина і висота не повинні бути у відсотках.
Hatoru Hansou

26

Вибачте, мені не вистачає репутації, щоб коментувати відповідь @Matyas, але якщо зображення svg також знаходиться в base64, воно буде залучено до виводу.

Демонстрація:

var svg = document.querySelector('svg');
var img = document.querySelector('img');
var canvas = document.querySelector('canvas');

// get svg data
var xml = new XMLSerializer().serializeToString(svg);

// make it base64
var svg64 = btoa(xml);
var b64Start = 'data:image/svg+xml;base64,';

// prepend a "header"
var image64 = b64Start + svg64;

// set it as the source of the img element
img.onload = function() {
    // draw the image onto the canvas
    canvas.getContext('2d').drawImage(img, 0, 0);
}
img.src = image64;
svg, img, canvas {
  display: block;
}
SVG

<svg height="40">
  <rect width="40" height="40" style="fill:rgb(255,0,255);" />
  <image xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAEX0lEQVQ4jUWUyW6cVRCFv7r3/kO3u912nNgZgESAAgGBCJgFgxhW7FkgxAbxMLwBEmIRITbsQAgxCEUiSIBAYIY4g1EmYjuDp457+Lv7n+4tFjbwAHVOnVPnlLz75ht67OhhZg/M0p6d5tD9C8SNBBs5XBJhI4uNLC4SREA0UI9yJr2c4e6QO+v3WF27w+rmNrv9Pm7hxDyHFg5yYGEOYxytuRY2SYiSCIwgRgBQIxgjEAKuZWg6R9S0SCS4qKLZElY3HC5tp7QPtmlMN7HOETUTXBJjrEGsAfgPFECsQbBIbDGJZUYgGE8ugQyPm+o0STtTuGZMnKZEjRjjLIgAirEOEQEBDQFBEFFEBWLFtVJmpENRl6hUuFanTRAlbTeZarcx0R6YNZagAdD/t5N9+QgCYAw2jrAhpjM3zaSY4OJGTDrVwEYOYw2qioigoviq5MqF31m9fg1V5fCx+zn11CLNVnufRhBrsVFE1Ihpthu4KDYYwz5YQIxFBG7duMZnH31IqHL6wwnGCLFd4pez3/DaG2/x4GNPgBhEZG/GGlxkMVFkiNMYay3Inqxed4eP33uf7Y0uu90xWkGolFAru7sZn5w5w921m3u+su8vinEO02hEWLN/ANnL2rkvv2an2yd4SCKLM0JVBsCgAYZZzrnPP0eDRzXgfaCuPHXwuEYjRgmIBlQVVLl8/hKI4fRzz3L6uWe5+PMvnHz6aa4uX+D4yYe5vXaLH86eoyoLjLF476l9oKo9pi5HWONRX8E+YznOef7Vl1h86QWurlwjbc+QpikPPfoIcZLS39pmMikp8pzae6q6oqgriqrGqS+xeLScoMYSVJlfOMTl5RXW1+5w5fJVnFGWf1/mxEMnWPppiclkTLM5RdJoUBYFZVlQ5DnZMMMV167gixKLoXXsKGqnOHnqOJ/+/CfZ+XUiZ0jTmFv5mAvf/YjEliQ2vPD8Ir6qqEcZkzt38cMRo5WruFvfL9FqpyRxQhj0qLOax5I2S08+Tu/lFiGUGOPormxwuyfMnjrGrJa88uIixeYWl776lmrzNjmw8vcG8sU7ixpHMXFsCUVg9tABjEvRgzP82j7AhbyiX5Qcv2+Bvy7dYGZ1k7efeQB/Y4PBqGBtdYvb3SFzLcfqToZc/OB1zYeBSpUwLBlvjZidmWaSB1yaYOfn6LqI/r0hyU6P+cRSlhXjbEI2zvnt7y79oqQ3qeg4g6vKjCIXehtDmi6m0UnxVnCRkPUHVNt9qkLJxgXOCYNOg34v48raPaamU2o89/KKsQ9sTSpc0JK7NwdcX8s43Ek5cnSOLC/Z2R6Rj0ra0w2W1/t0xyWn51uk2Ri1QtSO6OU5d7OSi72cQeWxKG7p/Dp//JXTy6C1Pcbc6DMpPRtjTxChEznWhwVZUCKrjCrPoPDczHLmnLBdBgZlRRWUEBR3ZKrme5TlrTGlV440Y1IrXM9qQGi6mkG5V6uza7tUIeCDElTZ1L26elX+fcH/ACJBPYTJ4X8tAAAAAElFTkSuQmCC" height="20px" width="20px" x="10" y="10"></image>
</svg>
<hr/><br/>

IMAGE
<img/>
<hr/><br/>
   
CANVAS
<canvas></canvas>
<hr/><br/>


1
Те саме стосується шрифтів, їх потрібно вбудовувати у SVG: jsfiddle.net/ykx7kp8L/121
Sphinxxx

1
ви можете переглядати imgтеги на теці svgта просто малювати зображення на полотні окремо після цього.
luckydonald

24

Ви можете легко намалювати прості svgs на полотні, виконавши:

  1. Призначення джерела svg зображенню у форматі base64
  2. Нанесення зображення на полотно

Примітка . Єдиним недоліком методу є те, що він не може малювати зображення, вбудовані в svg. (див. демонстрацію)

Демонстрація:

(Зверніть увагу, що вбудоване зображення бачиться лише на зображенні svg)

var svg = document.querySelector('svg');
var img = document.querySelector('img');
var canvas = document.querySelector('canvas');

// get svg data
var xml = new XMLSerializer().serializeToString(svg);

// make it base64
var svg64 = btoa(xml);
var b64Start = 'data:image/svg+xml;base64,';

// prepend a "header"
var image64 = b64Start + svg64;

// set it as the source of the img element
img.src = image64;

// draw the image onto the canvas
canvas.getContext('2d').drawImage(img, 0, 0);
svg, img, canvas {
  display: block;
}
SVG

<svg height="40">
  <rect width="40" height="40" style="fill:rgb(255,0,255);" />
  <image xlink:href="https://en.gravatar.com/userimage/16084558/1a38852cf33713b48da096c8dc72c338.png?size=20" height="20px" width="20px" x="10" y="10"></image>
</svg>
<hr/><br/>

IMAGE
<img/>
<hr/><br/>
   
CANVAS
<canvas></canvas>
<hr/><br/>


2
Чи є спосіб виправити проблему, про яку ви згадали. Зображення, вбудоване у svg.
Віджай Баскаран

Вибачте, але я не знайшов рішення проблеми із вбудованим зображенням.
Матяс

Добре. Дякую Матьясу ​​:)
Vijay Baskaran


6

Як Саймон каже вище, використання drawImage не повинно працювати. Але, використовуючи бібліотеку canvg і:

var c = document.getElementById('canvas');
var ctx = c.getContext('2d');
ctx.drawSvg(SVG_XML_OR_PATH_TO_SVG, dx, dy, dw, dh);

Це відбувається за посиланням, яке надає Саймон вище, яке містить низку інших пропозицій і вказує на те, що ви хочете або перейти на посилання, або завантажити canvg.js і rgbcolor.js. Вони дозволяють маніпулювати та завантажувати SVG, або через URL, або за допомогою вбудованого коду SVG між тегами svg, у межах функцій JavaScript.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.