将修改后的 SVG 绘制到画布上
我想加载一个 SVG 图像,对其 .contentDocument
进行一些操作,然后将其绘制到画布上.
I want to load an SVG image, do some manipulations to its .contentDocument
, and then draw it to a canvas.
将 SVG 绘制到画布上的一个很好的例子是:http://www.phrogz.net/tmp/canvas_from_svg.html
A good example for drawing an SVG to a canvas is here: http://www.phrogz.net/tmp/canvas_from_svg.html
但在本例中,svg 被创建为 new Image('url.svg')
对象.当您以这种方式创建 SVG 时,不幸的是,它似乎没有要操作的 contentDocument.当您将其创建为 <object>
元素时,它似乎只有一个.
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.
但是当我将 SVG 创建为对象时,获取 SVG 的 DOM 节点并将其传递给 context.drawImage(svgNode, x, y)
,它会抛出错误 "Value could不能转换为以下任何一种:HTMLImageElement、HTMLCanvasElement、HTMLVideoElement."
(在 Firefox 上).
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).
看来我要么必须找到将对象 SVG 转换为 HTMLImageElement 的方法,要么必须找到一种方法来获取作为图像加载的 SVG 的内容文档.有谁知道该怎么做?还是有第三种方法可以做到这一点,我错过了?
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 managed to do it. The trick was to:
- 使用 XMLHttpRequest() 将 SVG 加载为 XML 文档
- 操作该 XML 文档
- 将 XML 文档转换为字符串
- 从该字符串创建一个 ObjectURL
- 使用该 ObjectURL 创建一个图像
- 将该图像复制到画布
这是我的源代码:
不幸的是,它只适用于 Firefox 和 Chrome.它在 IE9 中失败,因为不支持 XMLSerializer()(它也不支持 XML 文档上的 getElementById,但有一些解决方法),它在 Opera 中失败,因为不支持 createObjectUrl.
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();
相关文章