zhangxinxu/quiz

DOM基础测试45期

Opened this issue · 7 comments

有一个自定义字体文件,地址是:../static/font/lota.woff2

现在,我们需要使用这个字体在Canvas画布上绘制一段文字,但是,如果这个字体还没有加载完毕的话,Canvas中使用fillText()方法绘制的文字是默认字体。

请实现:加载该字体文件,并准确判断字体加载成功的时机


大家提交回答的时候,注意缩进距离,起始位置从左边缘开始;另外,github自带代码高亮,所以请使用下面示意的格式。

```js
// 你的JS代码写在这里
 ```

其他
本期小测没有直播,也没有打分,但是会反馈要点。

实在没什么想法遂去查了资料,发现一个完全面生的 API ,document.fonts ,自己浏览器里实验了下默认字体正常可用,外部引用字体正常可用

Demo

还不太熟悉这个 API 的全部用法,所以目前我的办法是如果要引入字体的话,要先在 css 引入字体,然后再执行如下代码,不知道是否符合题意

    @font-face {
      font-family: 'lota';
      src: url('../static/font/lota.woff2');
      font-weight: normal;
      font-style: normal;
    }
  document.fonts.load('50px lota').then(val => {
    console.log('success')
    var ctx = document.getElementById("canvas").getContext("2d");
    ctx.fillStyle = "red";
    ctx.font = "50px lota";
    ctx.fillText("Hello!", 100, 100);
  }).catch(err => {
    console.log('faild')
    console.error(err)
  })

DEMO

const webfont = new FontFace(
  'webfont',
  'url(//at.alicdn.com/t/webfont_sq70rrfeoea.woff)'
)

webfont
  .load()
  .then(font => {
    document.fonts.add(font)
  })
  .then(() => {
    const cvs = document.querySelector('canvas')
    const ctx = cvs.getContext('2d')
    ctx.font = '30px webfont'
    ctx.fillText('执子之手', 50, 50)
  })
<canvas id="canvas"></canvas>

jsbin

:root {
  font-family: 'iconfont';
}
<canvas id="canvas"></canvas>
// 我在ie10上面尝试也成功了
var oReq = new XMLHttpRequest()
oReq.open('get', 'https://liyongleihf2006.github.io/main-bg/iconfont.woff')
oReq.responseType = 'blob'
oReq.addEventListener('load', function () {
  var url = URL.createObjectURL(this.response);
  var style = document.createElement("style");
  style.type = "text/css";
  var str = '@font-face{font-family: "iconfont";src: url(' + url + ') format("woff")}'
  style.appendChild(document.createTextNode(str))
  document.head.appendChild(style)
  setTimeout(function () {
    var ctx = document.getElementById("canvas").getContext("2d");
    ctx.font = "50px iconfont";
    ctx.fillText("\ue63b", 100, 100);
    // 我将chrome浏览器设置为disable cache ,将网络设置为 slow 3G,尝试了200遍,渲染在我的机器上面都成功了
  }, 17)
})
oReq.send()

既然没说兼容性,那我就姑且使用CSS Font Loading这个比较新的语法了;

@font-face {
  font-family: "Custom";
  src: url("../static/font/lota.woff2") format("woff2");
}
let fontLoaded = false // 字体是否加载完毕
document.fonts.load("20px Custom").then(res => { // 使用document.fonts.load方法加载字体,返回一个promise对象,resolved则代表字体加载完成
  fontLoaded = true
  // ...
}).catch(err => {
  console.log(err)
})
document.fonts.load("字体").then(res => {
  //处理加载好的逻辑
}).catch(err => {
  console.log(err)
})

没错,本题考点就是很简单的一个API ,document.fonts.load方法。

只知道 有一个 webfont loader 的库可以实现这个