refactor: use path builder

This commit is contained in:
Yifeng Wang
2025-05-26 01:06:46 +08:00
parent df2ecf2bec
commit 6483f36723
@@ -17,6 +17,60 @@ interface PathBounds {
maxY: number;
}
interface PathCommand {
command: string;
coordinates: number[];
}
class SVGPathBuilder {
private commands: PathCommand[] = [];
moveTo(x: number, y: number): this {
this.commands.push({
command: 'M',
coordinates: [x, y],
});
return this;
}
lineTo(x: number, y: number): this {
this.commands.push({
command: 'L',
coordinates: [x, y],
});
return this;
}
curveTo(
cp1x: number,
cp1y: number,
cp2x: number,
cp2y: number,
x: number,
y: number
): this {
this.commands.push({
command: 'C',
coordinates: [cp1x, cp1y, cp2x, cp2y, x, y],
});
return this;
}
build(): string {
const pathSegments = this.commands.map(cmd => {
const coords = cmd.coordinates.join(' ');
return `${cmd.command} ${coords}`;
});
return pathSegments.join(' ');
}
clear(): this {
this.commands = [];
return this;
}
}
function calculatePathBounds(path: PointLocation[]): PathBounds {
if (path.length === 0) {
return { minX: 0, minY: 0, maxX: 0, maxY: 0 };
@@ -43,23 +97,31 @@ function createConnectorPath(
): string {
if (points.length < 2) return '';
let pathData = `M ${points[0][0]} ${points[0][1]}`;
const pathBuilder = new SVGPathBuilder();
pathBuilder.moveTo(points[0][0], points[0][1]);
if (mode === ConnectorMode.Curve) {
// Use bezier curves
for (let i = 1; i < points.length; i++) {
const prev = points[i - 1];
const curr = points[i];
pathData += ` C ${prev.absOut[0]} ${prev.absOut[1]} ${curr.absIn[0]} ${curr.absIn[1]} ${curr[0]} ${curr[1]}`;
pathBuilder.curveTo(
prev.absOut[0],
prev.absOut[1],
curr.absIn[0],
curr.absIn[1],
curr[0],
curr[1]
);
}
} else {
// Use straight lines
for (let i = 1; i < points.length; i++) {
pathData += ` L ${points[i][0]} ${points[i][1]}`;
pathBuilder.lineTo(points[i][0], points[i][1]);
}
}
return pathData;
return pathBuilder.build();
}
function createArrowMarker(