绘制圆形

Canvas绑制圆形详解,包括arc方法绑制圆形、圆弧、扇形的方法,包含多个交互式案例。 圆形是Canvas中常用的图形,通过arc方法可以绑制圆形、圆弧和扇形。

arc方法参数

ctx.arc(x, y, radius, startAngle, endAngle, counterclockwise)
参数说明
x, y圆心坐标
radius半径
startAngle起始角度(弧度)
endAngle结束角度(弧度)
counterclockwise是否逆时针(默认false)

案例一:填充圆与描边圆

填充圆与描边圆

代码实现

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

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

// 填充圆
ctx.beginPath()
ctx.arc(80, 100, 50, 0, Math.PI * 2)
ctx.fillStyle = '#3498db'
ctx.fill()

// 描边圆
ctx.beginPath()
ctx.arc(200, 100, 50, 0, Math.PI * 2)
ctx.strokeStyle = '#e74c3c'
ctx.lineWidth = 4
ctx.stroke()

// 填充+描边
ctx.beginPath()
ctx.arc(320, 100, 50, 0, Math.PI * 2)
ctx.fillStyle = '#2ecc71'
ctx.fill()
ctx.strokeStyle = '#27ae60'
ctx.lineWidth = 4
ctx.stroke()
</script>

代码解析

步骤说明
beginPath()开始新路径
arc()定义圆形路径
fill()填充路径
stroke()描边路径

案例二:圆弧与扇形

圆弧与扇形

代码实现

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

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

// 圆弧
ctx.beginPath()
ctx.arc(70, 100, 45, 0, Math.PI * 0.75)
ctx.strokeStyle = '#e74c3c'
ctx.lineWidth = 4
ctx.stroke()

// 扇形
ctx.beginPath()
ctx.moveTo(180, 100)
ctx.arc(180, 100, 45, 0, Math.PI * 0.6)
ctx.closePath()
ctx.fillStyle = '#2ecc71'
ctx.fill()
</script>

代码解析

图形关键步骤
圆弧arc + stroke
扇形moveTo(圆心) + arc + closePath + fill

案例三:进度环

圆形进度环

代码实现

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

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

function drawProgressRing(x, y, radius, progress, color) {
  // 背景环
  ctx.beginPath()
  ctx.arc(x, y, radius, 0, Math.PI * 2)
  ctx.strokeStyle = '#ecf0f1'
  ctx.lineWidth = 8
  ctx.stroke()
  
  // 进度环
  ctx.beginPath()
  ctx.arc(x, y, radius, -Math.PI / 2, -Math.PI / 2 + progress * Math.PI * 2)
  ctx.strokeStyle = color
  ctx.lineWidth = 8
  ctx.lineCap = 'round'
  ctx.stroke()
  
  // 百分比文字
  ctx.fillStyle = '#333'
  ctx.font = 'bold 14px Arial'
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  ctx.fillText(Math.round(progress * 100) + '%', x, y)
}

drawProgressRing(100, 100, 40, 0.75, '#e74c3c')
drawProgressRing(220, 100, 40, 0.5, '#3498db')
drawProgressRing(340, 100, 40, 0.9, '#2ecc71')
</script>

代码解析

技术说明
背景环完整的灰色圆环
进度环从-π/2开始(12点方向)
lineCap: 'round'圆角端点

案例四:动态进度环

动画进度环

代码实现

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

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

let progress = 0
const targetProgress = 0.85
const centerX = 200
const centerY = 100
const radius = 60

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height)
  
  // 背景环
  ctx.beginPath()
  ctx.arc(centerX, centerY, radius, 0, Math.PI * 2)
  ctx.strokeStyle = '#ecf0f1'
  ctx.lineWidth = 12
  ctx.stroke()
  
  // 进度环
  ctx.beginPath()
  ctx.arc(centerX, centerY, radius, -Math.PI / 2, -Math.PI / 2 + progress * Math.PI * 2)
  ctx.strokeStyle = '#3498db'
  ctx.lineWidth = 12
  ctx.lineCap = 'round'
  ctx.stroke()
  
  // 百分比
  ctx.fillStyle = '#333'
  ctx.font = 'bold 24px Arial'
  ctx.textAlign = 'center'
  ctx.textBaseline = 'middle'
  ctx.fillText(Math.round(progress * 100) + '%', centerX, centerY)
  
  if (progress < targetProgress) {
    progress += 0.01
    requestAnimationFrame(draw)
  }
}

draw()
</script>

代码解析

技术说明
进度变量progress 从0增长到目标值
动画循环requestAnimationFrame
渐进增长每帧增加0.01

案例五:同心圆

同心圆图案

代码实现

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

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

const colors = ['#e74c3c', '#3498db', '#2ecc71', '#f39c12', '#9b59b6']

// 填充同心圆(从外到内)
for (let i = 5; i >= 1; i--) {
  ctx.beginPath()
  ctx.arc(100, 100, i * 15, 0, Math.PI * 2)
  ctx.fillStyle = colors[i - 1]
  ctx.fill()
}

// 描边同心圆
for (let i = 1; i <= 5; i++) {
  ctx.beginPath()
  ctx.arc(300, 100, i * 15, 0, Math.PI * 2)
  ctx.strokeStyle = colors[i - 1]
  ctx.lineWidth = 3
  ctx.stroke()
}
</script>

代码解析

技巧说明
从外到内绘制避免覆盖问题
递增半径i * 15 计算半径
颜色数组循环使用不同颜色