Timing and Springs

withTiming, withSpring and withDecay

Reanimated 11,010 's animation functions return a description that starts when you assign it to a shared value. withTiming(to, { duration, easing }) defaults to 300 ms and Easing.inOut(Easing.quad). withSpring(to, config) is physics-based: Reanimated 4's default is a critically damped spring (stiffness 900, damping 120, mass 4) that settles without overshoot, and passing duration or dampingRatio switches it to a duration-based spring that ends on time. withDecay({ velocity }) coasts from a velocity in pixels per second with deceleration 0.998 and can clamp to a range. withSequence(), withDelay() and withRepeat() compose them:

src/rea/Drivers.tsx: four animations on four shared values (excerpt)TSX
    const done = (name: string, v: SharedValue<number>) => (finished?: boolean) => {
      'worklet';
      scheduleOnRN(log, name, 'finished:', finished, 'at', Math.round(v.value));
    };
    a.value = withTiming(240, { duration: 800 }, done('withTiming', a));
    b.value = withSpring(240, undefined, done('withSpring (default)', b));
    c.value = withSpring(240, { duration: 800, dampingRatio: 0.4 }, done('withSpring 0.4', c));
    d.value = withDecay({ velocity: 1200, clamp: [0, 240] }, done('withDecay', d));
Output
 LOG  +544ms withDecay finished: true at 240
 LOG  +1138ms withTiming finished: true at 240
 LOG  +1162ms withSpring (default) finished: true at 240
 LOG  +1208ms withSpring 0.4 finished: true at 240

The decay hit its clamp first. The bouncy duration-based spring ended with the 800 ms timing (both late on the busy emulator), which is its point: it lines up with other motion. An interrupted animation reports finished: false, so check the flag before chaining work.