mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
close curve for circle arrowheads
This commit is contained in:
parent
068edfc1cd
commit
bec662eaf6
2 changed files with 43 additions and 33 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
import { pointsOnBezierCurves } from "points-on-curve";
|
||||||
import {
|
import {
|
||||||
isPoint,
|
isPoint,
|
||||||
pointFrom,
|
pointFrom,
|
||||||
|
@ -8,7 +9,6 @@ import {
|
||||||
type GlobalPoint,
|
type GlobalPoint,
|
||||||
type LocalPoint,
|
type LocalPoint,
|
||||||
polygonFromPoints,
|
polygonFromPoints,
|
||||||
pointAdd,
|
|
||||||
} from "../math";
|
} from "../math";
|
||||||
import {
|
import {
|
||||||
getClosedCurveShape,
|
getClosedCurveShape,
|
||||||
|
@ -16,6 +16,7 @@ import {
|
||||||
getCurveShape,
|
getCurveShape,
|
||||||
getEllipseShape,
|
getEllipseShape,
|
||||||
getFreedrawShape,
|
getFreedrawShape,
|
||||||
|
getPointsOnRoughCurve,
|
||||||
getPolygonShape,
|
getPolygonShape,
|
||||||
type GeometricShape,
|
type GeometricShape,
|
||||||
} from "../utils/geometry/shape";
|
} from "../utils/geometry/shape";
|
||||||
|
@ -209,14 +210,15 @@ export const getElementShapes = <Point extends GlobalPoint | LocalPoint>(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arrowhead.shape === "circle") {
|
if (arrowhead.shape === "circle") {
|
||||||
// TODO: close curve into polygon / ellipse
|
const polygonPoints = pointsOnBezierCurves(
|
||||||
|
getPointsOnRoughCurve(arrowhead),
|
||||||
|
15,
|
||||||
|
2,
|
||||||
|
).map((p) => transform(p as Point)) as Point[];
|
||||||
|
|
||||||
arrowheadShapes.push({
|
arrowheadShapes.push({
|
||||||
...getCurveShape<Point>(
|
type: "polygon",
|
||||||
arrowhead,
|
data: polygonFromPoints(polygonPoints),
|
||||||
element.angle,
|
|
||||||
center,
|
|
||||||
startingPoint,
|
|
||||||
),
|
|
||||||
isClosed: true,
|
isClosed: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -288,6 +288,35 @@ export const getFreedrawShape = <Point extends GlobalPoint | LocalPoint>(
|
||||||
) as GeometricShape<Point>;
|
) as GeometricShape<Point>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getPointsOnRoughCurve = <Point extends GlobalPoint | LocalPoint>(
|
||||||
|
roughCurve: Drawable,
|
||||||
|
) => {
|
||||||
|
const ops = getCurvePathOps(roughCurve);
|
||||||
|
|
||||||
|
const points: Point[] = [];
|
||||||
|
let odd = false;
|
||||||
|
for (const operation of ops) {
|
||||||
|
if (operation.op === "move") {
|
||||||
|
odd = !odd;
|
||||||
|
if (odd) {
|
||||||
|
points.push(pointFrom(operation.data[0], operation.data[1]));
|
||||||
|
}
|
||||||
|
} else if (operation.op === "bcurveTo") {
|
||||||
|
if (odd) {
|
||||||
|
points.push(pointFrom(operation.data[0], operation.data[1]));
|
||||||
|
points.push(pointFrom(operation.data[2], operation.data[3]));
|
||||||
|
points.push(pointFrom(operation.data[4], operation.data[5]));
|
||||||
|
}
|
||||||
|
} else if (operation.op === "lineTo") {
|
||||||
|
if (odd) {
|
||||||
|
points.push(pointFrom(operation.data[0], operation.data[1]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
|
};
|
||||||
|
|
||||||
export const getClosedCurveShape = <Point extends GlobalPoint | LocalPoint>(
|
export const getClosedCurveShape = <Point extends GlobalPoint | LocalPoint>(
|
||||||
element: ExcalidrawLinearElement,
|
element: ExcalidrawLinearElement,
|
||||||
roughShape: Drawable,
|
roughShape: Drawable,
|
||||||
|
@ -311,31 +340,10 @@ export const getClosedCurveShape = <Point extends GlobalPoint | LocalPoint>(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const ops = getCurvePathOps(roughShape);
|
const polygonPoints = pointsOnBezierCurves(
|
||||||
|
getPointsOnRoughCurve(roughShape),
|
||||||
const points: Point[] = [];
|
10,
|
||||||
let odd = false;
|
5,
|
||||||
for (const operation of ops) {
|
|
||||||
if (operation.op === "move") {
|
|
||||||
odd = !odd;
|
|
||||||
if (odd) {
|
|
||||||
points.push(pointFrom(operation.data[0], operation.data[1]));
|
|
||||||
}
|
|
||||||
} else if (operation.op === "bcurveTo") {
|
|
||||||
if (odd) {
|
|
||||||
points.push(pointFrom(operation.data[0], operation.data[1]));
|
|
||||||
points.push(pointFrom(operation.data[2], operation.data[3]));
|
|
||||||
points.push(pointFrom(operation.data[4], operation.data[5]));
|
|
||||||
}
|
|
||||||
} else if (operation.op === "lineTo") {
|
|
||||||
if (odd) {
|
|
||||||
points.push(pointFrom(operation.data[0], operation.data[1]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const polygonPoints = pointsOnBezierCurves(points, 10, 5).map((p) =>
|
|
||||||
transform(p as Point),
|
|
||||||
) as Point[];
|
) as Point[];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue