我的自定义webfonts和fabric.js一直存在问题。 我的应用程序使用了很多自定义webfonts,我在向画布添加iText时启动它们:
var text = new fabric.IText("My Text", {
fontFamily: "Some Custom Font Family",
fontSize: 50,
top: 0,
left: 0,
fill: "#000000"
});
canvas.add(text);
canvas.bringToFront(text);
canvas.setActiveObject(text);
canvas.renderAll();
只有当我点击画布上的iText并与之互动时才有效。然后,一旦加载了字体,它就不再是问题了。问题是最初和第一次添加iText。
我研究了很多并且来到这个主题:
Init loaded text with remote web font in Fabric.js
但这对我没有帮助。 jsfiddle提供了完全相同的问题:
使用已清除缓存的全新浏览器(例如Chrome CMD + Shift + R)打开此小提琴。一旦打开小提琴,您将看到自定义的webfont未加载,但是当您单击右侧的iText时会立即加载。
现在,我们如何解决这个问题?
建议的方法是将useNative
设置为false,让Cufon渲染文本,但这不起作用。
我将我的webfonts加载到这样的CSS文件中:
@font-face {
font-family: 'ApolloASM';
src: url('ApolloASM-webfont.eot');
src: url('ApolloASM-webfont.eot?#iefix') format('embedded-opentype'),
url('ApolloASM-webfont.woff2') format('woff2'),
url('ApolloASM-webfont.woff') format('woff'),
url('ApolloASM-webfont.ttf') format('truetype'),
url('ApolloASM-webfont.svg#apollo_asmregular') format('svg');
font-weight: normal;
font-style: normal;
}
答案 0 :(得分:14)
@font-face
是不够的。除非在文档中使用,否则浏览器不会请求字体文件。 您必须确保在初始化画布之前加载并应用webfont。这可以通过一些工作来实现,我将通过下面的示例来说明这一点。缺点是您可能需要预加载应用程序可供用户使用的所有字体。
@font-face
语句。只需确保它已加载到<head>
部分。让我们用你的例子: @font-face {
font-family: 'ApolloASM';
src: url('ApolloASM-webfont.eot');
src: url('ApolloASM-webfont.eot?#iefix') format('embedded-opentype'),
url('ApolloASM-webfont.woff2') format('woff2'),
url('ApolloASM-webfont.woff') format('woff'),
url('ApolloASM-webfont.ttf') format('truetype'),
url('ApolloASM-webfont.svg#apollo_asmregular') format('svg');
font-weight: normal;
font-style: normal;
}
奖金提示:如果您在应用中使用斜体和/或粗体,建议您在不同浏览器中使用一致的结果时,为这些样式添加字体 - 面。例如,Android Browser 4.2无法计算字体的斜体,并将正常显示。
如上所述,您需要实际使用DOM中的字体来强制加载字体。只需添加带有一些文本的div并使用您的字体设置样式就足够了:
<div style="font-family:'ApolloASM'"> </div>
奖金提示:不要忘记添加斜体和粗体变体
load
事件后初始化FabricJS Canvas 在浏览器加载字体后,您需要同步canvas init(或至少文本添加),否则您可能会看到FOUT效果(无格式文本的Flash)。幸运的是,在加载所有字体文件之前,浏览器不会触发load
事件,这可以用来安全地将样式文本添加到画布:
window.addEventListener('load', function onLoad() {
var canvas = new Fabric.Canvas({...});
var text = new fabric.Text("Web Font Example", {
left: 200,
top: 30,
fontFamily: 'ApolloASM',
fill: '#000',
fontSize: 60
});
canvas.add(text);
canvas.renderAll();
})
奖励提示:您可以将这些字体<div>
包装在另一个字体中,并在DOM load
事件后将其删除,以避免破坏您可能拥有的任何布局。
答案 1 :(得分:4)
您可以使用网络字体加载器。
<script src="//ajax.googleapis.com/ajax/libs/webfont/1.5.18/webfont.js"> </script>
<script>
var c = new fabric.Canvas('canvas');
WebFont.load({
google: {
families: ['Fredoka One']
},
active: function() {
var text = new fabric.IText('Hello world !', {
fontFamily: 'Fredoka One',
top: 100,
left: 100,
fontSize: 20
});
c.add(text);
},
});
</script>
JSFiddle here。
答案 2 :(得分:1)
当您的脚本首次渲染画布时,Webfont尚未加载。
我说最好的执行方法是使用HTML标记加载webfont。这将在DOM的顶部加载字体,以便在浏览器呈现时为您的画布脚本准备好字体。这是一个例子。
https://jsfiddle.net/j47k79e8/1/
<link href='http://fonts.googleapis.com/css?family=Ranchers' rel='stylesheet' type='text/css'>
虽然如果您仍想使用Javascript方法加载webfont,您可以在运行FabricJS脚本之前等待加载文档。只需将其包装在文档就绪声明中即可。
$(document).ready(function(){
// FabricJS scripts
});
答案 3 :(得分:0)
您只需在插入文本后插入canvas.renderAll();
命令,如下所示:
canvas = new fabric.Canvas('c');
var text = new fabric.Text("Web Font Example", {
left: 200,
top: 30,
fontFamily: 'Ranchers',
fill: '#000',
fontSize: 60
});
canvas.add(text);
canvas.renderAll();
答案 4 :(得分:0)
回答@Bernardo Domingues对我不好,因为我edit databases
有超过500种字体,我不想因为交通限制而预加载所有字体。
所以我通过每500ms重复调用<select>
方法解决了这个问题。一次又一次。这种方式我将字体更改为新的(尚未被浏览器加载) - 首先它将被浏览器下载(我不知道,我不在乎需要花多少时间)。一旦加载了新的字体 - 我的代码将在500毫秒内更新整个画布并瞧!我的字体也更新了:)