简体   繁体   English

使用safari在画布中绘制包含html的svg

[英]Drawing an svg containing html in a canvas with safari

I'm trying to create some thumbnails of dynamically created pages for a website, i have found a solution by adding the html in a svg which I then draw on an image inside a canvas that I resize after the image has been drawn. 我正在尝试为网站创建一些动态创建页面的缩略图,我已经通过在svg中添加html找到了解决方案,然后我在画布内的图像上绘制,我在绘制图像后调整大小。

This solution works in firefox and chrome but not in safari, the svg doesn't seem to be drawn I just get a blank page. 这个解决方案适用于firefox和chrome,但不适用于safari,svg似乎没有被绘制我只是得到一个空白页面。 I don't get any error even if i put some try catch and I couldn't find a solution on the web. 即使我把一些尝试捕获,我也没有得到任何错误,我无法在网上找到解决方案。

My html is just a basic test page with a canvas, I tried to add a meta tag on the head 我的html只是一个带有画布的基本测试页面,我试图在头上添加一个元标记

<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />

but it didn't work either. 但它也没有用。

Here's the code I wrote : 这是我写的代码:

var canvas = document.getElementById('canvasTest'),
            context = canvas.getContext('2d');

            var data = "<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'>" +
                 "<foreignObject width='100%' height='100%'>" +
                   "<div xmlns='http://www.w3.org/1999/xhtml' style='font-size:40px'>" +
                     "<div>TEST<span>TEST</span></div>" +
                   "</div>" +
                 "</foreignObject>" +
               "</svg>"
            ;

            var DOMURL = self.URL || self.webkitURL || self;
            var img = new Image();                                                                              

            try {
                var svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"});                      
            } catch(e) {                    
                window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || window.MSBlobBuilder;
                console.log(window.BlobBuilder);

                if(e.name == 'TypeError' && window.BlobBuilder){
                    var bb = new BlobBuilder();
                    bb.append(data);
                    var svg = bb.getBlob("image/svg+xml;charset=utf-8");
                } else if(e.name == "InvalidStateError") {                      
                    var svg = new Blob(data, {type : "image/svg+xml;charset=utf-8"});
                } else {

                }
            }               

            var url = DOMURL.createObjectURL(svg);              

            img.onload = function() {                   
                    context.drawImage(img, 100, 100);                                       
            };

            img.src = url;
            DOMURL.revokeObjectURL(url);

            context.translate(canvas.width / 2, canvas.height / 2);
            context.scale(0.4, 0.4);

Safari can use the Blob constructor so it doesn't go in the catch. Safari可以使用Blob构造函数,因此它不会进入catch。 It seems like the problem is when I pass the svg reference (img.src = url) but i can't figure out what to do differently, if someone has some ideas or solution it would be great. 似乎问题是当我传递svg引用(img.src = url)但我无法弄清楚要做什么不同,如果有人有一些想法或解决方案,那将是很好的。

Edit: console output for safari 编辑:safari的控制台输出

Blob: Blob {size=232, type="image/svg+xml;charset=utf-8", webkitSlice} Blob:Blob {size = 232,type =“image / svg + xml; charset = utf-8”,webkitSlice}

Url: blob: http://myPage.com/96fb502f-46bb-492b-af35-5313bb39bd31 网址:blob: http//myPage.com/96fb502f-46bb-492b-af35-5313bb​​39bd31

Basically the solution was to put the mime type(data:image/svg+xml) in the variable containing the svg, this way you don't need to use the blob anymore and then to set the img src with the svg before drawing it to the canvas. 基本上解决方案是将mime类型(data:image / svg + xml)放在包含svg的变量中,这样你就不需要再使用blob了,然后在绘制之前用svg设置img src到画布。

var canvas = document.getElementById('canvasTest'),
            context = canvas.getContext('2d');

            var data = "data:image/svg+xml,"+"<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'>" +
                 "<foreignObject width='100%' height='100%'>" +
                   "<div xmlns='http://www.w3.org/1999/xhtml' style='font-size:40px'>" +
                     "<div xmlns='http://www.w3.org/1999/xhtml'>aaaa<span>aaaa</span></div>" +
                   "</div>" +
                 "</foreignObject>" +
               "</svg>"
            ;

            var img = new Image();

            img.src = data;

            img.onload = function() {
                context.drawImage(img, 100, 100);                   
            };

            context.translate(canvas.width / 2, canvas.height / 2);
            context.scale(0.4, 0.4);

You don't state what you get in console on the Blob nor the URL. 您没有在Blob上说明您在控制台中获得的内容,也没有说明URL。

Just a shot but you are revoking the url right after setting it as source on the image. 只需一次拍摄,但您在将其设置为图像上的源后立即撤消该网址。 You need to revoke if after the image has been loaded in the onload event: 如果 onload事件中加载了图像 ,您需要撤消:

img.onload = function() {                   
    DOMURL.revokeObjectURL(url);      /// here
    context.drawImage(img, 100, 100);                                       
};

img.src = url;
//DOMURL.revokeObjectURL(url);        /// not here

See that helps out. 看到这有帮助。 If not then you're probably dealing with a Safari specific issue. 如果没有,那么你可能正在处理特定于Safari的问题。 (your canvas specific translate etc. should also be inside the onload event or at least called before you set the src property). (您的画布特定翻译等也应该在onload事件中,或者至少在设置src属性之前调用)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM