Skip to content

feat(family): mouse parallax + neighbor hover-lift (4a)#9

Open
ffllyygod wants to merge 1 commit into
feature/the-family-r3f-cinemafrom
worktree/the-family-r3f-cinema-4a
Open

feat(family): mouse parallax + neighbor hover-lift (4a)#9
ffllyygod wants to merge 1 commit into
feature/the-family-r3f-cinemafrom
worktree/the-family-r3f-cinema-4a

Conversation

@ffllyygod

Copy link
Copy Markdown
Owner

Task 4a — Mouse parallax + neighbor hover-lift

Brief: .karimo/prds/002_the-family-r3f-cinema/briefs/4a_the-family-r3f-cinema.md
Wave 7 · Complexity 4/10 · Model opus
Spec ref: docs/superpowers/specs/2026-05-18-the-family-r3f-cinema-design.md §7.2

Summary

Desktop-only cinematic affordances on the §05 The Family ring.

  • Cursor parallax: ±0.18 rad additive ring offset, eased via existing maath damp.
  • Neighbour hover-lift: non-active packs bump scale 0.72→0.78 and z +0.1 on pointerenter.
  • Both gate on (hover:hover) and (pointer:fine) + !reducedMotion — touch / coarse-pointer / reduced-motion users see none of it.
  • snapTo / nudge open a 150ms pause window during which getParallax() returns {0,0} so the cursor doesn't fight click-to-snap easing.

Files

  • components/about/TheFamily/use-family-controls.tsparallaxRef, pausedUntilRef, setParallax, getParallax, needsParallax, PARALLAX_PAUSE_MS (= 150ms). Reduced-motion zeros + ignores writes; needsTick extended.
  • components/about/TheFamily/use-family-controls.test.ts (new) — 3 vitest cases: setParallax write, post-snap pause window, reduced-motion no-op.
  • components/about/TheFamily/CanvasScene.tsx — Ring useFrame adds clamped parallax offset; per-pack hoveredIndex state lifts non-active packs; enableHover prop gates hover handler attachment. Frameloop "always" while hover is active.
  • components/about/TheFamily/TheFamilyClient.tsxmatchMedia('(hover: hover) and (pointer: fine)') probe; onPointerMove chained (drag + parallax); onPointerLeave resets to {0,0}.

Evidence

$ npm run typecheck
[clean]

$ npx vitest --run
Test Files  15 passed (15)
Tests       126 passed (126)

3 new cases under useFamilyControls — parallax (PRD 002 task 4a):

  • setParallax writes (x, y) into parallaxRef.current
  • snapTo opens a 150ms pause window during which getParallax returns {0,0}
  • reducedMotion=true: setParallax is a no-op (ref stays at {0,0})

Downstream

  • 4b consumes the same hook return — needsParallax + parallaxRef exports are stable. No API removals.

Closes karimo task 4a

🤖 Generated with Claude Code

Desktop-only: cursor pans ring ±0.18 rad; non-active packs lift on
hover (scale 0.72→0.78, z+0.1). Both gate on hover:hover+pointer:fine
+ !reducedMotion. snapTo/nudge pause parallax 150ms to avoid fighting
click-to-snap easing.

- use-family-controls: parallaxRef, pausedUntilRef, setParallax,
  getParallax, needsParallax. Reduced-motion zeros + ignores writes.
- CanvasScene: Ring useFrame adds clamped parallax offset; hoveredIndex
  state bumps non-active pack scale + z. frameloop "always" when hovering.
- TheFamilyClient: matchMedia probe for desktop-hover; onPointerMove
  + onPointerLeave wired to setParallax.
- +3 vitest cases covering setParallax write, post-snap pause window,
  reduced-motion no-op.

Spec: docs/superpowers/specs/2026-05-18-the-family-r3f-cinema-design.md §7.2
PRD: 002_the-family-r3f-cinema

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel

vercel Bot commented May 18, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pilato Ready Ready Preview, Comment May 18, 2026 10:54am

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

complexity-4 Complexity 4/10 karimo KARIMO automated PR karimo-the-family-r3f-cinema PRD: the-family-r3f-cinema wave-7

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant