字体不是 SVG 时 SVG 中的动态文本问题

平面设计 字体 svg 网络字体 调整大小 javascript
2022-02-06 05:58:02

因此,我有一个图形自动化链,它使用编程生成/更改的 SVG 和 PhantomJS(当前为 1.9.0)作为最终渲染引擎,在无头 linux 环境中愉快地运行。我有一些动态文本替换要求,以及由此产生的动态字体缩放和调整需求......我一直在使用嵌入式 SVG 字体和一些糟糕的嵌入式 javascript,它们工作得很好,除了两件事:

1) 客户端对带连字的字体有一些要求(SVG 字体格式不支持)

2)我们正在推出一个实时预览选项,并且希望能够将 SVG 提供给网页,而无需事先在我们的服务器上渲染出 png/jpeg/任何内容。降低负载,让客户端 CPU 完成繁重的工作,所有这些。

为了解决这些问题,我一直在玩 WOFF 字体,因为对 SVG 字体的支持从来都不是很好,现在 Chrome 不再支持它们,如果我想要客户端,切换到 Blink 引擎做我的工作我需要与尽可能多的常见浏览器兼容的东西......

所以问题来了:当我使用 WOFF(或 OFT 或 TTF)字体和 @font-face 函数时,我的自动缩放失败得很惨。

我一直在做的只是将 SVG 字体嵌入到我的 defs 图形中,并像任何其他 SVG 元素一样引用 DOM。当与这样的 java 脚本结合使用时,这可以满足我的期望和需要:

<script id="multiscaler1" type="text/javascript">
    var texta = document.getElementById(&quot;text8093&quot;);
    var textb = document.getElementById(&quot;text8100&quot;);
    var textpatha = document.getElementById(&quot;textPath8097&quot;);
    var textpathb = document.getElementById(&quot;textPath8104&quot;);
    var patha = document.getElementById(&quot;path8091&quot;);
    var pathb = document.getElementById(&quot;path8089&quot;);
    var charcounta = textpatha.getNumberOfChars();
    var charcountb = textpathb.getNumberOfChars();
    var fontsizea = 10;
    var fontsizeb = 10;
    var offseta = -13;
    var offsetb = -13;
    var spacing = 0;
    while ( ((textpatha.getComputedTextLength() + (spacing * charcounta)) &lt; patha.getTotalLength()) &amp;&amp; (fontsizea &lt; 43) )
    {
        fontsizea += .5;
        offseta += 0.2
        textpatha.setAttribute(&quot;font-size&quot;, fontsizea);
        texta.setAttribute(&quot;transform&quot;, &quot;translate(&quot; + offseta + &quot;,0)&quot;);
    }
    while ( ((textpathb.getComputedTextLength() + (spacing * charcountb)) &lt; pathb.getTotalLength()) &amp;&amp; (fontsizeb &lt; 43) )
    {
        fontsizeb += .5;
        offsetb += 0.2
        textpathb.setAttribute(&quot;font-size&quot;, fontsizeb);
        textb.setAttribute(&quot;transform&quot;, &quot;translate(&quot; + offsetb + &quot;,0)&quot;);
    } 
</script>

很垃圾,我知道,但我是生产经理和图形艺术家,而不是编码器:P,它看起来像这样:

在此处输入图像描述

这就是我想要的......(但当然只适用于支持 SVG 字体的浏览器......)

现在,当我将这个小美添加到我的定义中时

<style type="text/css">
@font-face {
  font-family: Narrow-Bold;
  src: url('WOFFFONTS/Narrow-Bold.woff');
}
</style>

并删除我得到的 SVG 字体数据:

在此处输入图像描述

哦亲爱的。这根本不对。我已经使用了我的间距值(这是为了处理另一种情况,即我更改字符间距以根据字符串长度最大化字体大小......)并且可以让它做到这一点:

在此处输入图像描述

也完全错误:/

这里给出了什么?有什么帮助吗?坦率地说,将所有字体都切换到 WOFF(或@font-face 链接的 OTF 或 TTF 字体,顺便说一句,做同样的事情)字体会很可爱,因为如果没有嵌入字体,我将拥有更少的 20,000 多行 SVG该死的地方……

我尝试了不同的字体转换工具,甚至是我在一些谷歌搜索结果中发现的一个技巧,其中你从 SVG 构建 WOFF,而不是 TTF 或 OTF ......相同的结果。

??

下面是一个使用免费Delicious Bold字体的带有嵌入式 SVG 字体的独立 SVG 的简化示例显然,这只适用于支持 SVG 字体的浏览器。嵌入的字体是使用FontForge For Windows Release 2015-06-12从新下载的 OTF 创建的我还创建了相同字体的 WOFF 版本以相同的方式(所有默认设置,忽略 TTF 定义中有关“非标准 ems Advance”的警告)并添加了一个具有不同名称的 @font-face 链接,当它与 WOFF 位于同一目录时,该链接将指向 WOFF SVG。通过编辑 SVG 的 text/textpath 元素中的 font-face="xxxxxx" ,您可以在嵌入的 SVG 字体、链接的 WOFF 字体(缩放不正确)和字体的系统版本之间快速切换family ,如果已安装(可能值得注意的是,它的渲染与嵌入的 SVG 字体略有不同,但也可以正确缩放)

这种行为在所有经过测试的浏览器中都是一致的(Opera-latest for Windows 7 64bit、Mozilla-Latest Linux Ubuntu 14、Chrome-latest Windows 7/8 64bit、Safari 5.1.7 for Windows(支持 SVG 字体)和 PhantomJS 1.9.7 Linux CentOS 6.4 最终版(支持 SVG 字体)。它在所有测试的字体(许多...)和字体转换引擎(squirrel-font、FontForge、Birdfont...)中也是一致的

由于自包含的 SVG 太大而无法粘贴到正文中,这里有一个粘贴到 JSfiddle 项目中的链接

是的,我确实意识到我可以通过使用 Apache batik 进行渲染来解决这个问题,但是:1) Batik 太慢了。Sooooo slooooooooooooooooooooooooooooow ... OMG 是不是很慢。2)我希望能够从我的服务器上卸载尽可能多的 CPU 负载,这与蜡染会做的完全相反 3)这不是重点,该死!

1个回答

我经常使用 SVG,因为我是一名网页设计师。如果我想保持文本的形状(字体样式),我打开 Adob​​e Illustrator,写下我想要的内容并从中“创建轮廓”。这不是那么耗时,只需确保在大纲之前复制文本以保持可编辑的版本。