Canvas beginPath与closePath详解,掌握路径的开始和闭合操作。beginPath和closePath是路径操作中最基础也最重要的两个方法。理解它们的作用是正确绑制图形的前提。
beginPath创建一个新的路径,并清除之前的路径数据:
const canvas = document.getElementById('canvas')
const ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.moveTo(50, 50)
ctx.lineTo(150, 50)
ctx.stroke()
看一个常见错误:
// 错误示例
ctx.moveTo(50, 50)
ctx.lineTo(100, 100)
ctx.stroke()
ctx.lineTo(200, 50)
ctx.stroke()
结果会从(100,100)画线到(200,50),因为路径没有重置。
正确做法:
ctx.beginPath()
ctx.moveTo(50, 50)
ctx.lineTo(100, 100)
ctx.stroke()
ctx.beginPath() // 重新开始
ctx.moveTo(100, 100)
ctx.lineTo(200, 50)
ctx.stroke()
closePath将路径的终点连接到起点,形成封闭图形:
ctx.beginPath()
ctx.moveTo(100, 50)
ctx.lineTo(50, 150)
ctx.lineTo(150, 150)
ctx.closePath() // 自动连接到(100, 50)
ctx.stroke()
// 方式1:手动闭合
ctx.beginPath()
ctx.moveTo(100, 50)
ctx.lineTo(50, 150)
ctx.lineTo(150, 150)
ctx.lineTo(100, 50) // 手动回到起点
ctx.stroke()
// 方式2:使用closePath
ctx.beginPath()
ctx.moveTo(100, 50)
ctx.lineTo(50, 150)
ctx.lineTo(150, 150)
ctx.closePath() // 自动闭合
ctx.stroke()
两种方式视觉效果相同,但closePath更简洁。
fill会自动闭合路径:
ctx.beginPath()
ctx.moveTo(100, 50)
ctx.lineTo(50, 150)
ctx.lineTo(150, 150)
// 没有closePath
ctx.fill() // 自动闭合并填充
但stroke不会自动闭合:
ctx.beginPath()
ctx.moveTo(100, 50)
ctx.lineTo(50, 150)
ctx.lineTo(150, 150)
// 没有closePath
ctx.stroke() // 不会闭合,显示开口三角形
// 推荐的路径绑制模式
function drawShape(ctx) {
ctx.beginPath()
// 定义路径
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
ctx.lineTo(x3, y3)
ctx.closePath()
// 设置样式
ctx.fillStyle = '#3498db'
ctx.strokeStyle = '#2980b9'
ctx.lineWidth = 2
// 渲染
ctx.fill()
ctx.stroke()
}
beginPath不会清除样式
ctx.strokeStyle = '#e74c3c'
ctx.beginPath()
ctx.moveTo(50, 50)
ctx.lineTo(100, 100)
ctx.stroke()
ctx.beginPath() // 只清除路径,不清除样式
ctx.moveTo(100, 50)
ctx.lineTo(150, 100)
ctx.stroke() // 仍然是红色
closePath不是必须的
// 绑制开放路径(如折线图)
ctx.beginPath()
ctx.moveTo(50, 50)
ctx.lineTo(100, 80)
ctx.lineTo(150, 60)
ctx.lineTo(200, 90)
ctx.stroke() // 不需要closePath
两条线使用相同的样式,因为样式在beginPath之前设置