【问题标题】:Drawing an svg containing html in a canvas with safari使用 safari 在画布中绘制包含 html 的 svg
【发布时间】:2014-01-29 17:07:01
【问题描述】:

我正在尝试为网站创建一些动态创建页面的缩略图,我找到了一个解决方案,方法是在 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 构造函数,因此它不会陷入困境。问题似乎是当我通过 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

【问题讨论】:

  • 之后可以使用.toDataURL(),还是在 Safari 上出现安全错误?

标签: javascript canvas svg safari


【解决方案1】:

基本上解决方案是将mime type(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);

【讨论】:

  • 该死的天才!谢谢你的超级简单的例子。我有一些代码可以在 Chrome 和 FF 中运行,但不能在 Safari 中运行。它使用 window.URL 对象并使用它来创建一个 blob,然后将 blob 绘制到画布上。您在此处的示例要简单得多,它适用于 Safari 以及我需要支持的其他浏览器。谢谢!
  • 您可能想说var data = "data:image/svg+xml;utf8," + encodeURIComponent(svgElementCode); 代替,以获得 utf-8 和更好的浏览器支持。 See here.
【解决方案2】:

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

只是一个镜头,但您在将其设置为图像上的源后立即撤消该 url。如果图像在onload 事件中加载之后,则需要撤销:

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

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

看到这有帮助。如果不是,那么您可能正在处理特定于 Safari 的问题。 (您的画布特定翻译等也应该在 onload 事件中,或者至少在您设置 src 属性之前调用)。

【讨论】:

  • 感谢您的回答。我尝试了你的解决方案,但我仍然在 safari 上得到一个空白页。我已经编辑了我的问题以包含 blob 和 url 的控制台输出。您对问题可能是什么有更多想法吗?
  • 我终于找到了适用于 ff chrome 和 safari 的解决方案,我稍后会发布。感谢您的回答,我赞成您的帮助
猜你喜欢
  • 2013-07-10
  • 2013-01-07
  • 2016-09-13
  • 1970-01-01
  • 2018-11-30
  • 2023-03-14
  • 1970-01-01
  • 2012-10-05
  • 2013-05-26
相关资源
最近更新 更多