Javascript 将修改后的SVG绘制到画布

Javascript 将修改后的SVG绘制到画布,javascript,svg,html5-canvas,Javascript,Svg,Html5 Canvas,我想加载一个SVG图像,对其.contentDocument进行一些操作,然后将其绘制到画布上 将SVG绘制到画布的一个很好的示例如下: 但在本例中,svg是作为新图像('url.svg')对象创建的。当您以这种方式创建SVG时,不幸的是,它似乎没有可操作的contentDocument。当您将它创建为元素时,它似乎只有一个 但是,当我将SVG创建为对象时,获取SVG的DOM节点并将其传递给context.drawImage(svgNode,x,y),它抛出错误“值无法转换为以下任何值:HTML

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

将SVG绘制到画布的一个很好的示例如下:

但在本例中,svg是作为
新图像('url.svg')
对象创建的。当您以这种方式创建SVG时,不幸的是,它似乎没有可操作的contentDocument。当您将它创建为
元素时,它似乎只有一个

但是,当我将SVG创建为对象时,获取SVG的DOM节点并将其传递给
context.drawImage(svgNode,x,y)
,它抛出错误
“值无法转换为以下任何值:HTMLImageElement、htmlCanvaElement、HTMLVideoElement。”
(在Firefox上)


似乎我必须找到一种方法将对象SVG转换为HTMLImageElement,或者找到一种方法获取作为图像加载的SVG的内容文档。有人知道怎么做吗?还是有第三种方法我没有找到?

将svg的xml内容转换为字符串数据,然后从中生成一个数据uri。您应该能够将其作为图像加载。大概是这样的:

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

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

我设法做到了。诀窍是:

  • 使用XMLHttpRequest()将SVG作为XML文档加载
  • 操纵那个XML文档
  • 将XML文档转换为字符串
  • 从该字符串创建ObjectURL
  • 使用该ObjectURL创建图像
  • 将该图像复制到画布上
  • 这是我的源代码:

    编辑:不幸的是,它只适用于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();
    

    也许可以将SVG的内容文档转换为ObjectURL,并使用它创建一个图像,如本例所示:抱歉,但这说起来容易做起来难。正如我所说,我正在使用contentDocument修改SVGs内容。这意味着我不能将SVGs源代码作为XML字符串加载。SVG对象没有toDataUrl方法。这意味着要将SVG内容转换为XML字符串,我必须手动迭代整个SVG文档树,并从中构建有效的XML。也许我可以将SVG作为一个通用的XMLDocument加载,并将其作为XML树而不是SVG对象进行操作。