canvas文字的渲染问题
1.简单的文字绘制,包括文字的一些样式的设置
canvas的默认字体是 ‘10px sans-serif’
我们可以通过如下语句进行文字的设置
const fonts=‘bold italic’ //倾斜加粗
const name=‘宋体’
const size=‘14’
const text=‘canvas总结’
const ctx = document.getElementById("canvas").getContext("2d");
ctx.save()
ctx.beginPath()
ctx.font = `${fonts} ${size}pt "${name}"`//设置字体大小名称倾斜加粗
ctx.textAlign = "left" || "right" || "center" || "start" || "end"//文本对齐的样式
ctx.textBaseline = "top" || "hanging" || "middle" || "alphabetic" || "ideographic" || "bottom";//设置字体基线对齐样式
ctx.fillStyle = '#000'//设置字体颜色
ctx.measureText(text);//可以测量文字的宽度
ctx.direction = "ltr" || "rtl" || "inherit";//设置文本的绘制方向,从左到右,从右到左,继承
ctx.fillText(text, 0, 100)//数字指的是位置信息,在那个位置绘制文字
ctx.strokeText("Hello world", 0, 100);//绘制空心的文字
ctx.restore()
2.文字的旋转问题
可以参考这个https://blog.csdn.net/a460550542/article/details/122062840
//水平文字的绘制
const ctx = document.getElementById("canvas").getContext("2d");
ctx.fillStyle='green'
ctx.fillText('canvas总结',100,100)
ctx.save()
ctx.translate(100,100)//旋转点为正常绘制水平文字的起始点为旋转中心
ctx.rotate((90 * Math.PI) / 180)//设置旋转角度
ctx.fillStyle='red'
ctx.fillText('canvas总结',0,0)
ctx.restore()
//以中心点为旋转中心
let strWidth=ctx.measureText('canvas总结').width
ctx.save()
ctx.translate(100+strWidth/2,100-strWidth/2)//旋转点为正常绘制水平文字的起始点为旋转中心
ctx.rotate((90 * Math.PI) / 180)//设置旋转角度
ctx.fillStyle='blue'
ctx.fillText('canvas总结',0,0)
ctx.restore()
3.canvas远程字体加载
加载远程字体可采用css字体加载API :new FontFace('test', 'url(x)').onload()或者fontfaceobserver第三方字体加载优化方案,此处以第三方的为例
import FontFaceObserve from 'fontfaceobserver'
import { difference, isMatch } from 'lodash-es'
const fontPrevRef = useRef<any>()
const fontFaces =['宋体','微软雅黑','幼圆']
const isResolved = isMatch(fontPrevRef.current, fontFaces || [])
if ( fontFaces?.length) {
//已经加载过的字体没必要再加载一次,过滤出不同的字体
const dif = difference(fontFaces, fontPrevRef.current)
let observers
if (dif.length) {
observers = dif.map(item => {
return new FontFaceObserve(item).load()
})
} else {
//初始情况会有个默认字体
observers = fontFaces.map(item => {
return new FontFaceObserve(item).load()
})
}
Promise.allSettled(observers).then(res => {
if (res) {
//去渲染字体
}
})
fontResolved = observers.length > 0
}
fontPrevRef.current = fontFaces