Skip to content

Commit

Permalink
feat(Circle): Add counterclockwise parameter to Circle class
Browse files Browse the repository at this point in the history
  • Loading branch information
lbordowitz committed Feb 16, 2024
1 parent 624d35f commit 568f69e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## [next]

- feat(Circle): Add counterclockwise parameter to Circle class [#9670](https://github.com/fabricjs/fabric.js/pull/9670)
- feat(LayoutManager): Expose objects registration [#9661](https://github.com/fabricjs/fabric.js/pull/9661)
- fix(Object): support specyfing toCanvasElement canvas [#9652](https://github.com/fabricjs/fabric.js/pull/9652)
- ci(): no `src` imports [#9657](https://github.com/fabricjs/fabric.js/pull/9657)
Expand Down
33 changes: 23 additions & 10 deletions src/shapes/Circle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,25 @@ interface UniqueCircleProps {
radius: number;

/**
* degrees of start of the circle.
* probably will change to degrees in next major version
* @type Number 0 - 359
* Angle for the start of the circle, in degrees.
* @type TDegree 0 - 359
* @default 0
*/
startAngle: number;

/**
* End angle of the circle
* probably will change to degrees in next major version
* @type Number 1 - 360
* Angle for the end of the circle, in degrees
* @type TDegree 1 - 360
* @default 360
*/
endAngle: number;

/**
* Orientation for the direction of the circle.
* Setting to true will switch the arc of the circle to traverse from startAngle to endAngle in a counterclockwise direction,
* @default false
*/
counterclockwise: boolean;
}

export interface SerializedCircleProps
Expand All @@ -41,12 +46,18 @@ export interface SerializedCircleProps

export interface CircleProps extends FabricObjectProps, UniqueCircleProps {}

const CIRCLE_PROPS = ['radius', 'startAngle', 'endAngle'] as const;
const CIRCLE_PROPS = [
'radius',
'startAngle',
'endAngle',
'counterclockwise',
] as const;

export const circleDefaultValues: UniqueCircleProps = {
radius: 0,
startAngle: 0,
endAngle: 360,
counterclockwise: true,
};

export class Circle<
Expand All @@ -60,6 +71,7 @@ export class Circle<
declare radius: number;
declare startAngle: number;
declare endAngle: number;
declare counterclockwise: boolean;

static type = 'Circle';

Expand Down Expand Up @@ -101,7 +113,7 @@ export class Circle<
this.radius,
degreesToRadians(this.startAngle),
degreesToRadians(this.endAngle),
false
this.counterclockwise
);
this._renderPaintInOrder(ctx);
}
Expand Down Expand Up @@ -169,12 +181,13 @@ export class Circle<
startY = sin(start) * radius,
endX = cos(end) * radius,
endY = sin(end) * radius,
largeFlag = angle > 180 ? '1' : '0';
largeFlag = angle > 180 ? '1' : '0',
sweepFlag = this.counterclockwise ? '0' : '1';
return [
`<path d="M ${startX} ${startY}`,
` A ${radius} ${radius}`,
' 0 ',
`${largeFlag} 1`,
`${largeFlag} ${sweepFlag}`,
` ${endX} ${endY}`,
'" ',
'COMMON_PARTS',
Expand Down
9 changes: 9 additions & 0 deletions test/unit/circle.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
radius: 0,
startAngle: 0,
endAngle: 360,
counterclockwise: false,
skewX: 0,
skewY: 0,
strokeUniform: false
Expand Down Expand Up @@ -166,6 +167,14 @@
assert.equal(svgClipPath, '\t<path d=\"M 10 0 A 10 10 0 0 1 -10 0\" transform=\"matrix(1 0 0 1 10.5 10.5)\" />\n', 'half circle as clipPath');
});

QUnit.test('toSVG with counterclockwise half circle', function (assert) {
var circle = new fabric.Circle({ width: 100, height: 100, radius: 10, endAngle: fabric.util.radiansToDegrees(Math.PI), counterclockwise: true });
var svg = circle.toSVG();
var svgClipPath = circle.toClipPathSVG();
assert.equal(svg, '<g transform=\"matrix(1 0 0 1 10.5 10.5)\" >\n<path d=\"M 10 0 A 10 10 0 0 0 -10 0\" style=\"stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;\" />\n</g>\n');
assert.equal(svgClipPath, '\t<path d=\"M 10 0 A 10 10 0 0 0 -10 0\" transform=\"matrix(1 0 0 1 10.5 10.5)\" />\n', 'half circle as clipPath');
});

QUnit.test('fromElement', function(assert) {
var done = assert.async();
assert.ok(typeof fabric.Circle.fromElement === 'function');
Expand Down

0 comments on commit 568f69e

Please sign in to comment.