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

时间:2014-01-10 16:15:46

标签: javascript canvas svg safari

我正在尝试为网站创建一些动态创建页面的缩略图,我已经通过在svg中添加html找到了解决方案,然后我在画布内绘制了一个图像,我在绘制图像后调整大小

此解决方案适用于firefox和chrome,但不适用于safari,svg似乎没有绘制我只是得到一个空白页面。即使我把一些尝试捕获,我也没有得到任何错误,我无法在网上找到解决方案。

我的html只是一个带画布的基本测试页面,我试图在头上添加一个元标记

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

但它也没有用。

这是我写的代码:

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可以使用Blob构造函数,因此它不会进入catch。似乎问题是当我传递svg引用(img.src = url)但我无法弄清楚要做什么不同的事情,如果有人有一些想法或解决方案那就太棒了。

编辑:safari的控制台输出

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

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

2 个答案:

答案 0 :(得分:13)

基本上解决方法是将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);

答案 1 :(得分:1)

您没有在Blob上说明您在控制台中获得的内容,也没有说明URL。

只需一次拍摄,但您在将其设置为图像上的源后立即撤消该网址。如果在<{1}}事件中加载了图像之后,则需要撤消

onload

看到帮助。如果没有,那么你可能正在处理特定于Safari的问题。 (您的画布特定翻译等也应该在img.onload = function() { DOMURL.revokeObjectURL(url); /// here context.drawImage(img, 100, 100); }; img.src = url; //DOMURL.revokeObjectURL(url); /// not here 事件内或至少在设置onload属性之前调用。)