From 1c217ff3474debec9a26956fd653a0367bbe7869 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Nov 2026 11:06:03 +0000 Subject: [PATCH] Draw homepage hero handles in from their tips Scaling handle groups made each pair of opposite handles spread out from its vertex. Pop the tip circle in first, then draw each handle line from its tip into the vertex, so no group-level transform origin is involved. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01G9u8FisF4fZjfoV441qmFB --- .../home/HomeHeroIconsAnimation.vue | 51 ++++++------------- 1 file changed, 15 insertions(+), 36 deletions(-) diff --git a/docs/.vitepress/theme/components/home/HomeHeroIconsAnimation.vue b/docs/.vitepress/theme/components/home/HomeHeroIconsAnimation.vue index 627afd4f8..9db77209f 100644 --- a/docs/.vitepress/theme/components/home/HomeHeroIconsAnimation.vue +++ b/docs/.vitepress/theme/components/home/HomeHeroIconsAnimation.vue @@ -35,8 +35,8 @@ const MARKERS = [ ]; /** - * Bezier handles as [x1, y1, x2, y2] segments, grouped by when they appear. - * Each group scales in around its own centre, so groups stay per stroke. + * Bezier handles as [x1, y1, x2, y2] segments (vertex to tip), grouped by when they appear. + * Each handle draws in from its tip towards its vertex. */ const HANDLE_GROUPS = [ // Outer stroke @@ -118,32 +118,6 @@ const HANDLE_GROUPS = [ /** Radius of the circle at the tip of each handle. */ const HANDLE_TIP_RADIUS = 0.25; -/** - * Scales a handle group out of its vertex (the shared start point of its segments) - * instead of the centre of its bounding box. motion-v scales SVG elements within their - * fill-box and owns transform-origin, so the vertex is given as a fraction of that box. - */ -const handleOrigin = (segments: number[][]) => { - const [x, y] = segments[0]; - const xs = segments.flatMap(([x1, , x2]) => [x1, x2 - HANDLE_TIP_RADIUS, x2 + HANDLE_TIP_RADIUS]); - const ys = segments.flatMap(([, y1, , y2]) => [ - y1, - y2 - HANDLE_TIP_RADIUS, - y2 + HANDLE_TIP_RADIUS, - ]); - const [minX, maxX, minY, maxY] = [ - Math.min(...xs), - Math.max(...xs), - Math.min(...ys), - Math.max(...ys), - ]; - - return { - originX: (x - minX) / (maxX - minX), - originY: (y - minY) / (maxY - minY), - }; -}; - const COLUMNS = 8; const SIZE = 2; const GAP = 1; @@ -413,26 +387,31 @@ const logoStroke = (isOuter: boolean) => :animate="{ opacity: showHandles ? 1 : 0 }" :transition="{ duration: 0.6 }" > - - +