Canvas绑制椭圆详解,包括ellipse方法绑制椭圆、椭圆弧的方法,包含多个交互式案例。
椭圆是圆形的扩展,通过ellipse方法可以绑制各种椭圆形状。
ellipse方法参数
ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterclockwise)
| 参数 | 说明 |
|---|
| x, y | 圆心坐标 |
| radiusX | 水平半径 |
| radiusY | 垂直半径 |
| rotation | 旋转角度(弧度) |
| startAngle | 起始角度 |
| endAngle | 结束角度 |
| counterclockwise | 是否逆时针 |
案例一:基本椭圆
不同比例的椭圆
代码实现
<canvas id="myCanvas" width="400" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.ellipse(70, 100, 50, 30, 0, 0, Math.PI * 2)
ctx.fillStyle = '#e74c3c'
ctx.fill()
ctx.beginPath()
ctx.ellipse(180, 100, 30, 50, 0, 0, Math.PI * 2)
ctx.fillStyle = '#3498db'
ctx.fill()
ctx.beginPath()
ctx.ellipse(290, 100, 45, 45, 0, 0, Math.PI * 2)
ctx.fillStyle = '#2ecc71'
ctx.fill()
</script>
代码解析
| 参数 | 效果 |
|---|
| rx > ry | 水平椭圆 |
| rx < ry | 垂直椭圆 |
| rx = ry | 正圆 |
案例二:旋转椭圆
旋转角度效果
代码实现
<canvas id="myCanvas" width="400" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.ellipse(70, 100, 40, 20, 0, 0, Math.PI * 2)
ctx.fillStyle = '#e74c3c'
ctx.fill()
ctx.beginPath()
ctx.ellipse(170, 100, 40, 20, Math.PI / 6, 0, Math.PI * 2)
ctx.fillStyle = '#3498db'
ctx.fill()
ctx.beginPath()
ctx.ellipse(270, 100, 40, 20, Math.PI / 4, 0, Math.PI * 2)
ctx.fillStyle = '#2ecc71'
ctx.fill()
ctx.beginPath()
ctx.ellipse(370, 100, 40, 20, Math.PI / 2, 0, Math.PI * 2)
ctx.fillStyle = '#f39c12'
ctx.fill()
</script>
代码解析
| 角度 | 弧度值 | 效果 |
|---|
| 0° | 0 | 不旋转 |
| 30° | π/6 | 顺时针旋转30度 |
| 45° | π/4 | 顺时针旋转45度 |
| 90° | π/2 | 顺时针旋转90度 |
案例三:椭圆弧
椭圆弧与椭圆扇形
代码实现
<canvas id="myCanvas" width="400" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')
ctx.beginPath()
ctx.ellipse(70, 100, 45, 30, 0, 0, Math.PI * 0.75)
ctx.strokeStyle = '#e74c3c'
ctx.lineWidth = 4
ctx.stroke()
ctx.beginPath()
ctx.moveTo(170, 100)
ctx.ellipse(170, 100, 45, 30, 0, 0, Math.PI * 0.6)
ctx.closePath()
ctx.fillStyle = '#2ecc71'
ctx.fill()
</script>
代码解析
| 图形 | 关键步骤 |
|---|
| 椭圆弧 | ellipse + stroke |
| 椭圆扇形 | moveTo(圆心) + ellipse + closePath + fill |
案例四:椭圆动画
旋转椭圆动画
代码实现
<canvas id="myCanvas" width="400" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')
let rotation = 0
const ellipses = [
{ rx: 60, ry: 30, color: 'rgba(231, 76, 60, 0.6)' },
{ rx: 50, ry: 25, color: 'rgba(52, 152, 219, 0.6)' },
{ rx: 40, ry: 20, color: 'rgba(46, 204, 113, 0.6)' }
]
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height)
ellipses.forEach((e, i) => {
ctx.beginPath()
ctx.ellipse(200, 100, e.rx, e.ry, rotation + i * Math.PI / 3, 0, Math.PI * 2)
ctx.fillStyle = e.color
ctx.fill()
})
rotation += 0.02
requestAnimationFrame(animate)
}
animate()
</script>
代码解析
| 技术 | 说明 |
|---|
| 旋转角度 | 每帧增加0.02弧度 |
| 相位差 | i * Math.PI / 3 创建错开效果 |
| 半透明 | rgba 颜色显示重叠效果 |
案例五:椭圆图案
椭圆组成的花朵图案
代码实现
<canvas id="myCanvas" width="400" height="200"></canvas>
<script>
const canvas = document.getElementById('myCanvas')
const ctx = canvas.getContext('2d')
const centerX = 200
const centerY = 100
const petals = 8
const colors = ['#e74c3c', '#3498db', '#2ecc71', '#f39c12', '#9b59b6', '#1abc9c', '#e67e22', '#95a5a6']
for (let i = 0; i < petals; i++) {
const angle = (i / petals) * Math.PI * 2
ctx.beginPath()
ctx.ellipse(centerX, centerY, 60, 20, angle, 0, Math.PI * 2)
ctx.fillStyle = colors[i]
ctx.fill()
}
ctx.beginPath()
ctx.arc(centerX, centerY, 15, 0, Math.PI * 2)
ctx.fillStyle = '#f1c40f'
ctx.fill()
</script>
代码解析
| 技术 | 说明 |
|---|
| 花瓣数量 | 8个椭圆均匀分布 |
| 角度计算 | (i / petals) * 2π |
| 椭圆旋转 | 每个花瓣旋转不同角度 |
兼容性说明
ellipse方法是较新的API,在旧浏览器中可能不支持。兼容方案:
if (ctx.ellipse) {
ctx.ellipse(x, y, rx, ry, rotation, 0, Math.PI * 2)
} else {
ctx.save()
ctx.translate(x, y)
ctx.rotate(rotation)
ctx.scale(rx / ry, 1)
ctx.beginPath()
ctx.arc(0, 0, ry, 0, Math.PI * 2)
ctx.restore()
}