如何判断应用@ font-face规则的时间

时间:2009-11-30 01:36:26

标签: javascript processing.js processing

有什么方法可以判断何时应用@ font-face规则?我正在创建使用数据的@ font-face规则:来自在JavaScript中使用同步XMLHttpRequest请求的字体文件中的URI,然后立即使用该字体将文本写入canvas元素。事实是,在最初的几毫秒内绘制文本时,它实际上并没有使用字体。我目前的解决方案是通过发送同步XMLHttpRequest来阻止执行几毫秒,这是一个糟糕的解决方案。

我不能将此异步,因为它是Processing中实现Processing.js loadFont()函数的同步函数。

我希望解决方案不检查字符的尺寸,因为不能保证字体具有某个字符,并且其尺寸与当前字体的相同字符不同。

2 个答案:

答案 0 :(得分:1)

即使您不喜欢维度检查,Modernizr @font-face功能检测的工作原理也可能是最佳方式:

  

Modernizr嵌入了一个很小的字体字形   使用数据:URI。在此,单身   “”字符被创建;就是这样   适用于临时元素   innerHTML设置为'........'和   测量其宽度,首先用a   基本的衬线字体然后用   应用自定义字体。如果宽度是   不同,我们知道浏览器   渲染了我们的新字体数据   提供。

答案 1 :(得分:1)

简短回答:浏览器尚不足以让我们在没有实际使用字体并验证它的情况下测试“已加载并可以使用”。

答案很长:Pjs带有一个用于字体预加载的内置字体验证器(与https://github.com/pomax/font.js相关)但是正如您所指出的那样,这对于使用data-uri的@ font-face规则不起作用。我建议的一种解决方法(虽然我还没有尝试过这个。我只是猜测它可以根据我在Processing.js和浏览器中的字体加载的工作而工作)是使用两个PGraphic屏幕外缓冲区。使它们都是黑色填充文本的白色背景,在第一个缓冲区上执行文本(“X”,0,0),然后在字体加载后,使用第二个缓冲区执行相同的文本(“X”,0, 0“)。抓住每个缓冲区的像素[],并进行并排比较:

boolean verifyFontLoad() {
  buffer1.loadPixels();
  buffer2.loadPixels();
  for (int i=0; i<buffer1.pixels.length; i++) {
    if (buffer1.pixels[i] != buffer2.pixels[i]) {
      return false; }}
  return true;
}

当你加载你的字体时,在一个指示字体加载状态的某个地方有一个跟踪布尔值,在“false”之后加载,并且在加载你的字体后,在draw()调用开始时调用

void draw() {
  // code that does not rely on your font
  [...]

  // check state
  if(!fontLoaded) { fontLoaded = verifyFontLoaded(); }
  // not ready? "stop" drawing.
  if(!fontLoaded) { return; }
  // font ready. run code that relies on the font being ready
  else {
    // code that depends on your font being available goes here.
  }
}

现在至少你可以避免浏览器完成解包你的data-uri字体并将其作为@ font-face资源加载的前几帧,但是没有时间将它传递给Canvas2D渲染系统爱好。

(此时使用字体设置DOM元素的样式实际上可以正常工作,它实际上是将它移交给Canvas2D导致它无法使用一个或多个帧)