最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Drawing a modified SVG to a canvas - Stack Overflow

programmeradmin1浏览0评论

I want to load an SVG image, do some manipulations to its .contentDocument, and then draw it to a canvas.

A good example for drawing an SVG to a canvas is here: .html

But in this example the svg was created as a new Image('url.svg') object. When you create an SVG that way, it unfortunately doesn't seem to have a contentDocument to manipulate. It only seems to have one when you create it as an <object> element.

But when I create the SVG as an object, get the SVG's DOM node and pass it to context.drawImage(svgNode, x, y), it throws the error "Value could not be converted to any of: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement." (on Firefox).

It seems like I either have to find a way to convert an object-SVG to a HTMLImageElement or a way to get the content document of an SVG which was loaded as an Image. Does anyone know how to do either? Or is there a third way to do it which I am missing?

I want to load an SVG image, do some manipulations to its .contentDocument, and then draw it to a canvas.

A good example for drawing an SVG to a canvas is here: http://www.phrogz/tmp/canvas_from_svg.html

But in this example the svg was created as a new Image('url.svg') object. When you create an SVG that way, it unfortunately doesn't seem to have a contentDocument to manipulate. It only seems to have one when you create it as an <object> element.

But when I create the SVG as an object, get the SVG's DOM node and pass it to context.drawImage(svgNode, x, y), it throws the error "Value could not be converted to any of: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement." (on Firefox).

It seems like I either have to find a way to convert an object-SVG to a HTMLImageElement or a way to get the content document of an SVG which was loaded as an Image. Does anyone know how to do either? Or is there a third way to do it which I am missing?

Share Improve this question edited Dec 20, 2012 at 0:25 Philipp asked Dec 20, 2012 at 0:03 PhilippPhilipp 69.9k10 gold badges120 silver badges158 bronze badges 1
  • 1 Maybe it's possible to turn the SVG's content document into an ObjectURL and use this to create an Image like in this example: developer.mozilla/en-US/docs/HTML/Canvas/… – Philipp Commented Dec 20, 2012 at 0:30
Add a ment  | 

2 Answers 2

Reset to default 2

I managed to do it. The trick was to:

  1. use XMLHttpRequest() to load the SVG as an XML document
  2. manipulate that XML document
  3. convert the XML document to a string
  4. create an ObjectURL from that string
  5. create an Image with that ObjectURL
  6. copy that Image to the canvas

That's my sourcecode:

Edit: Unfortunately it only works in Firefox and Chrome. It fails in IE9 because XMLSerializer() is not supported (it also doesn't support getElementById on XML documents, but there are workarounds for that) and it fails in Opera because createObjectUrl is not supported.

var xhr = new XMLHttpRequest();
xhr.onload = function() {
    // get the XML tree of the SVG
    var svgAsXml = xhr.responseXML;
    // do some modifications to the XML tree
    var element = svgAsXml.getElementById('hat');
    element.style.fill = '#ffff00';
    // convert the XML tree to a string
    var svgAsString = new XMLSerializer().serializeToString(svgAsXml);
    // create a new image with the svg string as an ObjectUrl
    var svgBlob = new Blob([svgAsString], {type: "image/svg+xml;charset=utf-8"});
    var url = window.URL.createObjectURL(svgBlob);
    var img = new Image();
    img.src = url;
    // copy it to the canvas
    img.onload = function() {
        var theCanvas = document.getElementById('theCanvas');
        var context = theCanvas.getContext('2d');
        context.drawImage(img, 0, 0);
        window.URL.revokeObjectURL(svgBlob);
    }
}
xhr.open("GET", "test.svg");
xhr.responseType = "document";
xhr.send();

Convert the svg's xml content into string data, then make a data uri out of it. You should be able to load that as an image. Something like this:

new Image("data:image/svg+xml," + svgdata);

Now you should be able to draw it to the canvas.

发布评论

评论列表(0)

  1. 暂无评论