close curve for circle arrowheads

pull/7469/head
Ryan Di 3 weeks ago
parent 068edfc1cd
commit bec662eaf6

@ -1,3 +1,4 @@
import { pointsOnBezierCurves } from "points-on-curve";
import {
isPoint,
pointFrom,
@ -8,7 +9,6 @@ import {
type GlobalPoint,
type LocalPoint,
polygonFromPoints,
pointAdd,
} from "../math";
import {
getClosedCurveShape,
@ -16,6 +16,7 @@ import {
getCurveShape,
getEllipseShape,
getFreedrawShape,
getPointsOnRoughCurve,
getPolygonShape,
type GeometricShape,
} from "../utils/geometry/shape";
@ -209,14 +210,15 @@ export const getElementShapes = <Point extends GlobalPoint | LocalPoint>(
}
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({
...getCurveShape<Point>(
arrowhead,
element.angle,
center,
startingPoint,
),
type: "polygon",
data: polygonFromPoints(polygonPoints),
isClosed: true,
});
}

@ -288,6 +288,35 @@ export const getFreedrawShape = <Point extends GlobalPoint | LocalPoint>(
) 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>(
element: ExcalidrawLinearElement,
roughShape: Drawable,
@ -311,31 +340,10 @@ export const getClosedCurveShape = <Point extends GlobalPoint | LocalPoint>(
};
}
const ops = getCurvePathOps(roughShape);
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]));
}
}
}
const polygonPoints = pointsOnBezierCurves(points, 10, 5).map((p) =>
transform(p as Point),
const polygonPoints = pointsOnBezierCurves(
getPointsOnRoughCurve(roughShape),
10,
5,
) as Point[];
return {

Loading…
Cancel
Save