animejs-v4

Anime.js 4.0 for Web Components

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "animejs-v4" with this command: npx skills add matthewharwood/fantasy-phonics/matthewharwood-fantasy-phonics-animejs-v4

Anime.js 4.0 for Web Components

Installation

npm i animejs

import { animate, createTimeline, stagger, createSpring, createDraggable } from 'animejs'; import { createDrawable, createMotionPath, morphTo, splitText, onScroll } from 'animejs';

Core API

Basic Animation

animate('.el', { x: 250, y: 100, rotate: 90, scale: 1.5, opacity: 0.5, backgroundColor: '#FFF', duration: 1000, delay: 200, ease: 'outQuad', loop: true, alternate: true });

Per-Property Control

animate('.el', { x: { from: -100, to: 100, duration: 800 }, rotate: { from: 0, to: 360, ease: 'inOutCirc' }, scale: { to: 1.5, delay: 200 } });

Keyframes

animate('.el', { y: [0, -50, 0], scale: [1, 1.2, 1], duration: 1000 });

Stagger

animate('.items', { y: -20, opacity: [0, 1], delay: stagger(100), // Sequential delay: stagger(100, { from: 'center' }), // From center delay: stagger(50, { grid: [5, 5] }) // Grid layout });

Function-Based Values

animate('.items', { x: (el, i, total) => i * 50, rotate: (el, i) => i % 2 === 0 ? 45 : -45 });

Playback Control

const anim = animate('.el', { x: 100, autoplay: false });

anim.play(); anim.pause(); anim.reverse(); anim.restart(); anim.seek(500); // Seek to 500ms anim.seek('50%'); // Seek to 50%

Method Behavior

cancel()

Stop immediately, keep current inline styles

revert()

Stop and remove all inline styles

complete()

Jump to final values immediately

Callbacks & Promises

animate('.el', { x: 100, onBegin: (anim) => {}, onUpdate: (anim) => {}, onComplete: (anim) => {} });

await animate('.el', { x: 100 }); // Promise-based

Timeline

const tl = createTimeline({ loop: true, alternate: true }); tl.add('.box1', { x: 100 }) .add('.box2', { y: 50 }, '-=200') // 200ms before previous ends .add('.box3', { scale: 2 }, '+=100') // 100ms after previous .add('.box4', { rotate: 90 }, 500); // At 500ms absolute

tl.label('myLabel', 1000); tl.call(() => console.log('done'), 2000);

Easings & Springs

Built-in: linear , in , out , inOut , outIn (with power: out(3) ). Named: inQuad , outQuad , inOutQuad , inCubic , outExpo , inOutElastic , outBounce , outBack .

// Spring physics animate('.el', { x: 100, ease: createSpring({ stiffness: 400, damping: 25 }) });

Spring Presets

const springs = { click: createSpring({ stiffness: 600, damping: 30 }), move: createSpring({ stiffness: 300, damping: 25 }), drop: createSpring({ stiffness: 400, damping: 20 }), settle: createSpring({ stiffness: 200, damping: 25 }), bounce: createSpring({ stiffness: 500, damping: 10 }) };

Web Component Integration

Animation Manager Pattern

Always cancel existing animations before starting new ones. Use a WeakMap to track animations per element without memory leaks.

class AnimationManager { #anims = new WeakMap();

animate(el, props, key = 'main') { const map = this.#anims.get(el) || {}; map[key]?.cancel(); // Cancel existing

const anim = animate(el, props);
map[key] = anim;
this.#anims.set(el, map);
return anim;

}

cancel(el, key = 'main') { this.#anims.get(el)?.[key]?.cancel(); } revert(el, key = 'main') { this.#anims.get(el)?.[key]?.revert(); } }

Component Lifecycle

Follows web-components-architecture skill — use disconnectedCallback for cleanup:

class AnimatedCard extends HTMLElement { #anim = null;

animate(props) { this.#anim?.cancel(); this.#anim = animate(this, props); return this.#anim; }

disconnectedCallback() { this.#anim?.revert(); // Clean up inline styles } }

Drag-and-Drop Animations

Drag Start (Lift)

function animateDragStart(card) { return animate(card, { scale: 1.12, rotate: 8, boxShadow: '0 20px 50px rgba(0,0,0,0.3)', duration: 150, ease: 'out(3)' }); }

During Drag — Direct Transform (60fps)

Do NOT use animate() for pointer tracking. Set transform directly for smooth motion:

function updateDragPosition(el, x, y) { el.style.transform = translate(${x}px, ${y}px) scale(1.12) rotate(8deg); }

Drop Animation

function animateDrop(card) { return animate(card, { x: 0, y: 0, scale: [1.12, 0.95, 1], rotate: [8, -2, 0], boxShadow: '0 2px 8px rgba(0,0,0,0.1)', duration: 350, ease: 'outBack' }); }

Return to Origin

function animateReturn(card) { return animate(card, { x: 0, y: 0, scale: 1, rotate: 0, duration: 400, ease: 'outBack' }); }

Card Swap (FLIP Pattern)

async function animateSwap(cardA, cardB, slotA, slotB) { const rectA = cardA.getBoundingClientRect(); const rectB = cardB.getBoundingClientRect();

// DOM swap first slotA.appendChild(cardB); slotB.appendChild(cardA);

const newRectA = cardA.getBoundingClientRect(); const newRectB = cardB.getBoundingClientRect();

// Animate from old positions await Promise.all([ animate(cardA, { x: [rectA.left - newRectA.left, 0], y: [rectA.top - newRectA.top, 0], scale: [1.1, 0.95, 1], duration: 400, ease: 'outBack' }), animate(cardB, { x: [rectB.left - newRectB.left, 0], y: [rectB.top - newRectB.top, 0], scale: [1, 1.05, 1], duration: 400, ease: 'outBack' }) ]); }

Slot Hover Feedback

function animateSlotHover(slot, isOver) { animate(slot, { scale: isOver ? 1.03 : 1, borderColor: isOver ? '#4CAF50' : '#999', duration: 150, ease: 'out(2)' }); }

Click Animations

// Bounce feedback animate(card, { scale: [1, 1.15, 1], rotate: [0, 5, -5, 0], duration: 400, ease: 'outElastic(1, 0.5)' });

// Disabled shake animate(card, { x: [0, -8, 8, -6, 6, 0], duration: 300, ease: 'linear' });

Scroll-Driven Animation

animate('.el', { x: 300, autoplay: onScroll({ target: '.el', enter: 'bottom', leave: 'top', sync: true }) });

SVG Animations

animate(createDrawable('path'), { draw: '0 1' }); // Draw path animate('.el', { ...createMotionPath('.path') }); // Motion path animate('.shape1', { d: morphTo('.shape2') }); // Morph shapes

Text Splitting

const { chars } = splitText('.text', { chars: true }); animate(chars, { y: [20, 0], opacity: [0, 1], delay: stagger(30) });

Built-in Draggable

createDraggable('.el', { x: true, y: true, snap: 50, container: '.bounds', releaseEase: createSpring({ stiffness: 120, damping: 6 }), onDrag: (d) => {}, onRelease: (d) => {} });

V3 to V4 Migration

V3 V4

anime({ targets: '.el' })

animate('.el', {...})

easing: 'easeOutQuad'

ease: 'outQuad'

direction: 'alternate'

alternate: true

translateX: 100

x: 100

anime.stagger(100)

stagger(100)

.finished

.then() or await

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

ux-spacing-layout

No summary provided by upstream source.

Repository SourceNeeds Review
General

audio-design

No summary provided by upstream source.

Repository SourceNeeds Review
General

web-components-architecture

No summary provided by upstream source.

Repository SourceNeeds Review
General

ux-iconography

No summary provided by upstream source.

Repository SourceNeeds Review