【发布时间】:2020-11-26 23:59:57
【问题描述】:
我正在生成一个带有文本的 svg,使用 D3.js 供用户下载。
不幸的是,当下载 svg 时,应用到 svg 上的文本的字体系列在 svg 转换为画布然后下载为 png 时似乎不包括在内。
字体样式似乎丢失了。
有没有办法使用这个字体系列来构建 png?
要将 svg 下载为 png,我调整了答案 described here。
这是我的过程:
首先,我创建 svg。
await d3.xml(`img_templates/${template}_${dimensions}.svg`)
.then(data => {
divsvg.append(data.documentElement) //Append svg to DOM
});
然后,我将我的文本元素添加到 svg
const quoteText = quoteGroup.append("text")
.attr("class", "quote")
.style("font-size", `15px`)
.style("font-family", 'Merriweather')
Merriweather 是一个 Google 字体系列,我将其加载到 html 页面的头部,如下所示:
<head>
<link href="https://fonts.googleapis.com/css2?family=Merriweather&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,700;1,400&display=swap" rel="stylesheet"> <!--Another font I use-->
<script src="d3.min.js"></script>
<script src=genImage.js></script> <!--The js code to interact with the svg -->
</head>
下载时,我在 svg 上执行以下功能,
function downloadSVG(svgObj){
var data = (new XMLSerializer()).serializeToString(svgObj);
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
var svgBlob = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
var url = DOMURL.createObjectURL(svgBlob);
img.onload = function () {
var canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
var imgURI = canvas
.toDataURL('image/png')
.replace('image/png', 'image/octet-stream');
// console.log(imgURI)
triggerDownload(imgURI);
};
img.src = url;
}
function triggerDownload (imgURI) {
var evt = new MouseEvent('click', {
view: window,
bubbles: false,
cancelable: true
});
var a = document.createElement('a');
a.setAttribute('download', 'MY_COOL_IMAGE.png');
a.setAttribute('href', imgURI);
a.setAttribute('target', '_blank');
a.dispatchEvent(evt);
}
当序列化为字符串时,svg 显示如下:
<svg xmlns="http://www.w3.org/2000/svg" width="484" height="484" viewBox="0 0 484 484" fill="none">
<g class="quoteGroup" transform="translate(42,100)">
<text class="quote" fill="#FFFFFF" style="font-size: 25px; font-family: Merriweather;"><tspan x="0">"I’m staying alone in Montauk at a</tspan><tspan x="0" dy="40px">friend’s house while he’s in Portugal</tspan><tspan x="0" dy="40px">(something about taxes and quality of</tspan><tspan x="0" dy="40px">life). After my morning coffee and</tspan><tspan x="0" dy="40px">power shake, it’s time to water the</tspan><tspan x="0" dy="40px">plants."</tspan></text>
</g>
<g class="headlineGroup" transform="translate(42,365)">
<text class="headline" font-size="15px" fill="#FFFFFF" style="font-family: Roboto; font-style: italic;"><tspan x="0">Stop Thinking of the Breakup of Big Tech as Punishment</tspan></text>
</g>
<g class="publisherGroup" transform="translate(42,430)">
<text class="publisher" font-size="15px" fill="#FFFFFF" style="font-family: Roboto; font-weight: bold;">Marker</text>
</g>
<g class="dateGroup" transform="translate(353,430)"><text class="date" font-size="15px" fill="#FFFFFF" style="font-family: Roboto; font-weight: bold;">Aug 04, 2020</text></g>
</svg>
据我所知,在字符串中正确指定了字体系列,但是当 svg 转换为画布然后转换为 png 时,它正在丢失。为什么会发生这种情况?
如果我可以提供任何其他信息,请告诉我。非常感谢任何帮助!
【问题讨论】:
-
因为字体定义不在 SVG 中,它们在 HTML 文档中,BLOB 无法从那里读取它们。
-
有道理,有没有一个地方可以放置字体定义以使 BLOB 可以访问它们?我也将字体下载为 .ttf 文件
-
您可以尝试对它们进行 URL 编码(或 base64 编码)并将它们嵌入到 blob 中。
标签: javascript html css d3.js svg