绘制直线

Canvas绑制直线详解,包括moveTo、lineTo绑制直线、折线、虚线、箭头的方法,包含多个交互式案例。 直线是最基本的图形元素,通过moveTo和lineTo方法可以绑制各种线条。

基本方法

方法作用
moveTo(x, y)移动画笔到指定位置
lineTo(x, y)从当前位置画线到指定位置
stroke()描边路径

案例一:基本直线

不同样式的直线

代码实现

<canvas id="myCanvas" width="400" height="200"></canvas>

<script>
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')

// 基本直线
ctx.beginPath()
ctx.moveTo(30, 30)
ctx.lineTo(370, 30)
ctx.strokeStyle = '#e74c3c'
ctx.lineWidth = 2
ctx.stroke()

// 粗线
ctx.beginPath()
ctx.moveTo(30, 60)
ctx.lineTo(370, 60)
ctx.strokeStyle = '#3498db'
ctx.lineWidth = 5
ctx.stroke()

// 圆角端点
ctx.beginPath()
ctx.moveTo(30, 90)
ctx.lineTo(370, 90)
ctx.strokeStyle = '#2ecc71'
ctx.lineWidth = 8
ctx.lineCap = 'round'
ctx.stroke()
</script>

代码解析

属性说明
lineWidth数字线条宽度
lineCapbutt平头(默认)
lineCapround圆头
lineCapsquare方头

案例二:折线与多边形

折线与多边形

代码实现

<canvas id="myCanvas" width="400" height="200"></canvas>

<script>
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')

// 折线
ctx.beginPath()
ctx.moveTo(30, 150)
ctx.lineTo(60, 50)
ctx.lineTo(90, 120)
ctx.lineTo(120, 30)
ctx.lineTo(150, 100)
ctx.strokeStyle = '#e74c3c'
ctx.lineWidth = 2
ctx.stroke()

// 多边形(闭合)
ctx.beginPath()
ctx.moveTo(200, 50)
ctx.lineTo(280, 50)
ctx.lineTo(280, 130)
ctx.lineTo(200, 130)
ctx.closePath()
ctx.strokeStyle = '#3498db'
ctx.lineWidth = 3
ctx.stroke()

// 填充多边形
ctx.beginPath()
ctx.moveTo(340, 30)
ctx.lineTo(380, 80)
ctx.lineTo(360, 150)
ctx.lineTo(320, 150)
ctx.lineTo(300, 80)
ctx.closePath()
ctx.fillStyle = '#2ecc71'
ctx.fill()
</script>

代码解析

方法说明
多个lineTo绘制折线
closePath()闭合路径
stroke()描边
fill()填充

案例三:虚线

不同样式的虚线

代码实现

<canvas id="myCanvas" width="400" height="200"></canvas>

<script>
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')

// 基本虚线
ctx.beginPath()
ctx.setLineDash([10, 5])
ctx.moveTo(30, 40)
ctx.lineTo(370, 40)
ctx.strokeStyle = '#e74c3c'
ctx.lineWidth = 2
ctx.stroke()

// 点划线
ctx.beginPath()
ctx.setLineDash([20, 10, 5, 10])
ctx.moveTo(30, 80)
ctx.lineTo(370, 80)
ctx.strokeStyle = '#3498db'
ctx.lineWidth = 2
ctx.stroke()

// 重置为实线
ctx.setLineDash([])
</script>

代码解析

参数说明
[实线长度, 空白长度]基本虚线模式
[长, 短, 短, 短]复杂虚线模式
setLineDash([])重置为实线

案例四:箭头

带箭头的直线

代码实现

<canvas id="myCanvas" width="400" height="200"></canvas>

<script>
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')

function drawArrow(fromX, fromY, toX, toY, color) {
  const headLength = 15
  const angle = Math.atan2(toY - fromY, toX - fromX)
  
  // 画线
  ctx.beginPath()
  ctx.moveTo(fromX, fromY)
  ctx.lineTo(toX, toY)
  ctx.strokeStyle = color
  ctx.lineWidth = 2
  ctx.stroke()
  
  // 画箭头
  ctx.beginPath()
  ctx.moveTo(toX, toY)
  ctx.lineTo(
    toX - headLength * Math.cos(angle - Math.PI / 6),
    toY - headLength * Math.sin(angle - Math.PI / 6)
  )
  ctx.lineTo(
    toX - headLength * Math.cos(angle + Math.PI / 6),
    toY - headLength * Math.sin(angle + Math.PI / 6)
  )
  ctx.closePath()
  ctx.fillStyle = color
  ctx.fill()
}

drawArrow(30, 50, 180, 50, '#e74c3c')
drawArrow(30, 100, 180, 100, '#3498db')
drawArrow(220, 30, 370, 100, '#f39c12')
</script>

代码解析

技术说明
Math.atan2计算线条角度
Math.cos/sin计算箭头顶点坐标
箭头角度π/6 = 30度

案例五:网格与坐标轴

网格与坐标轴

代码实现

<canvas id="myCanvas" width="400" height="200"></canvas>

<script>
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')

const padding = 40

// 绘制网格
ctx.strokeStyle = '#ecf0f1'
ctx.lineWidth = 1

for (let x = padding; x <= canvas.width - padding; x += 30) {
  ctx.beginPath()
  ctx.moveTo(x, padding)
  ctx.lineTo(x, canvas.height - padding)
  ctx.stroke()
}

for (let y = padding; y <= canvas.height - padding; y += 30) {
  ctx.beginPath()
  ctx.moveTo(padding, y)
  ctx.lineTo(canvas.width - padding, y)
  ctx.stroke()
}

// 绘制坐标轴
ctx.strokeStyle = '#333'
ctx.lineWidth = 2

// X轴
ctx.beginPath()
ctx.moveTo(padding, canvas.height - padding)
ctx.lineTo(canvas.width - padding, canvas.height - padding)
ctx.stroke()

// Y轴
ctx.beginPath()
ctx.moveTo(padding, padding)
ctx.lineTo(padding, canvas.height - padding)
ctx.stroke()
</script>

代码解析

步骤说明
绘制网格循环绘制水平和垂直线
绘制坐标轴X轴和Y轴
添加箭头坐标轴端点
绘制数据点使用arc绑制点