mirror of
https://github.com/lucide-icons/lucide.git
synced 2026-11-14 13:58:21 +00:00
feat: added curve handles to svg preview (#1661)
This commit is contained in:
@@ -199,6 +199,28 @@ const Radii = ({
|
||||
);
|
||||
};
|
||||
|
||||
const Handles = ({
|
||||
paths,
|
||||
...props
|
||||
}: { paths: Path[] } & PathProps<
|
||||
'strokeWidth' | 'stroke' | 'strokeDasharray' | 'strokeOpacity',
|
||||
any
|
||||
>) => {
|
||||
console.log(paths);
|
||||
return (
|
||||
<g className="svg-preview-handles-group" {...props}>
|
||||
{paths.map(({ c, prev, next, cp1, cp2 }) => (
|
||||
<>
|
||||
{cp1 && <path d={`M${prev.x} ${prev.y} ${cp1.x} ${cp1.y}`} />}
|
||||
{cp1 && <circle cy={cp1.y} cx={cp1.x} r={0.25} />}
|
||||
{cp2 && <path d={`M${next.x} ${next.y} ${cp2.x} ${cp2.y}`} />}
|
||||
{cp2 && <circle cy={cp2.y} cx={cp2.x} r={0.25} />}
|
||||
</>
|
||||
))}
|
||||
</g>
|
||||
);
|
||||
};
|
||||
|
||||
const SvgPreview = React.forwardRef<
|
||||
SVGSVGElement,
|
||||
{
|
||||
@@ -238,6 +260,7 @@ const SvgPreview = React.forwardRef<
|
||||
<style>{darkModeCss}</style>
|
||||
{showGrid && <Grid strokeWidth={0.1} stroke="#777" strokeOpacity={0.3} radius={1} />}
|
||||
<Shadow paths={paths} strokeWidth={4} stroke="#777" radius={1} strokeOpacity={0.15} />
|
||||
<Handles paths={paths} strokeWidth={0.12} stroke="#777" strokeOpacity={0.6} />
|
||||
<ColoredPath
|
||||
paths={paths}
|
||||
colors={[
|
||||
@@ -263,6 +286,7 @@ const SvgPreview = React.forwardRef<
|
||||
strokeOpacity={0.3}
|
||||
/>
|
||||
<ControlPath radius={1} paths={paths} pointSize={1} stroke="#fff" strokeWidth={0.125} />
|
||||
<Handles paths={paths} strokeWidth={0.12} stroke="#FFF" strokeOpacity={0.3} />
|
||||
{children}
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -8,7 +8,9 @@ export type Path = {
|
||||
prev: Point;
|
||||
next: Point;
|
||||
isStart: boolean;
|
||||
circle: { x: number; y: number; r: number };
|
||||
circle?: { x: number; y: number; r: number };
|
||||
cp1?: Point;
|
||||
cp2?: Point;
|
||||
c: ReturnType<typeof getCommands>[number];
|
||||
};
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ export const getPaths = (src: string) => {
|
||||
c: typeof commands[number],
|
||||
next: Point,
|
||||
d?: string,
|
||||
circle?: Path['circle']
|
||||
extras?: { circle?: Path['circle']; cp1?: Path['cp1']; cp2?: Path['cp2'] }
|
||||
) => {
|
||||
assert(prev);
|
||||
paths.push({
|
||||
@@ -71,7 +71,7 @@ export const getPaths = (src: string) => {
|
||||
d: d || `M ${prev.x} ${prev.y} L ${next.x} ${next.y}`,
|
||||
prev,
|
||||
next,
|
||||
circle,
|
||||
...extras,
|
||||
isStart: start === prev,
|
||||
});
|
||||
prev = next;
|
||||
@@ -110,7 +110,10 @@ export const getPaths = (src: string) => {
|
||||
}
|
||||
case SVGPathData.CURVE_TO: {
|
||||
assert(prev);
|
||||
addPath(c, c, `M ${prev.x} ${prev.y} ${encodeSVGPath(c)}`);
|
||||
addPath(c, c, `M ${prev.x} ${prev.y} ${encodeSVGPath(c)}`, {
|
||||
cp1: { x: c.x1, y: c.y1 },
|
||||
cp2: { x: c.x2, y: c.y2 },
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SVGPathData.SMOOTH_CURVE_TO: {
|
||||
@@ -146,13 +149,20 @@ export const getPaths = (src: string) => {
|
||||
y1: prev.y - reflectedCp1.y,
|
||||
x2: c.x2,
|
||||
y2: c.y2,
|
||||
})}`
|
||||
})}`,
|
||||
{
|
||||
cp1: reflectedCp1,
|
||||
cp2: { x: c.x2, y: c.y2 },
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
case SVGPathData.QUAD_TO: {
|
||||
assert(prev);
|
||||
addPath(c, c, `M ${prev.x} ${prev.y} ${encodeSVGPath(c)}`);
|
||||
addPath(c, c, `M ${prev.x} ${prev.y} ${encodeSVGPath(c)}`, {
|
||||
cp1: { x: c.x1, y: c.y1 },
|
||||
cp2: { x: c.x1, y: c.y1 },
|
||||
});
|
||||
break;
|
||||
}
|
||||
case SVGPathData.SMOOTH_QUAD_TO: {
|
||||
@@ -197,7 +207,11 @@ export const getPaths = (src: string) => {
|
||||
y: c.y,
|
||||
x1: prevCP.x,
|
||||
y1: prevCP.y,
|
||||
})}`
|
||||
})}`,
|
||||
{
|
||||
cp1: { x: prevCP.x, y: prevCP.y },
|
||||
cp2: { x: prevCP.x, y: prevCP.y },
|
||||
}
|
||||
);
|
||||
break;
|
||||
}
|
||||
@@ -218,7 +232,7 @@ export const getPaths = (src: string) => {
|
||||
c,
|
||||
c,
|
||||
`M ${prev.x} ${prev.y} A${c.rX} ${c.rY} ${c.xRot} ${c.lArcFlag} ${c.sweepFlag} ${c.x} ${c.y}`,
|
||||
c.rX === c.rY ? { ...center, r: c.rX } : undefined
|
||||
{ circle: c.rX === c.rY ? { ...center, r: c.rX } : undefined }
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user