当前位置:首页 > 前端开发 > 正文

如何用HTML5画布绘制椭圆?

在 HTML5画布中绘制椭圆可通过两种方法实现:1)使用 ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle)方法直接绘制;2)通过缩放圆形路径:先绘制正圆,再用 scale()水平/垂直缩放形成椭圆,后者需配合 save()/ restore()管理状态。

在HTML5 Canvas中绘制椭圆需要一些技巧,因为Canvas API没有直接提供ellipse()方法(直到Canvas Path2D的加入),以下是三种可靠的方法,附详细代码示例:

如何用HTML5画布绘制椭圆? 第1张

如何用HTML5画布绘制椭圆? 第2张

方法1:使用缩放变换(推荐)

<canvas id="myCanvas" width="400" height="300"></canvas> <script> const canvas = document.getElementById('myCanvas'); const ctx = canvas.getContext('2d'); function drawEllipse(x, y, radiusX, radiusY, rotation = 0) { ctx.save(); // 保存当前画布状态 ctx.translate(x, y); // 平移至椭圆中心 ctx.rotate(rotation); // 旋转(弧度制) ctx.scale(radiusX, radiusY); // 缩放坐标系 ctx.beginPath(); ctx.arc(0, 0, 1, 0, Math.PI * 2); // 绘制单位圆 ctx.restore(); // 恢复原始坐标系 ctx.stroke(); } // 示例:绘制椭圆 (中心点x=200,y=150, 水平半径80, 垂直半径50, 旋转30度) drawEllipse(200, 150, 80, 50, Math.PI/6); </script>

原理:通过缩放坐标系将圆形变形为椭圆,需配合save()/restore()避免影响后续绘制。

如何用HTML5画布绘制椭圆? 第3张

方法2:贝塞尔曲线逼近

function drawEllipseBezier(x, y, radiusX, radiusY) { const kappa = 0.5522848; // 贝塞尔曲线控制点系数 const ox = radiusX * kappa; const oy = radiusY * kappa; ctx.beginPath(); ctx.moveTo(x, y - radiusY); ctx.bezierCurveTo( x + ox, y - radiusY, x + radiusX, y - oy, x + radiusX, y ); ctx.bezierCurveTo( x + radiusX, y + oy, x + ox, y + radiusY, x, y + radiusY ); ctx.bezierCurveTo( x - ox, y + radiusY, x - radiusX, y + oy, x - radiusX, y ); ctx.bezierCurveTo( x - radiusX, y - oy, x - ox, y - radiusY, x, y - radiusY ); ctx.stroke(); }

方法3:使用Path2D对象(现代浏览器)

// 创建椭圆Path2D对象 const ellipse = new Path2D(); ellipse.ellipse(200, 150, 80, 50, Math.PI/4, 0, Math.PI*2); // 绘制 ctx.stroke(ellipse); ctx.fillStyle = '#FF9800'; ctx.fill(ellipse);

参数说明:ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle)


关键注意事项

  1. 坐标系影响:缩放法会同时缩放线条宽度,需在缩放前调整线宽
  2. 性能优化:贝塞尔曲线法在动画中性能较差,静态图形可用
  3. 浏览器兼容性
    • Path2D支持:Chrome 55+、Firefox 52+、Edge 79+
    • 传统方法支持所有Canvas浏览器
  4. 填充与描边:所有方法都支持fill()和stroke()

完整示例(缩放法优化版)

<canvas id="demoCanvas" width="500" height="400"></canvas> <script> const canvas = document.getElementById('demoCanvas'); const ctx = canvas.getContext('2d'); function drawEllipse(x, y, rx, ry, color, rotation = 0) { ctx.save(); ctx.translate(x, y); ctx.rotate(rotation); ctx.scale(rx, ry); ctx.lineWidth = 1 / Math.max(rx, ry) * 2; // 线宽自适应 ctx.beginPath(); ctx.arc(0, 0, 1, 0, Math.PI * 2); ctx.restore(); ctx.strokeStyle = color; ctx.stroke(); } // 绘制三个不同椭圆 drawEllipse(100, 100, 70, 40, 'blue'); drawEllipse(300, 200, 100, 60, 'red', Math.PI/4); drawEllipse(400, 300, 50, 80, '#0a0'); </script>

引用说明

提示:对于复杂场景,推荐使用Path2D + 变换矩阵的组合方案,可在实现效果的同时保持代码可维护性,实际开发中建议封装为可复用的椭圆绘制函数。

0