UNPKG

@omicrxn/mercury

Version:

Mercury is a Svelte animation library using AnimeJS under the hood. It simplifies complex animations with Svelte actions, provides layout and exit animations, and integrates seamlessly with Svelte features.

96 lines (95 loc) 3.41 kB
import { mapTransitionToAnimeJS } from '../utils.js'; let animeModule = null; let loadPromise = null; async function loadAnime() { if (animeModule) return animeModule; if (typeof window !== 'undefined' && window.anime) { animeModule = window.anime; return animeModule; } if (!loadPromise) { loadPromise = import('animejs').then((mod) => { animeModule = mod.default ?? mod; return animeModule; }, () => { throw new Error('Please install AnimeJS: npm install animejs'); }); } return loadPromise; } export const AnimeEngine = { animate(element, params) { const { animate: mercuryAnimation, transition: mercuryTransition, callbacks } = params; let animation = null; let animeReady = false; let pendingOperations = []; // Load AnimeJS in background loadAnime().then(anime => { animeReady = true; //Mapping animation to motion const animationOptions = mercuryAnimation; //Mapping transition to motion const transitionOptions = mapTransitionToAnimeJS(mercuryTransition, callbacks); transitionOptions.ease = mercuryTransition?.type === 'spring' ? anime.createSpring({ stiffness: mercuryTransition?.stiffness, damping: mercuryTransition?.damping, mass: mercuryTransition?.mass, velocity: mercuryTransition?.velocity }) : mercuryTransition?.ease; animation = anime.animate(element, { ...animationOptions, ...transitionOptions }); // Execute queued operations pendingOperations.forEach(op => op()); pendingOperations = []; }).catch(error => { console.error('Failed to load AnimeJS:', error); }); const instance = { completed: false, play: () => { if (animeReady && animation) { animation.restart(); } else { pendingOperations.push(() => animation?.restart()); } }, pause: () => { if (animeReady && animation) { animation.pause(); } else { pendingOperations.push(() => animation?.pause()); } }, cancel: () => { if (animeReady && animation) { animation.cancel(); } else { pendingOperations.push(() => animation?.cancel()); } }, onComplete: (onResolve) => { if (animeReady && animation) { return animation.then(() => { onResolve(); instance.completed = true; }); } else { pendingOperations.push(() => { animation?.then(() => { onResolve(); instance.completed = true; }); }); } } }; return instance; } };