morph points (useWobbleAnimation implementation)

This commit is contained in:
2026-01-25 09:39:08 +00:00
parent e0a207a842
commit fd00527169

View File

@@ -1,5 +1,7 @@
import { useWobbleAnimation } from "@/hooks/useWobbleAnimation";
import { morphPoints } from "@/lib/shapes/morph"; import { morphPoints } from "@/lib/shapes/morph";
import { generateCirclePoints, generateSquarePoints, generateTrianglePoints } from "@/lib/shapes/points"; import { generateCirclePoints, generateSquarePoints, generateTrianglePoints } from "@/lib/shapes/points";
import { applyWobble } from "@/lib/shapes/wobble";
import type { ShapeState } from "@/types/shape"; import type { ShapeState } from "@/types/shape";
import type { KonvaEventObject } from "konva/lib/Node"; import type { KonvaEventObject } from "konva/lib/Node";
import { useMemo } from "react"; import { useMemo } from "react";
@@ -15,6 +17,8 @@ export default function MorphableShape({
state: ShapeState; state: ShapeState;
onStateChange: (state: ShapeState) => void; onStateChange: (state: ShapeState) => void;
}) { }) {
const time = useWobbleAnimation(state.wobbleSpeed);
const handleDrag = (e: KonvaEventObject<DragEvent>) => { const handleDrag = (e: KonvaEventObject<DragEvent>) => {
onStateChange({ onStateChange({
...state, ...state,
@@ -23,7 +27,7 @@ export default function MorphableShape({
}); });
}; };
const flatPoints = useMemo(() => { const morphedPoints = useMemo(() => {
const presetPoints = (() => { const presetPoints = (() => {
switch (state.preset) { switch (state.preset) {
case "triangle": case "triangle":
@@ -37,12 +41,15 @@ export default function MorphableShape({
const circlePoints = generateCirclePoints(0, 0, SHAPE_RADIUS, NUM_POINTS); const circlePoints = generateCirclePoints(0, 0, SHAPE_RADIUS, NUM_POINTS);
const t = state.roundness / 100; const t = state.roundness / 100;
const morphed = morphPoints(presetPoints, circlePoints, t); return morphPoints(presetPoints, circlePoints, t);
// flatten to [x1, y1, x2, y2, ...]
return morphed.flatMap((p) => [p.x, p.y]);
}, [state.preset, state.roundness]); }, [state.preset, state.roundness]);
const flatPoints = useMemo(() => {
const wobbleAmount = state.wobble * 0.3; // scale wobble to reasonable range
const wobbled = applyWobble(morphedPoints, time, wobbleAmount);
return wobbled.flatMap((p) => [p.x, p.y]);
}, [morphedPoints, time, state.wobble]);
return ( return (
<Group x={state.x} y={state.y} draggable onDragMove={handleDrag}> <Group x={state.x} y={state.y} draggable onDragMove={handleDrag}>
<Line points={flatPoints} closed fill={state.color} /> <Line points={flatPoints} closed fill={state.color} />