Compare commits

..

2 Commits

Author SHA1 Message Date
semantic-release-bot
75b193e1d2 chore(release): 2.14.3 [skip ci]
## [2.14.3](https://github.com/antialias/soroban-abacus-flashcards/compare/v2.14.2...v2.14.3) (2025-10-09)

### Bug Fixes

* enable smooth spring animations between card hovers ([8d53b58](8d53b589aa))
2025-10-09 21:24:22 +00:00
Thomas Hallock
8d53b589aa fix: enable smooth spring animations between card hovers
Fixed spring animation not working when moving between cards:

ISSUE:
- Avatar would jump instantly to new position instead of smoothly gliding
- The 'from' config was preventing spring from animating position changes

SOLUTION:
- Remove 'from' entirely from spring config
- Use simple spring with immediate flag for first render only
- Track isFirstRender with useRef to skip initial animation
- After first render, all position changes animate smoothly

HOW IT WORKS:
1. First hover: immediate:true - Avatar appears instantly at position
2. isFirstRender flag cleared after position is set
3. Subsequent hovers: immediate:false - Spring animates smoothly
4. Position updates trigger spring to animate x,y to new values
5. Config (tension:280, friction:60) provides smooth glide

RESULT:
- First hover: Avatar appears instantly (no fly-in)
- Moving between cards: Avatar smoothly glides with spring physics
- Feels like watching remote player's mouse cursor move

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-09 16:23:26 -05:00
3 changed files with 20 additions and 12 deletions

View File

@@ -1,3 +1,10 @@
## [2.14.3](https://github.com/antialias/soroban-abacus-flashcards/compare/v2.14.2...v2.14.3) (2025-10-09)
### Bug Fixes
* enable smooth spring animations between card hovers ([8d53b58](https://github.com/antialias/soroban-abacus-flashcards/commit/8d53b589aa17ebc6d0a9251b3006fd8a90f90a61))
## [2.14.2](https://github.com/antialias/soroban-abacus-flashcards/compare/v2.14.1...v2.14.2) (2025-10-09)

View File

@@ -93,14 +93,13 @@ function HoverAvatar({
cardElement: HTMLElement | null
}) {
const [position, setPosition] = useState<{ x: number; y: number } | null>(null)
const isFirstRender = useRef(true)
// Update position when card element changes
useEffect(() => {
if (cardElement) {
const rect = cardElement.getBoundingClientRect()
// Calculate the actual position we want the avatar centered at (top-right of card)
// Since we're using translate(-50%, -50%), we need the center point
const avatarSize = 48
const avatarCenterX = rect.right - 12 // 12px from right edge
const avatarCenterY = rect.top - 12 // 12px from top edge
@@ -112,23 +111,25 @@ function HoverAvatar({
}, [cardElement])
// Smooth spring animation for position changes
// Use 'from' to set initial position when avatar first appears
const springProps = useSpring({
from: position
? { x: position.x, y: position.y, opacity: 0 }
: { x: 0, y: 0, opacity: 0 },
to: {
x: position?.x ?? 0,
y: position?.y ?? 0,
opacity: position ? 1 : 0,
},
x: position?.x ?? 0,
y: position?.y ?? 0,
opacity: position ? 1 : 0,
config: {
tension: 280,
friction: 60,
mass: 1,
},
immediate: isFirstRender.current, // Skip animation on first render only
})
// Clear first render flag after initial render
useEffect(() => {
if (position && isFirstRender.current) {
isFirstRender.current = false
}
}, [position])
// Don't render until we have a position
if (!position) return null

View File

@@ -1,6 +1,6 @@
{
"name": "soroban-monorepo",
"version": "2.14.2",
"version": "2.14.3",
"private": true,
"description": "Beautiful Soroban Flashcard Generator - Monorepo",
"workspaces": [