Rysowanie pliku SVG na kanwie HTML5

131

Czy istnieje domyślny sposób rysowania pliku SVG na kanwie HTML5? Google Chrome obsługuje ładowanie SVG jako obrazu (i po prostu używanie drawImage), ale konsola programisty ostrzega o tym resource interpreted as image but transferred with MIME type image/svg+xml.

Wiem, że istnieje możliwość przekonwertowania SVG do poleceń kanwy (jak w tym pytaniu ), ale mam nadzieję, że nie jest to potrzebne. Nie obchodzą mnie starsze przeglądarki (więc jeśli FireFox 4 i IE 9 będą coś obsługiwać, to wystarczy).

Randy Voet
źródło
4
Na to pytanie można znaleźć odpowiedź dzięki stackoverflow.com/questions/5495952/ ...
Drew LeSueur

Odpowiedzi:

122

EDYCJA 16 grudnia 2019 r

Path2D jest obsługiwana przez wszystkich głównych przeglądarek teraz

EDYCJA 5 listopada 2014

Możesz teraz używać ctx.drawImagedo rysowania HTMLImageElements, które mają źródło .svg w niektórych, ale nie we wszystkich przeglądarkach . Chrome, IE11 i Safari działają, Firefox działa z niektórymi błędami (ale co noc je naprawił).

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";

Przykład na żywo tutaj . Na płótnie powinien być widoczny zielony kwadrat. Drugi zielony kwadrat na stronie to ten sam <svg>element wstawiony do DOM w celach informacyjnych.

Możesz także użyć nowych obiektów Path2D do rysowania ścieżek SVG (ciągów znaków). Innymi słowy, możesz napisać:

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

Żywy przykład tego tutaj.


Odpowiedź starej potomności:

Nie ma nic natywnego, co pozwala na natywne używanie ścieżek SVG w kanwie. Musisz się przekonwertować lub skorzystać z biblioteki, aby zrobić to za Ciebie.

Proponuję zajrzeć do canvg:

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

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

Simon Sarris
źródło
4
Dlaczego jest to potrzebne? Wydaje się, że SVG doskonale rysuje się na płótnie z samym plikiem drawImage. Ale nadal otrzymuję to ostrzeżenie. Skąd to pochodzi?
shoosh,
1
Simon, to, co mówisz, nie jest poprawne. Po drugie, jest to potwierdzony błąd w Chrome.
Mathias Lykkegaard Lorenzen
4
Wygląda na to, że Wikimedia nie lubi, gdy używasz SVG. I zamienili w snapsvg.io/assets/images/logo.svg jak znaleźć pierwszą dostępny SVG ja. Pracował w FF. jsfiddle.net/Na6X5/331
Thomas
1
Możesz również użyć identyfikatorów URI danych, aby to zrobić: jsfiddle.net/020k543w
Swivel
9
Uwaga: z powodu długotrwałego błędu FireFox, niestety pliki SVG bez znaczników szerokości i wysokości w ogóle nie będą renderowane na płótnie. Ponadto szerokość i wysokość nie mogą być wyrażone w procentach.
Hatoru Hansou
26

Przepraszamy, nie mam wystarczającej reputacji, aby komentować odpowiedź @Matyas, ale jeśli obraz svg jest również w base64, zostanie narysowany na wyjściu.

Próbny:

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/>

Henrique Campos
źródło
1
To samo z czcionkami, muszą być osadzone w SVG: jsfiddle.net/ykx7kp8L/121
Sphinxxx
1
możesz przejść przez imgtagi w programie svg, a potem po prostu narysować osobno obrazy na płótnie.
luckydonald
24

Możesz łatwo narysować proste svgobrazy na płótnie:

  1. Przypisywanie źródła svg do obrazu w formacie base64
  2. Rysowanie obrazu na płótnie

Uwaga: jedyną wadą tej metody jest to, że nie może ona rysować obrazów osadzonych wsvg . (zobacz demo)

Demonstracja:

(Zwróć uwagę, że osadzony obraz jest widoczny tylko w 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/>

Matyas
źródło
2
Czy istnieje sposób rozwiązania wspomnianego problemu? Obraz osadzony w svg.
Vijay Baskaran
Przepraszamy, ale nie znalazłem rozwiązania problemu z osadzonym obrazem.
Matyas
W porządku. Dzięki Matyas :)
Vijay Baskaran
6

Mozilla oferuje prosty sposób rysowania SVG na płótnie o nazwie „ Rysowanie obiektów DOM na płótnie

Nati Krisi
źródło
Ma to tę samą wadę, co w pierwszej metodzie @ Simona: nie działa w przeglądarce Firefox, Chrome OK.
amergin
3
Twój link już nie działa. Nadal interesuje mnie sposób Mozilli
Alirezak
6

Jak mówi Simon powyżej, użycie drawImage nie powinno działać. Ale używając biblioteki canvg i:

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

Wynika to z linku, który Simon podał powyżej, który zawiera szereg innych sugestii i wskazuje, że chcesz utworzyć łącze lub pobrać pliki canvg.js i rgbcolor.js. Umożliwiają one manipulowanie i ładowanie pliku SVG za pomocą adresu URL lub za pomocą wbudowanego kodu SVG między tagami svg w ramach funkcji JavaScript.

Max West
źródło