ChatGPT解决这个技术问题 Extra ChatGPT

Drawing an SVG file on a HTML5 canvas

Is there a default way of drawing an SVG file onto a HTML5 canvas? Google Chrome supports loading the SVG as an image (and simply using drawImage), but the developer console does warn that resource interpreted as image but transferred with MIME type image/svg+xml.

I know that a possibility would be to convert the SVG to canvas commands (like in this question), but I'm hoping that's not needed. I don't care about older browsers (so if FireFox 4 and IE 9 will support something, that's good enough).

This question has the answer with a live demo stackoverflow.com/questions/5495952/…

a
ashleedawg

EDIT: Dec 2019

The Path2D() constructor is supported by all major browsers now, "allowing path objects to be declared on 2D canvas surfaces".

EDIT: Nov 2014

You can now use ctx.drawImage to draw HTMLImageElements that have a .svg source in some but not all browsers (75% coverage: Chrome, IE11, and Safari work, Firefox works with some bugs, but nightly has fixed them).

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

Live example here. You should see a green square in the canvas. The second green square on the page is the same <svg> element inserted into the DOM for reference.

You can also use the new Path2D objects to draw SVG (string) paths. In other words, you can write:

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

Live example of that here.

Original 2010 answer:

There's nothing native that allows you to natively use SVG paths in canvas. You must convert yourself or use a library to do it for you.

I'd suggest looking in to canvg: (check homepage & demos)

canvg takes the URL to an SVG file, or the text of the SVG file, parses it in JavaScript and renders the result on Canvas.


Why is this needed? SVG seem to draw perfectly on a canvase with just drawImage. But I still get that warning. Where does it come from?
Simon, what you are saying is not correct. And secondly, it's a confirmed bug in Chrome.
Wikimedia doesn't like you using the SVG, it seems. I swapped in snapsvg.io/assets/images/logo.svg as the first available SVG I found. Worked in FF. jsfiddle.net/Na6X5/331
You can also use Data URI's in order to do this: jsfiddle.net/020k543w
Note: due to a long standing FireFox Bug, sadly, svgs that lack the width and height tags won't render at all on the canvas. Also, width and height must not be in percentages.
a
ashleedawg

Further to @Matyas answer: if the svg's image is also in base64, it will be drawn to the output.

Demo:

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
IMAGE
CANVAS


Same thing with fonts, they need to be embedded in the SVG: jsfiddle.net/ykx7kp8L/121
you might be able to iterate through the img tags in the svg, and just draw images on the canvas separately afterwards.
C
Crashalot

You can easily draw simple svgs onto a canvas by:

Assigning the source of the svg to an image in base64 format Drawing the image onto a canvas

Note: The only drawback of the method is that it cannot draw images embedded in the svg. (see demo)

Demonstration:

(Note that the embedded image is only visible in the 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



IMAGE

CANVAS


Is there any way to fix the problem that you mentioned. Image embedded in svg.
Sorry, but I haven't found a solution to the embedded image problem.
Okay. Thanks Matyas :)
D
DᴀʀᴛʜVᴀᴅᴇʀ

Mozilla has a simple way for drawing SVG on canvas called "Drawing DOM objects into a canvas"


This has the same drawback as in @Simon's first method: does not work in Firefox, Chrome OK.
Your link doesn't work anymore. I still interested in Mozilla way
@Alirezak just dug up a capture from archive.org: web.archive.org/web/20160529021018/https://…
s
sampathsris

As Simon says above, using drawImage shouldn't work. But, using the canvg library and:

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

This comes from the link Simon provides above, which has a number of other suggestions and points out that you want to either link to, or download canvg.js and rgbcolor.js. These allow you to manipulate and load an SVG, either via URL or using inline SVG code between svg tags, within JavaScript functions.


A
Alberto Manuel

Something to add, to show the svg correctly in canvas element add the attributes height and width to svg root element, Eg:

<svg height="256" width="421">...</svg>

Or

// Use this if to add the attributes programmatically
const svg = document.querySelector("#your-svg");

svg.setAttribute("width", `${width}`);
svg.setAttribute("height", `${height}`);

For more details see this