-
Notifications
You must be signed in to change notification settings - Fork 8
feat: Effects Micro-Interactions & Animation — Damped Knobs, Meter Physics, Transition Polish #1242
Description
Epic: Effects Micro-Interactions & Animation
Motivation
The difference between a professional plugin and a toy is in the micro-interactions. When you drag a FabFilter knob, there's a sense of weight and precision. When an iZotope meter moves, it has physical inertia. When a Soundtoys tube warms up, you feel the glow. These details are what makes artists say "this tool feels good" and keep coming back.
ACE-Step's current interactions are functional but lack any sense of physicality or craftsmanship. The only animation is hover:scale-110 on knobs. No transitions on parameter changes, no physics on meters, no feedback on state changes.
Design Philosophy: Reference-Driven Motion Design
MANDATORY: Before implementing ANY animation or interaction refinement:
- Screen-record the equivalent interaction in 3+ professional plugins (GIF or video)
- Study timing: How many milliseconds is the transition? What easing curve? What overshoots?
- Study physics: Does the meter have inertia? Does the knob have resistance? Is there overshoot/bounce?
- Document:
.llm/research/ui-references/animation-{element}-references.mdwith frame-by-frame analysis- Match: Implement to match the feel of the best reference, then test by recording our version and comparing
Motion design is even harder than static design to "guess right" — always reference real plugins.
Current State
| Interaction | Current Behavior | Feel |
|---|---|---|
| Knob hover | hover:scale-110 (CSS transition 150ms) |
Minimal, OK |
| Knob drag | Instant value update, no smoothing | Abrupt |
| Knob release | Nothing | Dead |
| Slider drag | Instant fill update | Flat |
| GR meter | Bar width updates per frame (raw value) | Jumpy |
| Peak meter | Smooth fall (0.012/frame) + peak hold (18 frames) | Decent |
| Spectrum | Raw FFT draw per frame | Flickery |
| Effect bypass | opacity-45 transition |
OK but abrupt |
| Card expand | Not implemented | N/A |
| A/B switch | Not implemented | N/A |
| Parameter reset (double-click) | Instant jump to default | Jarring |
Implementation Plan
1. Knob Micro-Interactions
1.1 — Drag physics
- Value smoothing: When dragging, value follows mouse with slight easing (exponential smoothing, ~3 frames lag)
displayValue = displayValue + (targetValue - displayValue) × 0.3- Makes knob feel like it has slight mass/inertia
- Audio parameter updates instantly (no audible delay), only visual smooths
- Fine mode (Alt+drag): 4× reduced sensitivity
- Visual: Value arc color changes to indicate fine mode (e.g., brighter)
- Cursor changes (or indicator appears)
1.2 — Reset animation (double-click)
- Current: instant jump to default
- Target: animate from current value to default over 200ms with ease-out
- The arc smoothly sweeps to default position
- Brief "settled" pulse on the knob body (subtle brightness flash)
1.3 — Magnetic snap near default
- When value is within 3% of default, reduce drag sensitivity by 50%
- Makes it easy to return to exactly the default value
- Subtle haptic "click" feel (brief pause in smooth tracking)
1.4 — Active state
- During drag: knob body brightens 10%, shadow deepens slightly
- After release: 200ms fade back to normal
- Focus ring: thin accent-colored ring when keyboard-focused
1.5 — Value tooltip
- Appears 100ms after drag starts, positioned above knob
- Shows current value with unit (e.g., "-12.3 dB", "2.4 kHz", "150 ms")
- Follows knob value in real-time during drag
- Fades out 300ms after drag ends
- Semi-transparent dark background with slight blur
2. Meter Physics
2.1 — Gain reduction meter (Compressor/Limiter)
Study reference: FabFilter Pro-C 2 GR meter, Waves CLA-76 needle
- Ballistics: GR meter should have attack/release behavior matching the compressor's attack/release
- Fast attack: meter responds quickly to GR onset
- Slower release: meter falls back smoothly
displayGR = displayGR + (targetGR - displayGR) × (targetGR > displayGR ? attackCoeff : releaseCoeff)
- Overshoot: Slight overshoot on fast transients (meter briefly shows more GR than actual, then settles)
- Creates a sense of the compressor "working hard"
- Peak hold: Show peak GR value for 1.5 seconds before fading back
2.2 — VU-style meter smoothing
- For optional VU-style display mode (not just peak)
- Integration time: 300ms (standard VU response)
- Overshoot on transients: ~1.5% overshoot, damped oscillation
- Physical simulation:
acceleration = (target - position) × spring - velocity × damping
2.3 — Spectrum analyzer smoothing
- Current: raw FFT per frame — visually noisy/flickery
- Target: configurable smoothing
- Fast:
smooth = smooth × 0.7 + new × 0.3(good for detecting transients) - Medium:
smooth = smooth × 0.85 + new × 0.15(default, readable) - Slow:
smooth = smooth × 0.95 + new × 0.05(smooth, mastering analysis)
- Fast:
- Peak hold line: peaks stay for 2s, then fall at -20dB/s (like Logic's analyzer)
- Phosphor persistence effect: previous frame blended at 50% opacity (creates "afterglow")
3. State Transitions
3.1 — Effect bypass animation
- Current:
opacity-45instant toggle - Target:
- Bypass ON: Card dims over 200ms, visualization fades to gray, "BYPASS" watermark appears (subtle)
- Bypass OFF: Card brightens over 200ms, visualization colors restore
- The audio bypass itself is instant (no fade) — only visual transition is animated
3.2 — Effect card expand/collapse
- Expand: Height animates from compact to full over 250ms (ease-out)
- Visualization canvas resizes smoothly
- Controls reflow with staggered appear (30ms delay between each parameter row)
- Collapse: Reverse, 200ms
3.3 — Effect add/remove in chain
- Add: New card slides in from right and fades in (200ms)
- Remove: Card fades out and collapses height (200ms)
- Reorder (drag): Ghost card follows cursor, target position shows insertion marker
3.4 — A/B comparison toggle
- Smooth crossfade between A and B parameter visualizations (150ms)
- Knobs smoothly animate between A and B values
- Not a jump — a visible transition showing what changed
3.5 — Parameter change from external source (automation, preset load)
- When parameters change from automation playback or preset, knobs visually animate to new position
- 100ms transition to new value (not instant jump)
- Distinguishes "user is dragging" (smooth follow) from "preset loaded" (animated transition)
4. Hover & Focus Feedback
4.1 — Control hover states
- Knob hover: subtle scale (1.05×) + brightness increase (5%) — 150ms transition
- Slider hover: thumb brightens, track fill becomes more opaque — 100ms
- Button hover: background lightens — 100ms
- Canvas hover: cursor changes to crosshair, show coordinate tooltip
4.2 — Connected parameter highlighting
- When hovering a knob, if it affects the visualization, highlight the relevant part
- Hover "Frequency" knob → the EQ band point glows
- Hover "Threshold" knob → the threshold line in GR display pulses
- Hover "Decay" knob → the decay curve endpoint highlights
- Visual connection: thin dotted line from knob to affected visualization element (optional, for expanded mode)
4.3 — Keyboard focus indicators
- Tab navigation between controls: visible focus ring (2px accent-colored outline)
- Current focused control: slightly elevated (subtle shadow increase)
- Focus within card: card border brightens to indicate active editing
5. Loading & Processing States
5.1 — IR loading animation (Convolver)
- When loading a new impulse response: progress bar on card + waveform builds from left to right
- Completion: brief green flash on card header
5.2 — CPU indicator per effect
- Subtle CPU load indicator on card header (thin progress bar)
- Green: < 2%, Yellow: 2-5%, Red: > 5%
- Updates every 500ms (not real-time — avoid performance impact from measuring performance)
Technical Approach
- All animations use
requestAnimationFrame, not CSS transitions (for canvas elements) - CSS transitions for DOM element state changes (opacity, transform, color)
- Spring physics: custom spring simulation function (no external physics library)
- Parameter smoothing: separate display value (animated) from audio value (instant)
- All timing constants defined as named constants (easy to tune by comparing with references)
Acceptance Criteria
- Knob drag has visual smoothing (display value follows with ~3 frame lag)
- Knob double-click reset animates to default (200ms ease-out)
- Fine mode (Alt+drag) with 4× reduced sensitivity and visual indicator
- Value tooltip appears during knob drag (above knob, shows value + unit)
- GR meter has attack/release ballistics matching compressor timing
- Spectrum analyzer has configurable smoothing (fast/medium/slow) + peak hold
- Effect bypass has smooth visual transition (200ms dim/brighten)
- Card expand/collapse animates height smoothly (250ms)
- A/B toggle crossfades between parameter states
- Automation-driven parameter changes animate knob visuals (100ms transition)
- Hover on parameter highlights related visualization element
- All animation timing verified against reference recordings from professional plugins
- No animation drops audio performance (animations are visual-only, audio params update instantly)
- Reference recordings stored in
.llm/research/ui-references/animation-references/
References (MUST record and study before implementing)
- FabFilter Pro-Q 3: Record knob drag feel, band hover highlighting, resize animation
- FabFilter Pro-C 2: Record GR meter ballistics, threshold interaction, curve animation
- iZotope Ozone: Record spectrum smoothing, module expand animation, bypass transition
- Soundtoys Decapitator: Record knob resistance feel, tube warmth glow animation
- Ableton Live: Record device expand, knob drag, automation parameter animation
- Logic Pro: Record channel EQ band interaction, compressor curve, meter physics
- Apple Human Interface Guidelines — Animation — timing principles
- Material Design — Motion — easing curves reference