Canvas提供了两种文本渲染方式:填充文本和描边文本,支持丰富的字体样式设置。Canvas文本绘制完整教程,掌握文本渲染、字体设置、文本测量等核心功能。
| 方法 | 说明 |
|---|---|
| fillText(text, x, y, maxWidth) | 绘制填充文本 |
| strokeText(text, x, y, maxWidth) | 绘制描边文本 |
| measureText(text) | 测量文本宽度 |
| 属性 | 类型 | 说明 |
|---|---|---|
| font | string | 字体样式 |
| textAlign | string | 水平对齐方式 |
| textBaseline | string | 垂直对齐方式 |
| direction | string | 文本方向 |
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
// 设置字体
ctx.font = '30px Arial'
// 填充文本
ctx.fillStyle = '#3498db'
ctx.fillText('Hello Canvas', 50, 50)
// 描边文本
ctx.strokeStyle = '#e74c3c'
ctx.lineWidth = 2
ctx.strokeText('Hello Canvas', 50, 100)
font属性使用CSS字体语法:
// 完整语法: font-style font-weight font-size font-family
ctx.font = 'italic bold 24px Arial'
ctx.fillText('斜体粗体', 50, 50)
ctx.font = 'normal 400 20px "Microsoft YaHei"'
ctx.fillText('正常字重', 50, 100)
ctx.font = 'bold 28px Georgia, serif'
ctx.fillText('衬线字体', 50, 150)
textAlign控制文本水平对齐:
| 值 | 说明 |
|---|---|
| left | 左对齐 |
| center | 居中对齐 |
| right | 右对齐 |
| start | 起始对齐(根据文本方向) |
| end | 结束对齐(根据文本方向) |
ctx.font = '20px Arial'
// 绘制参考线
ctx.strokeStyle = '#bdc3c7'
ctx.beginPath()
ctx.moveTo(200, 0)
ctx.lineTo(200, 200)
ctx.stroke()
ctx.textAlign = 'left'
ctx.fillText('左对齐', 200, 50)
ctx.textAlign = 'center'
ctx.fillText('居中对齐', 200, 100)
ctx.textAlign = 'right'
ctx.fillText('右对齐', 200, 150)
textBaseline控制文本垂直对齐:
| 值 | 说明 |
|---|---|
| top | 文本顶部对齐 |
| hanging | 悬挂基线 |
| middle | 文本中部对齐 |
| alphabetic | 字母基线(默认) |
| ideographic | 表意文字基线 |
| bottom | 文本底部对齐 |
ctx.font = '20px Arial'
// 绘制参考线
ctx.strokeStyle = '#bdc3c7'
ctx.beginPath()
ctx.moveTo(0, 100)
ctx.lineTo(400, 100)
ctx.stroke()
ctx.textBaseline = 'top'
ctx.fillText('top', 50, 100)
ctx.textBaseline = 'middle'
ctx.fillText('middle', 150, 100)
ctx.textBaseline = 'alphabetic'
ctx.fillText('alphabetic', 250, 100)
measureText方法返回文本的测量信息:
ctx.font = '24px Arial'
const text = 'Hello Canvas'
const metrics = ctx.measureText(text)
console.log(metrics.width) // 文本宽度
fillText和strokeText的第四个参数限制最大宽度:
ctx.font = '24px Arial'
// 无限制
ctx.fillText('Hello Canvas', 50, 50)
// 限制宽度为100px(文本会被压缩)
ctx.fillText('Hello Canvas', 50, 100, 100)
// 限制宽度为200px
ctx.fillText('Hello Canvas', 50, 150, 200)
ctx.font = '36px Arial'
ctx.shadowColor = 'rgba(0, 0, 0, 0.5)'
ctx.shadowBlur = 5
ctx.shadowOffsetX = 3
ctx.shadowOffsetY = 3
ctx.fillStyle = '#3498db'
ctx.fillText('阴影文本', 50, 100)
const gradient = ctx.createLinearGradient(0, 0, 200, 0)
gradient.addColorStop(0, '#e74c3c')
gradient.addColorStop(0.5, '#f39c12')
gradient.addColorStop(1, '#2ecc71')
ctx.font = '40px Arial'
ctx.fillStyle = gradient
ctx.fillText('渐变文本', 50, 100)
字体加载
// 确保字体加载完成
document.fonts.ready.then(function() {
ctx.font = '24px "Custom Font"'
ctx.fillText('自定义字体', 50, 50)
})
多行文本
// Canvas不支持自动换行,需要手动处理
const lines = ['第一行文本', '第二行文本', '第三行文本']
ctx.font = '20px Arial'
lines.forEach((line, index) => {
ctx.fillText(line, 50, 50 + index * 30)
})
文本换行函数
function wrapText(ctx, text, x, y, maxWidth, lineHeight) {
const words = text.split('')
let line = ''
let testLine = ''
let lineCount = 0
for (let i = 0; i < words.length; i++) {
testLine = line + words[i]
const metrics = ctx.measureText(testLine)
if (metrics.width > maxWidth && i > 0) {
ctx.fillText(line, x, y + lineCount * lineHeight)
line = words[i]
lineCount++
} else {
line = testLine
}
}
ctx.fillText(line, x, y + lineCount * lineHeight)
}