From eaa9f5bc24d968e29bd0f830737e28abedd9179b Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 4 Nov 2026 10:57:13 +0000 Subject: [PATCH] Scale homepage hero handle groups from their vertex Set each handle group's transform origin to its vertex, given as a fraction of the group's fill-box because motion-v owns transform-origin. Handle pairs were already centred on their vertex; single handles now grow out of the path instead of from their midpoint. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01G9u8FisF4fZjfoV441qmFB --- .../home/HomeHeroIconsAnimation.vue | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/.vitepress/theme/components/home/HomeHeroIconsAnimation.vue b/docs/.vitepress/theme/components/home/HomeHeroIconsAnimation.vue index 7b651e152..627afd4f8 100644 --- a/docs/.vitepress/theme/components/home/HomeHeroIconsAnimation.vue +++ b/docs/.vitepress/theme/components/home/HomeHeroIconsAnimation.vue @@ -115,6 +115,35 @@ 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; @@ -387,6 +416,7 @@ const logoStroke = (isOuter: boolean) =>