javascript - 使用 Blob 将使用 Google 字体的 SVG 转换为 Canvas

标签 javascript svg canvas

<分区>

我在使用 Google 字体的页面上显示了一个 SVG。

<text> SVG 上的节点很好地继承了 Google 字体。

现在,我正在尝试使用 Blob 转换 SVG .

这有效,除了 <text>使用安装在浏览器计算机上的后备“Verdana”呈现,而不是“Pacifico”,后者是一种动态加载的 Google 字体。

window.onload = function() {
  var width = 400;
  var height = 100;

  var DOMURL = self.URL || self.webkitURL || self;
  var data = new XMLSerializer().serializeToString(document.getElementById("test"));

  var svg = new Blob([data], { type: "image/svg+xml" });
  var url = DOMURL.createObjectURL(svg);

  var canvas = document.getElementById("result");
  canvas.width = width;
  canvas.height = height;
  var ctx = canvas.getContext("2d");

  var img = new Image(width, height);
  img.onload = function() {
    ctx.drawImage(img, 0, 0);
    DOMURL.revokeObjectURL(url);
  }
  img.src = url;
}
@import url('https://fonts.googleapis.com/css?family=Pacifico');
body {
  font-family: Pacifico, Verdana;
  font-size: 15px;
}
body * {
  font-family: Pacifico, Verdana;
}

#test, #result {
  border: 1px solid #eee;
}

h4 {
  margin: 2em 0 1em 0;
}
<h4>Source SVG</h4>
<svg id="test" width="400px" height="100px" style="font-family: 'Pacifico', 'Verdana'; font-size: 15px;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <g xmlns="http://www.w3.org/2000/svg">
    <rect fill="#67b7dc" transform="translate(-0.5,-0.5)" width="80" height="100" />
    <rect fill="#6794dc" transform="translate(80,0)" transform="translate(-0.5,-0.5)" width="80" height="100" />
    <rect fill="#6771dc" transform="translate(160,0)" transform="translate(-0.5,-0.5)" width="80" height="100" />
    <rect fill="#8067dc" transform="translate(240,0)" transform="translate(-0.5,-0.5)" width="80" height="100" />
    <rect fill="#a367dc" transform="translate(320,0)" transform="translate(-0.5,-0.5)" width="80" height="100" />
    <text fill="#fff" transform="translate(20,20)" font-size="25" dy="20">
      Some text using font</tspan>
    </text>
  </g>
</svg>
  
<h4>Result canvas</h4>
<canvas id="result" />

到目前为止,我还没有找到让 Canvas 文本使用自定义字体的方法,如果有任何帮助,我将不胜感激。

附言作为记录,我知道像 fabric 和 canvg 这样的第三方库的存在。他们能够将 SVG 转换为 Canvas 而不会丢失自定义字体。但是,我试图避免不使用任何第 3 方库,以保持轻便。

附言包括 Google 字体的 @import进入<defs><style> SVG 部分没有帮助,即使我们明确定义 @font-face .坦率地说,这不是一个选择,因为我还不知道库将使用什么字体。

P.P.P.S 延迟导出没有帮助,所以这可能也不是时间问题。

最佳答案

您可能将所有精力都集中在 Canvas 上,但问题已经开始出现在您的图像上...

这是您的代码,但只是一个非常小的示例

<style>
  @import url('https://fonts.googleapis.com/css?family=Pacifico');
  body * { margin: 0; }
</style>

<h4>Source</h4>
<svg id="test" width="300px" height="30px" style="font-family: 'Pacifico', 'Verdana'; font-size: 15px;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <g xmlns="http://www.w3.org/2000/svg">
    <rect fill="#67b7dc" transform="translate(-0.5,-0.5)" width="300" height="50" />
    <text fill="#fff"  font-size="25" dy="20"> <tspan>Some text using font</tspan> </text>
  </g>
</svg>

<h4>Image</h4>
<img id="image" />

<script>
  window.onload = function() {
    var DOMURL = self.URL || self.webkitURL || self;
    var data = new XMLSerializer().serializeToString(document.getElementById("test"));

    var svg = new Blob([data], { type: "image/svg+xml" });
    var url = DOMURL.createObjectURL(svg);

    var img = document.getElementById("image");
    img.src = url;
  }
</script>

关于 SVG 字体的这个问题有很多争论,这里有一篇很好的文章:

https://github.com/JChemPaint/jchempaint/wiki/The-svg-font-problem-and-its-solution

关于javascript - 使用 Blob 将使用 Google 字体的 SVG 转换为 Canvas,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51695753/

相关文章:

android - 颜色选择器不适用于撤消和重做

javascript - 将 jQuery 焦点和模糊添加到菜单以实现可访问性

javascript - ReactJS:有更好的方法吗?

javascript - 使用每个函数 jquery 迭代父 li

javascript - 如果在 svg 中单击的不是某个元素,而是使用 d3.js v5.4.0 的其他元素,则调用函数

javascript - SVG 路径绘制和图像填充

html - 将 JPEG 图层添加到 Canvas(使用 Caman)

javascript - Express 似乎忽略了根路由的 Controller

html - 缩放 svg

javascript - html5 <canvas> 在 Opera 11 上速度极慢?