Spring Animation Configuration for Gesture-Driven Interactions

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.

The repository defines two sanctioned approaches in 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:

{ 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:

{ 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 (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 (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 and feed the release velocity into the animation. The following example, aligned with skills/emil-design-eng/SKILL.md and skills/apple-design/SKILL.md (lines 88‑110), demonstrates a draggable bottom sheet that retains momentum on release:

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 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:

.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 (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 (lines 62‑66) to ensure gesture-driven motion uses springs.

Frequently Asked Questions

The single source of truth resides in 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 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 and 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, with enforcement criteria documented in skills/improve-animations/AUDIT.md. Conceptual justification for using springs in gestures appears in skills/apple-design/SKILL.md (lines 62 and 88‑110).

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →