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

Feature add ellipse
This commit is contained in:
Chris Waters 2022-07-15 17:57:55 -07:00 committed by GitHub
commit c4fe5203a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 86 additions and 0 deletions

View File

@ -1030,6 +1030,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

@ -3,6 +3,7 @@ import arc from './tests/arc'
import arcTo from './tests/arcTo'
import arcTo2 from './tests/arcTo2'
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'
@ -23,6 +24,7 @@ const tests = [
arcTo,
arcTo2,
emptyArc,
ellipse,
fillstyle,
globalAlpha,
gradient,

View File

@ -4,6 +4,7 @@ import arc from './tests/arc'
import arcTo from './tests/arcTo'
import arcTo2 from './tests/arcTo2'
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'
@ -24,6 +25,7 @@ const tests = {
arcTo,
arcTo2,
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();
}
}
}
};