使用支持字体元素的HTML5画布绘制SVG

23

有没有一个好的库能够将SVG转换为HTML画布并支持font元素?我已经尝试过canvg,但它不支持Font。


需要在SVG中嵌入字体(和图像),才能使其正常工作:https://jsfiddle.net/ykx7kp8L/121/ - Sphinxxx
3个回答

33

支持 HTML5 Canvas 的浏览器也很好地支持 SVG。因此,您可以这样做:

var img = new Image;
img.onload = function(){ myCanvasContext.drawImage(img,0,0); };
img.src = "foo.svg";
这种技术的唯一缺点是,如果SVG位于你的域之外,那么canvas将变得污染;如果这是你的目标,那么你将无法使用getImageData()读取结果。 我在我的服务器上放了一个此技术的示例:http://phrogz.net/tmp/canvas_from_svg.html。 我已经测试并验证它可以在IE9、Chrome v11b、Safari v5和Firefox v4上正常工作(并且看起来相同)。 [编辑]请注意:
  1. Chrome和Firefox目前在安全方面“放弃”并禁止您在将任何SVG绘制到画布上后从画布中读取它们(例如getImageData()toDataURL()),而不考虑域(无论如何都不能)。 这些问题已经被解决了

  2. Firefox目前存在一个错误,除非指定SVG的heightwidth属性,否则它将拒绝将SVG绘制到画布上。


@Nilesh 你用的是什么操作系统和Firefox版本?我在Windows 7上使用FF4.0可以正常工作。 - Phrogz
3
我有一个 JavaScript 字符串作为 SVG。我使用它的方式是 img.src = "data:image/svg+xml,"+svgString; Chrome 可以正常工作,但 Firefox 拒绝解析 svgString 变量,因为我嵌入了 CDATA 样式。 更新:通过使用 encodeURIComponent(svgString) 已经解决了这个问题。 - arunkjn
这个解决方案不包括字体!你能添加一些Arial字体的文本(除了衬线字体Times)并查看它是否仍然正确呈现吗? - headwinds
@headwinds 是的。您可以进行测试并自行查看。(如果您需要帮助设置字体并绘制它,您需要使用.font = "...".fillText()这里有一个教程。) - Phrogz
1
@Phrogz 好的,我看到了区别,谢谢。但是如果原始SVG有特殊的字体,并且您想通过序列化SVG将其包括字体复制到画布上,则如果在画布上使用.font,字体实际上不会显示出来,这就是为什么http://graphicdesign.stackexchange.com/questions/5162/how-do-i-embed-google-web-fonts-into-an-svg -您的解决方案很好,但根据SVG如何转换,可能并非在所有情况下都适用。 - headwinds

13

如果您将svg嵌入HTML或作为原始源,则可以使用数据URL将svg转换为HTML图像元素,然后可以在画布上绘制:

var img = new Image();
// here attach an onload handler that draws the image on the canvas

// svgSource is the raw svg xml
img.src = "data:image/svg+xml," + encodeURIComponent(svgSource);

请注意,对于复杂的SVG内容,您可能会遇到数据:URI的大小限制 - 在我的情况下,这意味着我别无选择,只能使用canvg来绘制复杂的SVG。 - Florian Ledermann

1

我刚刚尝试了一个简单的img标签,Phrogs'方法和canvg。我的SVG文件中嵌入了PNG图像。只有canvg可以正常显示,其他方法都无法显示嵌入的PNG图像。这是在Android Jellybean上使用标准浏览器或Chrome浏览器测试的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接