← Back to Web app developers

Skill · Version 1.0.0

Framework animation integration

Coordinates animations with component lifecycles so rendering, cancellation and navigation do not compete for the same properties.

framework-animation-integration

Team members using this skill

See how it helps

When is it useful?

Use when exit animations flicker or continue after a component disappears.

What does it help you do?

  • Assigns one owner to each animated DOM property.
  • Coordinates exit completion with removal and a bounded fallback.
  • Uses stable list keys and server-rendering-safe initialization.

Try asking this

Fix a closing panel that disappears before its animation finishes and leaves a running timer after navigation. Close, reopen and navigate away during the exit animation. The panel must finish in the requested state with no orphaned timer or hidden focus target.

Detailed documentation

Read the skill’s original instructions, examples and checks in their authored language.

Details…Show less

Framework Animation Integration

Declarative UI frameworks (React, Vue, Angular) own the virtual/template DOM and unmount elements immediately when state flips to false. Imperative animation engines (WAAPI, GSAP, Canvas/Three.js) mutate real DOM nodes over time. Prevent the framework and the animation engine from fighting over the same properties.

Single Owner Rule for DOM Properties

  • Never bind a reactive framework style prop and an imperative animation to the same CSS property on the same element: If a component re-renders mid-animation with :style="{ transform: ... }" or style={{ opacity }}, the framework overwrites the animation engine's interpolated frame value.
  • Either let the framework's native transition primitive drive the state, or give the imperative animation a dedicated wrapper <div ref="animEl"> whose transform/opacity is untouched by reactive template bindings.

Framework-Specific Lifecycle & Exit Patterns

Framework Idiomatic Entry / Exit & Layout Primitives Imperative Timeline / Canvas Integration
React Motion (<AnimatePresence> + <motion.div layout exit={{ ... }}> + useReducedMotion()) or CSS @starting-style Scope with useGSAP(() => { ... }, { scope: containerRef, dependencies: [...] }) or useLayoutEffect returning () => ctx.revert(). Never query document.querySelector outside containerRef.
Vue 3 Built-in <Transition name="..." mode="out-in"> and <TransitionGroup> (includes built-in FLIP via .v-move transition class!), plus JavaScript hooks (@enter, @leave(el, done)) Create gsap.context(..., containerRef.value) or WAAPI handles in onMounted(), call done() in @leave hooks only after exit animation finishes, and always call ctx?.revert() in onUnmounted().
Angular @angular/animations (animate.enter / animate.leave, route transition triggers) or CSS transitions bound to host state signals Run continuous requestAnimationFrame, WAAPI, or GSAP loops via NgZone.runOutsideAngular(() => ...) so 60fps ticks never trigger change detection across the component tree; clean up via DestroyRef.onDestroy(...).

Handling Unmount & Route Transitions Safely

  1. Wait for exit completion before DOM removal—with a fallback timeout:
    • When using JS-driven exit hooks (Vue @leave(el, done) or custom exit promises), always ensure done() is called even if the animation is cancelled or prefers-reduced-motion skips it; otherwise the detached DOM node remains stuck in the document forever.
  2. Stable keys in animated lists:
    • <TransitionGroup> (Vue), <AnimatePresence> (React), and @for (...; track item.id) (Angular) rely on stable, unique item keys to calculate FLIP deltas and exit targets. Never use array index (index) as the key of an animated list.
  3. SSR & Hydration safety:
    • Guard browser-only globals (window, document, matchMedia, ResizeObserver, IntersectionObserver) behind mount hooks (onMounted, useEffect, afterNextRender) so server-side rendering and hydration complete without mismatches.

Included files 1

  • SKILL.md