Merge pull request #18 from aha-app/feature-add-ellipse

Add ellipse support
This commit is contained in:
Zeno Zeng 2022-07-17 15:42:37 +08:00 committed by GitHub
commit b4af606473
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 0 deletions

View File

@ -1033,6 +1033,63 @@ export default (function () {
this.__currentPosition = {x: endX, y: endY};
};
/**
* Ellipse command!
*/
Context.prototype.ellipse = function(x, y, radiusX, radiusY, rotation, startAngle, endAngle, counterClockwise) {
if (startAngle === endAngle) {
return;
}
x = this.__matrixTransform(x, y).x;
y = this.__matrixTransform(x, y).y;
var scaleX = Math.hypot(this.__transformMatrix.a, this.__transformMatrix.b);
var scaleY = Math.hypot(this.__transformMatrix.c, this.__transformMatrix.d);
radiusX = radiusX * scaleX;
radiusY = radiusY * scaleY;
startAngle = startAngle % (2*Math.PI);
endAngle = endAngle % (2*Math.PI);
if(startAngle === endAngle) {
endAngle = ((endAngle + (2*Math.PI)) - 0.001 * (counterClockwise ? -1 : 1)) % (2*Math.PI);
}
var endX = x + Math.cos(-rotation) * radiusX * Math.cos(endAngle)
+ Math.sin(-rotation) * radiusY * Math.sin(endAngle),
endY = y - Math.sin(-rotation) * radiusX * Math.cos(endAngle)
+ Math.cos(-rotation) * radiusY * Math.sin(endAngle),
startX = x + Math.cos(-rotation) * radiusX * Math.cos(startAngle)
+ Math.sin(-rotation) * radiusY * Math.sin(startAngle),
startY = y - Math.sin(-rotation) * radiusX * Math.cos(startAngle)
+ Math.cos(-rotation) * radiusY * Math.sin(startAngle),
sweepFlag = counterClockwise ? 0 : 1,
largeArcFlag = 0,
diff = endAngle - startAngle;
if(diff < 0) {
diff += 2*Math.PI;
}
if(counterClockwise) {
largeArcFlag = diff > Math.PI ? 0 : 1;
} else {
largeArcFlag = diff > Math.PI ? 1 : 0;
}
this.lineTo(startX / scaleX, startY / scaleY);
this.__addPathCommand(format("A {rx} {ry} {xAxisRotation} {largeArcFlag} {sweepFlag} {endX} {endY}",
{
rx:radiusX,
ry:radiusY,
xAxisRotation:rotation*(180/Math.PI),
largeArcFlag:largeArcFlag,
sweepFlag:sweepFlag,
endX:endX,
endY:endY
}));
this.__currentPosition = {x: endX, y: endY};
};
/**
* Generates a ClipPath from the clip command.
*/

View File

@ -4,6 +4,7 @@ import arcTo from './tests/arcTo'
import arcTo2 from './tests/arcTo2'
import arcToScaled from './tests/arcToScaled'
import emptyArc from './tests/emptyArc'
import ellipse from './tests/ellipse'
import fillstyle from './tests/fillstyle'
import globalAlpha from './tests/globalalpha'
import gradient from './tests/gradient'
@ -25,6 +26,7 @@ const tests = [
arcTo2,
arcToScaled,
emptyArc,
ellipse,
fillstyle,
globalAlpha,
gradient,

View File

@ -5,6 +5,7 @@ import arcTo from './tests/arcTo'
import arcTo2 from './tests/arcTo2'
import arcToScaled from './tests/arcToScaled'
import emptyArc from './tests/emptyArc'
import ellipse from './tests/ellipse'
import fillstyle from './tests/fillstyle'
import globalAlpha from './tests/globalalpha'
import gradient from './tests/gradient'
@ -26,6 +27,7 @@ const tests = {
arcTo2,
arcToScaled,
emptyArc,
ellipse,
fillstyle,
globalAlpha,
gradient,

25
test/tests/ellipse.js Normal file
View File

@ -0,0 +1,25 @@
export default function ellipse(ctx) {
// Draw shapes
for (let i = 0; i < 4; i++) {
for (let j = 0; j < 3; j++) {
ctx.beginPath();
var x = 25 + j * 50; // x coordinate
var y = 25 + i * 50; // y coordinate
var radiusX = 20; // Arc radius
var radiusY = 10; // Arc radius
var rotation = Math.PI + (Math.PI * (i+j)) / 8;
var startAngle = 0; // Starting point on circle
var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle
var clockwise = i % 2 == 0 ? false : true; // clockwise or anticlockwise
ctx.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, clockwise);
if (i > 1) {
ctx.fill();
} else {
ctx.stroke();
}
}
}
};