@omicrxn/mercury
Version:
Mercury is a Svelte animation library powered by Motion. It simplifies complex animations with Svelte actions, provides layout and exit animations, and integrates seamlessly with Svelte features.
67 lines (66 loc) • 2.1 kB
JavaScript
import { tick } from 'svelte';
import { DEFAULT_LAYOUT_CHILDREN, loadAnime, mapTransitionToAnimeLayout, prefersReducedMotion } from './layout-anime.js';
async function flushDom() {
await tick();
await new Promise((resolve) => queueMicrotask(() => resolve()));
await tick();
await new Promise((resolve) => queueMicrotask(() => resolve()));
if (typeof requestAnimationFrame !== 'undefined') {
await new Promise((resolve) => requestAnimationFrame(() => resolve()));
}
}
export class LayoutScopeController {
#instance = null;
#pending = null;
#options;
constructor(options) {
this.#options = options;
}
setOptions(options) {
this.#options = options;
}
async mount(element) {
const anime = await loadAnime();
const { states, children, transition, callbacks } = this.#options;
this.#instance = anime.createLayout(element, {
children: children ?? DEFAULT_LAYOUT_CHILDREN,
...mapTransitionToAnimeLayout(transition, callbacks, anime),
...states
});
this.#instance.record();
}
record() {
this.#instance?.record();
}
async animate() {
if (!this.#instance)
return;
if (prefersReducedMotion()) {
this.#instance.record();
return;
}
this.#pending?.cancel();
await flushDom();
if (!this.#instance)
return;
const anime = await loadAnime();
const baseCallbacks = this.#options.callbacks ?? {};
const params = mapTransitionToAnimeLayout(this.#options.transition, {
...baseCallbacks,
onComplete: () => {
baseCallbacks.onComplete?.();
this.#instance?.record();
}
}, anime);
this.#pending = this.#instance.animate(params);
}
dispose() {
this.#pending?.cancel();
this.#instance?.revert();
this.#instance = null;
this.#pending = null;
}
}
if (typeof window !== 'undefined') {
void loadAnime();
}