Firefox SVG2Blob not working as expected

北城余情 提交于 2019-12-11 13:13:01

问题


I'm working with SVG text paths which I need to convert to regular HTML canvas. For that I'm converting SVG to a blob file and "downloading" it as an image. However it seems that while converting SVG to blob firefox breaks somewhere and text path is lost completely in the process.

Here's a fiddle of the problem: 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);

It works with IE10+, Opera, Chrome but not firefox. (Current stable releases) It seems that firefox completely ignores the path element.

Any ideas on how to solve this? I tried Canvg but it doesn't support text paths and Kinetic seems to create rendering artifacts in firefox not to mention it's missing some of the key SVG features.


回答1:


I know no good solution for this to work cross-browser.

However for Firefox and webkit browsers, you could try to pass directly the url encoded data to an image src.
(with the header set as data:image/svg+xml; charset=utf8 ,)
Then draw it in your canvas.

It should keep the xlink references, but IE will taint the canvas so you won't be able to access its data.
However, you can let the user right click on the canvas and save picture as….

Here is a little script that handles the full process :

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);
    }

The main problem of this is that if you have to support IE, there is no other way to know whereas it has tainted the canvas or not that a try{}catch().
Thus, toDataURL() can be really consumptive and it may be a bad idea to do it in a try catch, badly garbage collected by browsers.
So if you have a way to know that you are using IE before, avoid it and if you have to do it multiple time on the same page, add a flag so it occurs only once.



来源:https://stackoverflow.com/questions/29968549/firefox-svg2blob-not-working-as-expected

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!