Test / components /studio /Shape.tsx
TrikozikGames's picture
Add source files
eddc354
Raw
History Blame Contribute Delete
1.82 kB
import type { ElementKind } from "@/lib/tatting";
type Props = {
kind: ElementKind;
picots: number;
radius: number;
color: string;
};
const r3 = (n: number) => Math.round(n * 1000) / 1000;
/** Renders a tatting motif centered at (0,0) in local coordinates. */
export function Shape({ kind, picots, radius, color }: Props) {
const picotR = Math.max(3, radius * 0.11);
if (kind === "ring") {
const dots = Array.from({ length: picots }, (_, i) => {
const a = (i / picots) * Math.PI * 2 - Math.PI / 2;
return {
cx: r3(Math.cos(a) * (radius + picotR * 0.7)),
cy: r3(Math.sin(a) * (radius + picotR * 0.7)),
};
});
return (
<g fill="none" stroke={color} strokeWidth={2.5} strokeLinecap="round">
<circle cx={0} cy={0} r={radius} />
<circle cx={0} cy={0} r={radius - 5} strokeWidth={1} opacity={0.45} />
{dots.map((d, i) => (
<circle key={i} cx={d.cx} cy={d.cy} r={picotR} />
))}
</g>
);
}
// Arc: half-circle bow with picots along the outer edge
const start = { x: -radius, y: 0 };
const end = { x: radius, y: 0 };
const dots = Array.from({ length: picots }, (_, i) => {
const t = (i + 1) / (picots + 1);
const a = Math.PI - t * Math.PI;
const rr = radius + picotR * 0.7;
return { cx: r3(Math.cos(a) * rr), cy: r3(-Math.sin(a) * rr) };
});
return (
<g fill="none" stroke={color} strokeWidth={2.5} strokeLinecap="round">
<path d={`M ${start.x} ${start.y} A ${radius} ${radius} 0 0 1 ${end.x} ${end.y}`} />
<path
d={`M ${start.x + 5} 0 A ${radius - 5} ${radius - 5} 0 0 1 ${end.x - 5} 0`}
strokeWidth={1}
opacity={0.45}
/>
{dots.map((d, i) => (
<circle key={i} cx={d.cx} cy={d.cy} r={picotR} />
))}
</g>
);
}