Skip to content

feat: refine robot avatar cursor-follow + center welcome questions#2

Merged
FranRom merged 3 commits into
mainfrom
feat/robot-avatar-idle-cursor-follow
May 20, 2026
Merged

feat: refine robot avatar cursor-follow + center welcome questions#2
FranRom merged 3 commits into
mainfrom
feat/robot-avatar-idle-cursor-follow

Conversation

@FranRom

@FranRom FranRom commented May 20, 2026

Copy link
Copy Markdown
Owner

Summary

UX polish on the robot avatar and welcome screen.

Robot avatar — cursor follow

  • Pause while thinking. When isTalking flips true, the avatar smoothly returns to a neutral position (the existing rAF lerp interpolates toward a zeroed target). Mousemoves are ignored while thinking, then tracking resumes on idle.
  • Reset when the cursor leaves the page. mouseleave on document.documentElement (the canonical cross-browser hook for "cursor exited the viewport") + window blur for tab switches.
  • Stay idle while typing. When the cursor is over an input, textarea, or [contenteditable], target is zeroed so the avatar doesn't jitter under the user's typing.
  • Fix the "freezes when cursor is over the avatar" bug. The old code read getBoundingClientRect() on every mousemove; with a live 3D rotateY/X + perspective + translate3d transform, the rect's center shifts in non-obvious ways and fed back into the offset calculation, collapsing the response to ~0 whenever the cursor approached the avatar. Now the natural center is cached on mount (with the transform briefly cleared) and re-measured on resize/scroll. onMove compares against the stable cached point — no feedback loop.
  • Visible response near the avatar. A sqrt curve (sign(v) * sqrt(|v|)) amplifies small offsets so the tilt is visible when the cursor is close, while keeping the same saturation at the radius.
  • Tuned amplitudes after a few rounds of iteration: MAX_TILT_DEG = 28°, MAX_TRANSLATE_PX = 10, FOLLOW_RADIUS_PX = 400.

Welcome screen

  • Centered suggested questions. Added justify-center to the horizontal flex-wrap so each wrapped row sits under the avatar/welcome message. The vertical sidebar layout used during conversations is untouched.

Test plan

  • npx vitest run — 121/121 passing
  • npx playwright test — 7/7 passing
  • Smoke the avatar in the browser:
    • Cursor over the avatar produces visible tilt that tracks position
    • Cursor exits the viewport → avatar eases back to neutral
    • Cursor over the chat input → avatar idles
    • Sending a message → avatar pauses tracking while streaming, resumes after
    • Welcome screen questions visually centered under the avatar

FranRom added 3 commits May 20, 2026 16:17
Avatar smoothly eases back to a neutral position when isTalking flips
true, and resumes following the cursor once it returns to idle. Reuses
the existing rAF lerp by zeroing the shared target ref during talking
and short-circuiting mousemove updates via an isTalking ref.
- Cache the natural center on mount (with transform briefly cleared) and
  re-measure on resize/scroll. The previous approach read the live rect
  on every mousemove, which fed the transformed AABB back into the
  offset calculation and made the avatar settle to ~idle whenever the
  cursor was near or over it.
- Apply a sqrt response curve so small offsets still produce visible
  tilt, keeping the avatar reactive when the cursor is close.
- Reset to idle when the cursor leaves the viewport via mouseleave on
  document.documentElement, and on window blur for tab switches.
- Stay idle while the cursor is over any input/textarea/contenteditable
  so the avatar doesn't jitter during typing.
- Tune amplitudes (35° tilt -> 28°, 12px -> 10px translate, 350 -> 400
  follow radius) for a calmer feel.
Add justify-center to the horizontal flex-wrap container so each
wrapped row aligns under the avatar/welcome message. The vertical
sidebar layout used during conversations is unaffected.
@vercel

vercel Bot commented May 20, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
cv-bot Ready Ready Preview, Comment May 20, 2026 3:06pm

@FranRom FranRom self-assigned this May 20, 2026
@FranRom FranRom merged commit c6e0b5f into main May 20, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant