Firefox SVG2Blob 未按预期工作

Firefox SVG2Blob not working as expected

我正在使用 SVG 文本路径,我需要将其转换为常规 HTML canvas。为此,我将 SVG 转换为 blob 文件并将其 "downloading" 作为图像。然而,似乎在将 SVG 转换为 blob 时,firefox 在某处中断并且文本路径在此过程中完全丢失。

这是一个 fiddle 的问题:http://jsfiddle.net/ne5s2r1d/

var image = new Image();
var serializer = new XMLSerializer();
var data = serializer.serializeToString(document.getElementById("w3SVG"));

var blob = new Blob([data], {
    type: 'image/svg+xml'
});

var DOMURL = window.URL || window.webkitURL || window;
var url = DOMURL.createObjectURL(blob);

image.onload = function () {

    var canvas = document.createElement("canvas");
    var ctx = canvas.getContext("2d");

    canvas.width = canvas.height = 256;
    document.body.appendChild(canvas);

    ctx.drawImage(image, 20, 20);

    DOMURL.revokeObjectURL(url);
}

image.src = url;

var canvas2 = document.createElement("canvas");
var ctx2 = canvas2.getContext("2d");
document.body.appendChild(canvas2);

它适用于 IE10+、Opera、Chrome,但不适用于 Firefox。 (当前稳定版本) firefox 似乎完全忽略了路径元素。

关于如何解决这个问题有什么想法吗?我试过 Canvg,但它不支持文本路径,而且 Kinetic 似乎在 firefox 中创建渲染工件,更不用说它缺少一些关键的 SVG 功能。

我不知道有什么好的解决方案可以解决这个问题cross-browser。

但是对于 Firefox 和 webkit 浏览器,您可以尝试将 url 编码数据直接传递到图像 src。
(header 设置为 data:image/svg+xml; charset=utf8 ,)
然后在你的 canvas 中画出来。

它应该保留 xlink 引用,但 IE 会污染 canvas 因此您将无法访问其数据。
但是,您可以让用户右键单击 canvas 和 save picture as…

这是一个处理整个过程的小脚本:

function svgToPngDataURL(svg){
    var svgDocType = document.implementation.createDocumentType('svg',  "-//W3C//DTD SVG 1.1//EN", "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd");
    var svgDoc = document.implementation.createDocument ('http://www.w3.org/2000/svg', 'svg', svgDocType);
    svgDoc.replaceChild(svg.cloneNode(true), svgDoc.documentElement);
    var svgData = (new XMLSerializer()).serializeToString(svgDoc);
    var header = 'data:image/svg+xml; charset=utf8 ,';

    var img = new Image();
    img.onload = function(){
        var canvas = document.createElement('canvas');
        canvas.width = this.width;
        canvas.height = this.height;
        var ctx = canvas.getContext('2d');
        ctx.drawImage(this, 0,0);
        try{
            var data = canvas.toDataURL();
            }
        catch(ie){
            document.body.appendChild(canvas);
            displayIEerror();
            return;
            }
        doWhateverWith(data);
        }
    img.src = header+encodeURIComponent(svgData);
    }

这个的主要问题是,如果你必须支持 IE,没有其他方法可以知道它是否污染了 canvas 或 try{}catch()。
因此,toDataURL() 可能真的很耗电,在 try catch 中执行此操作可能不是一个好主意,严重 浏览器收集的垃圾
因此,如果您有办法知道您以前使用过 IE,请避免使用它,如果您必须在同一页面上多次使用它,请添加一个标志,使其只出现一次。