Skip to content

Instantly share code, notes, and snippets.

@holgergp
Last active June 13, 2024 18:41
Show Gist options
  • Save holgergp/b95396f8e81abb17add1809c404b163c to your computer and use it in GitHub Desktop.
Save holgergp/b95396f8e81abb17add1809c404b163c to your computer and use it in GitHub Desktop.
Retrofitted SmoothStepPath to react-flow-smart-edge
import { SVGDrawFunction } from "@tisoap/react-flow-smart-edge/src/functions/drawSvgPath";
import { XYPosition } from "reactflow";
const distance = (a: XYPosition, b: XYPosition) => Math.sqrt(Math.pow(b.x - a.x, 2) + Math.pow(b.y - a.y, 2));
function getBend(a: XYPosition, b: XYPosition, c: XYPosition, size: number): string {
const bendSize = Math.min(distance(a, b) / 2, distance(b, c) / 2, size);
const { x, y } = b;
// no bend
if ((a.x === x && x === c.x) || (a.y === y && y === c.y)) {
return `L${x} ${y}`;
}
// first segment is horizontal
if (a.y === y) {
const xDir = a.x < c.x ? -1 : 1;
const yDir = a.y < c.y ? 1 : -1;
return `L ${x + bendSize * xDir},${y}Q ${x},${y} ${x},${y + bendSize * yDir}`;
}
const xDir = a.x < c.x ? 1 : -1;
const yDir = a.y < c.y ? -1 : 1;
return `L ${x},${y + bendSize * yDir}Q ${x},${y} ${x + bendSize * xDir},${y}`;
}
function toPoint(pathSegment: number[]): XYPosition {
return { x: pathSegment[0], y: pathSegment[1] };
}
export const svgDrawSmoothStepPath =
(smoothStepOptions: { borderRadius: number }): SVGDrawFunction =>
(source, target, path) => {
const borderRadius = smoothStepOptions.borderRadius;
let svgPathString = `M ${source.x}, ${source.y} `;
const smoothedPath = path.reduce<string>((res, p, i) => {
let segment = "";
if (i > 0 && i < path.length - 1) {
segment = getBend(toPoint(path[i - 1]), toPoint(p), toPoint(path[i + 1]), borderRadius);
} else {
const [x, y] = p;
segment = `${i === 0 ? "M" : "L"}${x} ${y}`;
}
res += segment;
return res;
}, "");
svgPathString += smoothedPath;
svgPathString += `L ${target.x}, ${target.y} `;
return svgPathString;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment