anime-svelte
v0.0.1
Published
Svelte + Animejs integration. Small, reactive, and fully typed utilities for beautiful animations.
Readme
anime-svelte
Svelte + Animejs integration. Small, reactive, and fully typed utilities for beautiful animations.
Features
Multiple Animation Approaches
Components, transitions, and attachments for every use case
Reactive
Animations update reactively when parameters change
Type-Safe
Complete TypeScript support with animejs types
Extra Control
Pause, play, restart animations on demand, and define targets
Installation
npm install anime-svelte animejs
# or
pnpm add anime-svelte animejsQuick Start
Basic Animation with Component
<script>
import { Animate } from 'anime-svelte';
</script>
<Animate
params={{
opacity: [0, 1],
duration: 600,
rotate: [180, 0]
}}
>
<div class="box">I'm animated!</div>
</Animate>Text Animation with Split
<script>
import { Split } from 'anime-svelte';
import { stagger } from 'animejs';
</script>
<Split
split={{ chars: true }}
params={{
opacity: [0, 1],
translateY: [-10, 0],
delay: stagger(30),
duration: 400
}}
>
Amazing text
</Split>Transition Animation
<script>
import { anime } from 'anime-svelte';
let visible = $state(true);
</script>
<button onclick={() => visible = !visible}>Show/hide</button>
{#if visible}
<div
transition:anime={{
duration: 600,
opacity: [0, 1],
scale: [0.8, 1]
}}
>
Animated in and out!
</div>
{/if}Attachment Animation
<script>
import { animate } from 'anime-svelte';
</script>
<div {@attach animate({ rotate: 360, duration: 1000 })}>
Spinning element
</div>Components
<Animate>
Wraps elements with anime.js animations. Provides full reactive control with pause/play/restart methods.
Props:
paramsAnime.js animation parameters (duration, easing, targets, etc.)childrenContent to render inside the animated elementrootBindable reference to the animated DOM elementanimationBindable reference to the active anime.js instancetargetOptional function that returns animation target element or array...restStandard HTML attributes passed to the container
Methods:
getAnimation()Get the current anime.js animation instancerestart()Restart the animation from the beginningpause()Pause the animationplay()Resume the animation
Example:
<script>
import { Animate } from 'anime-svelte';
let animateComponent;
</script>
<Animate
bind:this={animateComponent}
params={{ opacity: [0, 1], duration: 600 }}
>
<h1>Hello</h1>
</Animate>
<button onclick={() => animateComponent.restart()}>
Restart
</button><Split>
Splits text into characters, words, or lines and animates each segment independently.
Props:
splitText splitting configuration (chars, words, lines)paramsAnimation parameters applied to each split elementrootBindable reference to the split containeranimationBindable reference to the active animation instance...restStandard HTML attributes passed to the container
Methods:
getAnimation()Get the current animation instance for the split textrestart()Restart the text split animationpause()Pause the animationplay()Resume the animation
Example:
<script>
import { Split } from 'anime-svelte';
import { stagger } from 'animejs';
</script>
<Split
split={{ words: true }}
params={{
opacity: [0, 1],
duration: 400,
delay: stagger(50)
}}
>
Animated text by words
</Split>Transitions
transition:anime
Apply animejs animations for element enter/exit transitions.
Parameters:
- AnimationParams & { easing?: (t: number) => number }
Example:
<script>
import { anime } from 'anime-svelte';
import { expoOut } from 'svelte/easing';
</script>
<div
transition:anime={{
duration: 600,
easing: expoOut,
opacity: [0, 1],
scale: [0.8, 1]
}}
>
Animated with transitions!
</div>Attachments
Attachments allow you to apply animations without wrapping elements.
{@attach animate(params)}
Parameters:
paramsAnime.js animation parameters (duration, easing, targets, etc.)
Example:
<script>
import { animate } from 'anime-svelte';
</script>
<div {@attach animate({ rotate: 360, duration: 1000 })}>
Spinning element
</div>{@attach split()}
Split text and apply animations to each segment using an attachment.
Parameters:
splitParamsText splitting configuration (chars, words, lines)paramsAnimation parameters applied to split elements
Example:
<script>
import { split } from 'anime-svelte';
import { stagger } from 'animejs';
</script>
<p {@attach split({ words: true }, { opacity: [0, 1], stagger: 50, duration: 400 })}>
Animated text by words
</p>Select the right Approach
- Components for extra control (target, pause, play, restart)
- Transitions for element enter/exit animations
- Attachments for text animations or simple animations without wrapping
Examples
Staggered Animations
<script>
import { Animate } from 'anime-svelte';
import { stagger } from 'animejs';
</script>
<Animate
target={(el) => el.children}
params={{
opacity: [0, 1],
translateY: [-20, 0],
delay: stagger(100),
duration: 500
}}
>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</Animate>Targeting Multiple Elements
<script>
import { Animate } from 'anime-svelte';
</script>
<Animate
target={(el) => [el.querySelector('.title'), el.querySelector('.subtitle')]}
params={{
opacity: [0, 1],
delay: [0, 200],
duration: 600
}}
>
<h1 class="title">Title</h1>
<p class="subtitle">Subtitle</p>
<p>not animated</p>
</Animate>Conditional Animations
<script>
import { Animate } from 'anime-svelte';
let visible = $state(false);
</script>
{#if visible}
<Animate params={{ opacity: [0, 1], duration: 600 }}>
<div>Conditionally animated content</div>
</Animate>
{/if}
<button onclick={() => visible = !visible}>
Toggle
</button>Multiple animations on same element
For independent animations on the same element, use attachments:
<div
{@attach animate({ rotate: 45, duration: 1000 })}
{@attach split({ chars: true }, { opacity: [0, 1], delay: stagger(50) })}
>
Animated text
</div>Roadmap
Planned features:
- [ ] Draggable support
- [ ] Layout animations
- [ ] Timeline support
Contributing
Feedback, issues, and contributions are welcome!
License
This project is licensed under the MIT License. See the LICENSE file for details.
