ux-animation-motion

UX Animation & Motion Skill

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 "ux-animation-motion" with this command: npx skills add matthewharwood/fantasy-phonics/matthewharwood-fantasy-phonics-ux-animation-motion

UX Animation & Motion Skill

Animation system using Anime.js v4 for responsive, accessible UI motion. This skill covers animation patterns, timing, and reduced motion support.

Related Skills

  • animejs-v4 : Complete Anime.js 4.0 API reference

  • js-micro-utilities : Array utilities like .at(-1) for accessing last element

  • ux-iconography : Icon animation patterns

  • ux-accessibility : Reduced motion requirements

Animation Import

import { animate } from 'animejs';

Note: Project uses import maps to resolve animejs to local node_modules.

Animation Utilities

The project provides reusable animations in js/utils/animations.js :

import { shake, pressEffect, successBounce, glow, DURATION, EASE } from '../../utils/animations.js';

Duration Constants

const DURATION = { instant: 100, // Micro-interactions quick: 200, // Button press, toggles normal: 300, // Standard transitions slow: 500, // Page transitions celebration: 600 // Success animations };

Easing Functions

const EASE = { snap: 'easeOutQuad', // Quick, snappy feel smooth: 'easeInOutQuad', // Gentle transitions bounceOut: 'easeOutBack' // Playful, overshooting };

Animation Patterns

Press Effect (Tactile Feedback)

For button clicks and taps:

pressEffect(element); // or animate(element, { scale: [1, 0.95, 1], duration: DURATION.instant, ease: EASE.snap });

Success Bounce

For completed actions:

successBounce(element); // or animate(element, { scale: [1, 1.1, 1], duration: DURATION.normal, ease: EASE.bounceOut });

Shake (Error/Invalid)

For validation failures:

shake(element, { intensity: 6 }); // or animate(element, { translateX: [-6, 6, -6, 6, -3, 3, 0], duration: DURATION.normal, ease: EASE.snap });

Glow Effect

For achievements or highlights:

glow(element, { color: 'rgba(74, 222, 128, 0.6)', intensity: 15 }); // Uses box-shadow animation

Pulse (Attention)

For elements requiring attention:

@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }

.attention { animation: pulse 1.5s ease-in-out infinite; }

Transition Patterns

Fade In

animate(element, { opacity: [0, 1], duration: DURATION.normal, ease: EASE.smooth });

Slide In

animate(element, { translateY: [20, 0], opacity: [0, 1], duration: DURATION.normal, ease: EASE.snap });

Scale In

animate(element, { scale: [0.9, 1], opacity: [0, 1], duration: DURATION.quick, ease: EASE.bounceOut });

Staggered List

animate('.list-item', { translateY: [20, 0], opacity: [0, 1], delay: (el, i) => i * 50, duration: DURATION.normal, ease: EASE.snap });

State Change Animations

Attribute Change Response

attributeChangedCallback(name, oldVal, newVal) { if (name === 'completed' && newVal !== null) { this.#animateComplete(); } }

#animateComplete() { animate(this, { scale: [1, 2, 1], duration: DURATION.normal, ease: EASE.bounceOut }); }

Phase Transition

#animatePhaseChange() { animate(this.#container, { opacity: [1, 0, 1], duration: DURATION.slow, ease: EASE.smooth }); }

Game Feedback Animations

Word Completion

#celebrateWord() { successBounce(this.#wordElement); glow(this.#wordElement, { color: 'rgba(74, 222, 128, 0.6)' }); }

Score Update

#animateScore() { animate(this.#scoreElement, { scale: [1, 1.2, 1], duration: DURATION.quick, ease: EASE.bounceOut }); }

Achievement Unlock

#celebrateAchievement() { animate(this.#badge, { scale: [0, 1.2, 1], rotate: [0, -10, 10, 0], duration: DURATION.celebration, ease: EASE.bounceOut }); }

Reduced Motion Support

Check Preference

const prefersReducedMotion = window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches;

if (!prefersReducedMotion) { animate(element, { scale: [1, 1.1, 1] }); } else { // Instant state change instead element.classList.add('completed'); }

CSS Fallback

@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } }

Safe Animation Wrapper

function safeAnimate(element, props) { if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) { // Apply final state immediately if (props.scale) element.style.transform = scale(${props.scale.at(-1)}); if (props.opacity) element.style.opacity = props.opacity.at(-1); return; } return animate(element, props); }

CSS Transitions

For simple state changes, prefer CSS:

.button { transition: background-color 0.15s ease, transform 0.1s ease, opacity 0.15s ease; }

.button:hover { background: var(--color-hover-overlay); }

.button:active { transform: scale(0.98); }

Loading Animations

Spinner

.spinner { width: 24px; height: 24px; border: 2px solid var(--theme-outline); border-top-color: var(--theme-primary); border-radius: 50%; animation: spin 0.6s linear infinite; }

@keyframes spin { to { rotate: 360deg; } }

Dots

.loading-dots span { animation: bounce 1s ease-in-out infinite; }

.loading-dots span:nth-child(2) { animation-delay: 0.1s; } .loading-dots span:nth-child(3) { animation-delay: 0.2s; }

@keyframes bounce { 0%, 80%, 100% { transform: translateY(0); } 40% { transform: translateY(-6px); } }

Performance Guidelines

Do

  • Use transform and opacity for smooth 60fps

  • Keep animations under 300ms for interactions

  • Use will-change sparingly for complex animations

  • Cancel animations when element unmounts

Don't

  • Animate width , height , margin , padding

  • Use long durations for frequent interactions

  • Chain many sequential animations

  • Animate elements off-screen

Cleanup

#animation = null;

disconnectedCallback() { if (this.#animation) { this.#animation.pause(); this.#animation = null; } }

Animation Timing Reference

Action Duration Easing

Button press 100ms easeOutQuad

Toggle switch 150ms easeOutQuad

Dropdown open 200ms easeOutQuad

Modal appear 200-300ms easeOutBack

Page transition 300-500ms easeInOutQuad

Success celebration 400-600ms easeOutBack

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

animejs-v4

No summary provided by upstream source.

Repository SourceNeeds Review
General

webgpu-canvas

No summary provided by upstream source.

Repository SourceNeeds Review
General

web-components-architecture

No summary provided by upstream source.

Repository SourceNeeds Review
General

audio-design

No summary provided by upstream source.

Repository SourceNeeds Review