2012-12-20 32 views
3

我想加载SVG图像,对其.contentDocument进行一些操作,然后将其绘制到画布上。将修改后的SVG绘制到画布上

一个很好的例子绘制一个SVG的画布是在这里:http://www.phrogz.net/tmp/canvas_from_svg.html

但在这个例子中,SVG被作为new Image('url.svg')对象创建的。当你这样创建一个SVG时,它不幸似乎没有一个contentDocument来操作。当您将它创建为<object>元素时,它似乎只有一个。

但是,当我创建SVG作为对象时,获取SVG的DOM节点并将其传递给context.drawImage(svgNode, x, y),它会抛出错误"Value could not be converted to any of: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement."(在Firefox上)。

看来我要么必须找到一种方法将对象SVG转换为HTMLImageElement或获取作为图像加载的SVG的内容文档的方式。有谁知道如何做?还是有第三种方法来做到这一点,我失踪了?

+1

也许有可能打开SVG内容文档转换成的ObjectURL并使用它来创建一个图片就像这个例子:https://developer.mozilla.org/en-US/docs/HTML/Canvas/ Drawing_DOM_objects_into_a_canvas – Philipp

回答

1

我设法做到了。诀窍是:

  1. 使用XMLHttpRequest()来加载SVG作为XML文档
  2. 操作这些XML文档
  3. XML文档转换为字符串
  4. 从字符串
  5. 创建的ObjectURL
  6. 制作图像与的ObjectURL
  7. 拷贝图片到画布

这是我的源代码:

编辑:不幸的是,它只适用于Firefox和Chrome。它在IE9中失败,因为XMLSerializer()不受支持(它也不支持XML文档上的getElementById,但有解决方法),并且在Opera中失败,因为不支持createObjectUrl。

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(); 
1

将svg的xml内容转换为字符串数据,然后将数据uri从中提取出来。您应该能够将其作为图像加载。类似这样的:

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

现在你应该可以把它画到画布上了。

+0

对不起,但说起来容易做起来难。正如我所说我正在使用contentDocument修改SVG内容。这意味着我无法将SVGs源代码作为XML字符串加载。而SVG对象没有toDataUrl方法。这意味着要将SVG内容转换为XML字符串,我必须手动迭代整个SVG文档树并从中构建有效的XML。 – Philipp

+0

虽然你给了我一个主意。也许我可以将SVG加载为通用XMLDocument,并将其作为XML树而不是SVG对象进行操作。 – Philipp

+0

我设法做到了!看到我的答案。 – Philipp