class Curve {
constructor({x, y, radiusX, radiusY, borderRadius, position}) {
const kappa = 4 * ((Math.sqrt(2) - 1) / 3);
const ox = borderRadius * kappa; // control point offset horizontal
const oy = borderRadius * kappa; // control point offset vertical
const xm = x + borderRadius; // x-middle
const ym = y + borderRadius; // y-middle
switch(position) {
case 'leftTop':
this.startx = x;
this.starty = ym;
this.cp1x = x;
this.cp1y = ym - oy;
this.cp2x = xm - ox;
this.cp2y = y;
this.x = xm;
this.y = y;
break;
case 'rightTop':
this.startx = x - borderRadius;
this.starty = y;
this.cp1x = x - borderRadius + ox;
this.cp1y = y;
this.cp2x = x;
this.cp2y = ym - oy;
this.x = x;
this.y = ym;
break;
case 'rightBottom':
this.startx = x;
this.starty = y - borderRadius;
this.cp1x = x;
this.cp1y = y - borderRadius + oy;
this.cp2x = x - borderRadius + ox;
this.cp2y = y;
this.x = x - borderRadius;
this.y = y;
break;
case 'leftBottom':
this.startx = xm;
this.starty = y;
this.cp1x = xm - ox;
this.cp1y = y;
this.cp2x = x;
this.cp2y = y - borderRadius + oy;
this.x = x;
this.y = y - borderRadius;
break;
}
}
}
export const ellipse = ({x, y, radiusX, radiusY, borderRadius, ctx}) => {
const curves = [
new Curve({
x: x - radiusX,
y: y - radiusY,
radiusX,
radiusY,
borderRadius,
position: 'leftTop'
}),
new Curve({
x: x + radiusX,
y: y - radiusY,
radiusX,
radiusY,
borderRadius,
position: 'rightTop'
}),
new Curve({
x: x + radiusX,
y: y + radiusY,
radiusX,
radiusY,
borderRadius,
position: 'rightBottom'
}),
new Curve({
x: x - radiusX,
y: y + radiusY,
radiusX,
radiusY,
borderRadius,
position: 'leftBottom'
}),
]
curves.forEach((curve, index) => {
if (index === 0) {
ctx.moveTo(curve.startx, curve.starty);
} else {
ctx.lineTo(curve.startx, curve.starty);
}
ctx.bezierCurveTo(curve.cp1x, curve.cp1y, curve.cp2x, curve.cp2y, curve.x, curve.y);
});
}
// 绘制椭圆
ellipse({
x: 100,
radiusX: 50,
radiusY: 20,
borderRadius: 12,
ctx: wx.createCanvasContext('screenCanvas')
})
本文来自网易实践者社区,经作者江云唬授权发布。