文本绘制

Canvas提供了两种文本渲染方式:填充文本和描边文本,支持丰富的字体样式设置。Canvas文本绘制完整教程,掌握文本渲染、字体设置、文本测量等核心功能。

文本绘制方法

方法说明
fillText(text, x, y, maxWidth)绘制填充文本
strokeText(text, x, y, maxWidth)绘制描边文本
measureText(text)测量文本宽度

文本属性

属性类型说明
fontstring字体样式
textAlignstring水平对齐方式
textBaselinestring垂直对齐方式
directionstring文本方向

基本文本绘制

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)
}