将修改后的SVG绘制到画布上 [英] Drawing a modified SVG to a canvas

查看:184
本文介绍了将修改后的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被创建为新图像('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) ,它会抛出错误无法将值转换为以下任何值: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:


  1. 使用XMLHttpRequest()将SVG加载为XML文档

  2. 操作该XML文档

  3. 将XML文档转换为字符串

  4. 从该字符串创建ObjectURL

  5. 使用ObjectURL创建图像

  6. 将图像复制到画布

  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

这是我的源代码:

修改:不幸的是,它仅适用于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();

这篇关于将修改后的SVG绘制到画布上的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆