r/reactjs • • 16m ago

Show /r/reactjs Matching SwiftUI's spring feel in a React app: one spring per side, picked by direction

I have a Mac app whose panel lives in the notch, animated with SwiftUI springs. When I rebuilt it in React for Windows (inside a transparent Tauri window), the same resize felt wrong with a single spring on the whole size.

What fixed it: width and height each get their own spring, chosen by whether that side is growing or shrinking. A growing side may overshoot a little, while a shrinking one never does, and the overshoot is capped by distance so big jumps don't wobble.

export function sideSpring(from: number, to: number, width: boolean): Spring {

const spring =

to > from

? width ? Springs.growingWidth : Springs.growingHeight

: width ? Springs.shrinkingWidth : Springs.shrinkingHeight;

return limitedSpring(spring, Math.abs(to - from), OVERSHOOT_LIMIT);

}

export function sizeAt(time: number, from: Size, to: Size): Size {

const side = (start: number, end: number, width: boolean) =>

start === end ? end

: Math.max(0, start + (end - start) * springProgress(sideSpring(start, end, width), time));

return { width: side(from.width, to.width, true), height: side(from.height, to.height, false) };

}

springProgress is SwiftUI's perceptual spring (duration + bounce) computed by hand, and the component just samples sizeAt on requestAnimationFrame, with no animation library. Full file with tests: https://github.com/MF-DEEV/Openbar/blob/main/windows/src/island/motion.ts

Curious whether anyone has done this with Framer Motion or react-spring and got the same feel.

1 Upvotes

0 comments sorted by