绘制椭圆

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()

// 正圆(rx=ry)
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()

// 旋转30度
ctx.beginPath()
ctx.ellipse(170, 100, 40, 20, Math.PI / 6, 0, Math.PI * 2)
ctx.fillStyle = '#3498db'
ctx.fill()

// 旋转45度
ctx.beginPath()
ctx.ellipse(270, 100, 40, 20, Math.PI / 4, 0, Math.PI * 2)
ctx.fillStyle = '#2ecc71'
ctx.fill()

// 旋转90度
ctx.beginPath()
ctx.ellipse(370, 100, 40, 20, Math.PI / 2, 0, Math.PI * 2)
ctx.fillStyle = '#f39c12'
ctx.fill()
</script>

代码解析

角度弧度值效果
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 {
  // 使用scale模拟椭圆
  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()
}