在 canvas 使用过程中,我们经常会遇到到把文字换行的情况,canvas 要实现换行,并没有 css 中使用样式换行那么方便,但 canvas 提供测量工具函数 measureText 给你测出每个文字的宽度,然后自己用它来按需切割文本为多行,然后按需把多行一行一行地绘画到 canvas 上实现换行效果。在 canvas 要实现 letter-space 也没有太好的办法,但在 stackoverflow 中,有人提出一种比较有效的近似的办法,,就是往文字间插入间隔空白符来实现 letter-space 的效果,下面一起来看看如何实现。
/**
* canvas 中如何实现文字换行?canvas 中如何实现 letter-space 效果?
*
* @param { CanvasRenderingContext2D } ctx
* @param {String} text
* @param {Number} x
* @param {Number} y
* @param {Number} w 行宽
* @param {String} color
* @param {Number} fontSize
* @param {Boolean} isBold
*/
function drawMultiLineRichText (ctx, text, x, y, w, color, fontSize, isBold) {
if (!text) {
return false
}
const rawRows = text.split('\n')
let rows = []
// 保存画布 用save及restore是为了不影响其他地方使用画布
ctx.save()
fontSize = fontSize ? fontSize : 26
ctx.font = `${isBold ? '700' : '400'} ${fontSize}px "Hiragino Sans GB W3","Microsoft YaHei",sans-serif`
ctx.textBaseline = 'middle'
ctx.fillStyle = color
rawRows.forEach((txt) => {
const chars = txt.split('').join(String.fromCharCode(8202)).split('') // .split('').join(String.fromCharCode(8202)) 增加 letter-space, 8201 可以更宽一点。 引用自: https://stackoverflow.com/questions/8952909/letter-spacing-in-canvas-element
let tempStr = ''
chars.forEach((char) => {
if (ctx.measureText(tempStr).width >= w) {
rows.push(tempStr)
tempStr = ''
}
tempStr += char
})
rows.push(tempStr)
})
rows.forEach((txt, n) => {
ctx.fillText(txt, x, y + n * fontSize * 1.8)
})
ctx.restore() // 恢复画布
}