motion-sv
v0.1.8
Published
Motion for Svelte
Readme
Motion For Svelte
This is an attempt to bring a Motion (formerly known as Framer Motion) to Svelte.
Quick Start
npm install motion-svThen import the motion component:
<script lang="ts">
import { motion } from "motion-sv";
</script>
<motion.div animate={{ x: 100 }}>Hello</motion.div>Key Differences from Framer Motion
Some Framer Motion features cannot be reproduced in Svelte with the same APIs.
Layout Animations
React uses getSnapshotBeforeUpdate and Vue uses onBeforeUpdate.
Svelte has no equivalent, so layout animations require a helper.
Enable them by wrapping motion with createLayoutMotion:
import { motion, createLayoutMotion } from "motion-sv";
const layout = createLayoutMotion(motion);createLayoutMotion provides:
layout.update()— mark a layout change after state updates.layout.update.with(fn)— wrap a state update so layout changes are tracked automatically.
Usage:
<script lang="ts">
import { motion, createLayoutMotion } from "motion-sv";
let isOn = $state(false);
const layout = createLayoutMotion(motion);
const toggle = layout.update.with(() => (isOn = !isOn));
// or:
// function toggle() {
// isOn = !isOn;
// layout.update();
// }
</script>
<motion.button style={{ ...container, justifyContent: "flex-" + (isOn ? "start" : "end") }} onclick={toggle}>
<layout.div
style={handle}
layoutDependency={isOn}
transition={{ type: "spring", visualDuration: 0.2, bounce: 0.2 }}
/>
</motion.button>Use
layoutDependencyif the element is not being remounted. This gives motion a reactive trigger for the update.
Layout Animations with layoutId
Alternatively, use layoutId to link elements across renders:
<motion.button style={{ ...container, justifyContent: "flex-" + (isOn ? "start" : "end") }} onclick={toggle}>
{#if isOn}
<layout.div
style={handle}
layoutId="handle"
transition={{
type: "spring",
visualDuration: 0.2,
bounce: 0.2,
}}
/>
{:else}
<layout.div
style={handle}
layoutId="handle"
transition={{
type: "spring",
visualDuration: 0.2,
bounce: 0.2,
}}
/>
{/if}
</motion.button>Animate Presence (Enter/Exit)
- React: implemented with child diffing.
- Vue: uses
Transition/TransitionGroup. - Svelte: has no equivalent (issue #8547).
Limitations in this port:
- Variants with
AnimatePresence(e.g.when) may not work. - Rapid toggling can cause flickers instead of smooth reversal.
