# Spring Animation Configuration for Gesture-Driven Interactions

> Master spring animation configuration for gesture driven interactions. Learn to preserve velocity and avoid the brick wall effect for smoother user experiences.

- Repository: [Emil Kowalski/skills](https://github.com/emilkowalski/skills)
- Tags: how-to-guide
- Published: 2026-08-02

---

**Use `{ type: "spring", duration: 0.5, bounce: 0.2 }` as the canonical configuration for gesture-driven interactions to preserve velocity and prevent the "brick-wall" effect when users reverse direction mid-animation.**

The `emilkowalski/skills` repository codifies design-engineering best practices for web UI animations, establishing a single source of truth for motion parameters. Mastering the correct **spring animation configuration for gesture-driven interactions** ensures that drag, swipe, and flick motions feel physically responsive rather than robotic, because springs settle based on momentum rather than fixed durations.

## Recommended Spring Parameters

The repository defines two sanctioned approaches in [`skills/review-animations/STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md), depending on whether you prefer perceptual timing or traditional physics constants.

### Apple-Style Spring (Default)

For most gesture-driven components, use the standard Apple-style spring defined at lines 65‑68:

```javascript
{ type: "spring", duration: 0.5, bounce: 0.2 }

```

- **`duration`**: Approximately 0.5 seconds provides a perceptually quick settle without feeling rushed.
- **`bounce`**: A value of 0.2 keeps overshoot subtle; the acceptable range is **0.1‑0.3** according to the standards.

### Traditional Physics Spring

For tighter control over the physical model, reference the alternative configuration at lines 69‑71:

```javascript
{ type: "spring", mass: 1, stiffness: 100, damping: 10 }

```

This explicit mass‑stiffness‑damping model is useful when you need to fine‑tune the response curve for specific input devices or accessibility requirements.

## Why Springs Are Required for Gesture-Driven Motion

Springs convey physical feel because they have no fixed duration; they settle dynamically based on velocity, mass, and damping. According to [`skills/improve-animations/AUDIT.md`](https://github.com/emilkowalski/skills/blob/main/skills/improve-animations/AUDIT.md) (lines 62‑66), **gesture-driven motion should use springs** because they carry velocity when interrupted.

CSS transitions and keyframes cannot retain velocity. As noted in [`skills/apple-design/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/apple-design/SKILL.md) (line 62), using CSS for interruptible gestures creates a "brick‑wall" effect where the animation either retargets abruptly or restarts from zero. Springs avoid this by re‑targeting mid‑flight, yielding seamless motion when a user reverses a drag or dismisses a toast.

## Implementing Gesture-Driven Springs with Motion

When implementing with the Motion library (Framer Motion compatible), pass the spring configuration from [`STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/STANDARDS.md) and feed the release velocity into the animation. The following example, aligned with [`skills/emil-design-eng/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/emil-design-eng/SKILL.md) and [`skills/apple-design/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/apple-design/SKILL.md) (lines 88‑110), demonstrates a draggable bottom sheet that retains momentum on release:

```tsx
import { motion, useMotionValue, useSpring } from "motion/react";

function BottomSheet() {
  const y = useMotionValue(0);
  
  // Apply the canonical spring config from STANDARDS.md lines 65-68
  const springY = useSpring(y, {
    type: "spring",
    duration: 0.5,   // STANDARDS.md line 67
    bounce: 0.2,     // STANDARDS.md line 67
    // Optional: traditional physics override from lines 69-71
    // mass: 1, stiffness: 100, damping: 10
  });

  const handleDragEnd = (event, info) => {
    // Calculate release velocity (px per ms) and pass it to the spring
    const velocity = info.velocity.y / Math.abs(info.point.y - info.startPoint.y);
    springY.set(springY.get(), { velocity });
  };

  return (
    <motion.div
      style={{ y: springY }}
      drag="y"
      dragConstraints={{ top: -300, bottom: 0 }}
      onDragEnd={handleDragEnd}
      className="bottom-sheet"
    >
      {/* Sheet content */}
    </motion.div>
  );
}

```

## Performance and Auditing Guidelines

Springs run on the JavaScript thread but remain lightweight because they animate only `transform`‑related properties, avoiding layout thrashing. However, the auditing rules in [`skills/improve-animations/AUDIT.md`](https://github.com/emilkowalski/skills/blob/main/skills/improve-animations/AUDIT.md) mandate that springs be used **only** for gesture‑driven motion where the target can change mid‑flight.

For static, predetermined motion—such as a simple fade‑in or button hover—prefer CSS transitions to keep the main thread free:

```css
.button {
  transform: scale(0.97);
  transition: transform 160ms var(--ease-out); /* Referenced in STANDARDS.md line 32 */
}

```

## Summary

- **Canonical configuration**: Use `{ type: "spring", duration: 0.5, bounce: 0.2 }` from [`skills/review-animations/STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md) (lines 65‑68) for all gesture-driven interactions.
- **Velocity retention**: Always pass the release velocity to the spring API so interruptions feel physically continuous.
- **Scope restriction**: Reserve springs for interruptible gestures; use CSS transitions for static, predetermined animations.
- **Auditing**: Follow the enforcement rules in [`skills/improve-animations/AUDIT.md`](https://github.com/emilkowalski/skills/blob/main/skills/improve-animations/AUDIT.md) (lines 62‑66) to ensure gesture-driven motion uses springs.

## Frequently Asked Questions

### What is the exact spring configuration recommended for gesture-driven interactions?

The single source of truth resides in [`skills/review-animations/STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md) at lines 65‑68: `{ type: "spring", duration: 0.5, bounce: 0.2 }`. This Apple-style spring provides a 0.5‑second settle time with subtle overshoot (bounce 0.2), perfectly balancing responsiveness with physical realism.

### Why do gesture-driven interactions require springs instead of CSS transitions?

CSS transitions cannot retain velocity when interrupted; they either retarget abruptly or restart from zero, creating what [`skills/apple-design/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/apple-design/SKILL.md) calls the "brick‑wall" effect (line 62). Springs maintain momentum mathematically, allowing the animation to re‑target mid‑flight when a user reverses direction or interrupts a gesture.

### How do I calculate and apply velocity when a user releases a drag gesture?

Compute the release velocity by dividing the gesture's pixel velocity by the elapsed distance, then pass it to the spring's `velocity` option. In the Motion library, this means calling `springY.set(currentPosition, { velocity: calculatedVelocity })` inside the `onDragEnd` handler, as demonstrated in [`skills/emil-design-eng/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/emil-design-eng/SKILL.md) and [`skills/apple-design/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/apple-design/SKILL.md) (lines 88‑110).

### Where does the Skills repository define these animation standards?

All spring parameters and auditing rules are centralized in [`skills/review-animations/STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md), with enforcement criteria documented in [`skills/improve-animations/AUDIT.md`](https://github.com/emilkowalski/skills/blob/main/skills/improve-animations/AUDIT.md). Conceptual justification for using springs in gestures appears in [`skills/apple-design/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/apple-design/SKILL.md) (lines 62 and 88‑110).