Canvas仅使用fabric.js在click事件上呈现自定义webfont

Don*_*nMB 13 javascript canvas fabricjs

我对自定义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();
Run Code Online (Sandbox Code Playgroud)

只有当我点击画布上的iText并与之互动时,这才有效.然后,一旦加载了字体,它就不再是问题了.问题是最初和第一次添加iText.

我研究了很多并且来到这个主题:

在Fabric.js中使用远程Web字体初始化加载的文本

但这对我没有帮助.提供的jsfiddle有完全相同的问题:

http://jsfiddle.net/vvL6f/6/

只需使用带有清除缓存的全新浏览器(例如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;
}
Run Code Online (Sandbox Code Playgroud)

小智 14

@Prominic答案几乎就在那里.我还有一个使用Fabric的自定义字体的画布应用程序.我像你一样在CSS中加载所有字体.问题是,仅@font-face在样式表中声明是不够的.除非在文档中使用,否则浏览器不会请求字体文件.在初始化画布之前,您必须确保加载并应用webfont.这可以通过一些工作来实现,我将通过下面的示例来说明这一点.缺点是您可能需要预加载应用程序可供用户使用的所有字体.


  1. 声明你的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;
}
Run Code Online (Sandbox Code Playgroud)

额外提示:如果您在应用程序中使用斜体和/或粗体,如果您希望在不同浏览器中获得一致的结果,建议您将这些样式的字体面添加为weel.例如,Android Browser 4.2无法计算字体的斜体,并将正常显示.

  1. 强制请求字体文件

如上所述,您需要实际使用DOM中的字体来强制加载字体.只需添加带有一些文本的div并使用您的字体设置样式就足够了:

<div style="font-family:'ApolloASM'">&nbsp;</div>
Run Code Online (Sandbox Code Playgroud)

额外提示:不要忘记添加斜体和粗体变体

  1. 在DOM 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();
})
Run Code Online (Sandbox Code Playgroud)

额外提示:您可以将这些字体包装<div>在另一个字体中,并在DOM load事件之后将其删除,以避免破坏您可能具有的任何布局.

  • 你刚刚把我从头痛中解救出来.. + 1 (2认同)

ptC*_*der 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();
Run Code Online (Sandbox Code Playgroud)

小提琴: http: //jsfiddle.net/vvL6f/107/