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 计算半径 |
| 颜色数组 | 循环使用不同颜色 |