How to draw an inline svg (in DOM) to a canvas?
For inline SVG you'll need to:
- Convert the SVG string to a
Blob
- Get an URL for the Blob
- Create an image element and set the URL as
src
- When loaded (
onload
) you can draw the SVG as an image on canvas - Use
toDataURL()
to get the PNG file from canvas.
For example:
function drawInlineSVG(ctx, rawSVG, callback) {
var svg = new Blob([rawSVG], {type:"image/svg+xml;charset=utf-8"}),
domURL = self.URL || self.webkitURL || self,
url = domURL.createObjectURL(svg),
img = new Image;
img.onload = function () {
ctx.drawImage(this, 0, 0);
domURL.revokeObjectURL(url);
callback(this);
};
img.src = url;
}
// usage:
drawInlineSVG(ctxt, svgText, function() {
console.log(canvas.toDataURL()); // -> PNG data-uri
});
Of course, console.log here is just for example. Store/transfer the string instead here. (I would also recommend adding an onerror
handler inside the method).
Also remember to set canvas size using either the width
and height
attributes, or from JavaScript using properties.
How to draw a SVG on Canvas using Javascript?
Try to use image to draw (so snippet not works - but when you edit it - it works)
let xml = new XMLSerializer().serializeToString(circSvg); // get svg datalet svg64 = btoa(xml); // make it base64let b64Start = 'data:image/svg+xml;base64,';let image64 = b64Start + svg64; // prepend a "header"
circImg.src = image64; // image sourcecircImg.onload = x=> { can.getContext('2d').drawImage(circImg, 0, 0); // draw}
svg<br><svg id="circSvg" width="100" height="100"> <circle cx="50" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" /> Sorry, your browser does not support inline SVG.</svg>
<br>canvas<br> <canvas id="can"></canvas>
<img id="circImg" style="display:none">
Drawing an SVG file on a HTML5 canvas
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.
How to draw a SVG in string format in a canvas html element?
Here you have two examples. In both examples I added the SVG namespace to the string, be cause it is a separate XML/SVG document and not haft of the HTML.
In the first example I just create a data URL and insert that as the source of an image object. Here you need to set the width and the height.
In the second example I used Blob and the function URL.createObjectURL().
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
const svgString = (color) => `<svg xmlns="http://www.w3.org/2000/svg" height="150" width="500">
<ellipse cx="240" cy="100" rx="220" ry="30" style="fill:${color}" />
<ellipse cx="220" cy="70" rx="190" ry="20" style="fill:lime" />
<ellipse cx="210" cy="45" rx="170" ry="15" style="fill:yellow" />
</svg>`;
var img = new Image();
img.width = 500;
img.height = 150;
img.addEventListener('load', e => {
ctx.drawImage(e.target, 0, 0);
});
img.src = `data:image/svg+xml,${svgString('red')}`;
<canvas width="500" height="150" id="canvas"></canvas>
Drawing SVG into Canvas and manipulating drawn elements using their IDs
Here's how to do this with Fabric:
fabric.loadSVGFromURL('/assets/72.svg', function(objects, options){
var group = fabric.util.groupSVGElements(objects, options);
group
.set({ left: 300, top: 200 })
.scaleToWidth(500)
.setCoords();
canvas.add(group);
}, reviver);
function reviver(element, object) {
object.id = element.getAttribute('id');
}
The code should be pretty self-explanatory. We load SVG; Fabric parses it internally, spitting out set of objects representing each element. We then group those elements and add them onto canvas in one chunk. Reviver is responsible for reading id off of each SVG element and assigning it to a corresponding fabric instance.
Run this snippet in http://fabricjs.com/kitchensink/ and you get:
Let's inspect this grouped object:
canvas.item(0) + ''; "#<fabric.PathGroup (29303): { top: 200, left: 300 }>"
And its children:
canvas.item(0).getObjects(); // Array[2287]
Let's retrieve one by id:
var greenland = canvas.item(0).getObjects().filter(function(obj) {
return obj.id === 'path4206';
})[0];
This is all plain old Javascript, as you can see. Let's change color of that particular object/shape now:
greenland.fill = 'red';
Trying to draw SVG to canvas, but it's being cut short
Change the SVG so its size matches the canvas and it works on Firefox for me e.g.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class="layer" id="layer_text" width="778" height="544">
Related Topics
Get Next/Previous Element Using JavaScript
Case Insensitive Xpath Contains() Possible
How to Use HTML Tags in the Options For Select Elements
How Exactly Does ≪Script Defer="Defer"≫ Work
How to Capture the Right-Click Event in JavaScript
How to Set Html5 Required Attribute in JavaScript
Innertext VS Innerhtml VS Label VS Text VS Textcontent VS Outertext
How to Create a Link Using JavaScript
How to Disable HTML Button Using JavaScript
How to Open a Pdf File in an ≪Iframe≫
Good Tutorial For Using Html5 History API (Pushstate)
Convert Data Uri to File Then Append to Formdata
How to Launch HTML Using Chrome At "--Allow-File-Access-From-Files" Mode
Adding Two Numbers Concatenates Them Instead of Calculating the Sum