45590ce5269e3cb8abc2fbda968d6f3e4f1944af0b9a5fea20107c2c0fe13302cd9947dacc39f6e431d455f954cd6b9185e5dd272ce4f929cdb63daba5dd38 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. /**
  2. * 椭圆形状
  3. */
  4. import Path, { PathProps } from '../Path';
  5. export class EllipseShape {
  6. cx = 0
  7. cy = 0
  8. rx = 0
  9. ry = 0
  10. }
  11. export interface EllipseProps extends PathProps {
  12. shape?: Partial<EllipseShape>
  13. }
  14. class Ellipse extends Path<EllipseProps> {
  15. shape: EllipseShape
  16. constructor(opts?: EllipseProps) {
  17. super(opts);
  18. }
  19. getDefaultShape() {
  20. return new EllipseShape();
  21. }
  22. buildPath(ctx: CanvasRenderingContext2D, shape: EllipseShape) {
  23. const k = 0.5522848;
  24. const x = shape.cx;
  25. const y = shape.cy;
  26. const a = shape.rx;
  27. const b = shape.ry;
  28. const ox = a * k; // 水平控制点偏移量
  29. const oy = b * k; // 垂直控制点偏移量
  30. // 从椭圆的左端点开始顺时针绘制四条三次贝塞尔曲线
  31. ctx.moveTo(x - a, y);
  32. ctx.bezierCurveTo(x - a, y - oy, x - ox, y - b, x, y - b);
  33. ctx.bezierCurveTo(x + ox, y - b, x + a, y - oy, x + a, y);
  34. ctx.bezierCurveTo(x + a, y + oy, x + ox, y + b, x, y + b);
  35. ctx.bezierCurveTo(x - ox, y + b, x - a, y + oy, x - a, y);
  36. ctx.closePath();
  37. }
  38. }
  39. Ellipse.prototype.type = 'ellipse';
  40. export default Ellipse;