Codync
免费开源的 1:1 Grok Bot 与 Muse 替代方案。可在 iPhone、Mac 或 Linux 桌面上将 Claude 代码、Codex、Cursor 以及 40 多个编码代理作为持久机器人使用。支持群组聊天、线程、应用。
AI 翻译
Framer Motion for Svelte 5. Declarative motion.<tag> components with AnimatePresence exit animations, gestures (hover, tap, drag, focus, in-view), variants, FLIP layout animations, shared-layout transitions, spring physics, and scroll-linked motion values. The drop-in Framer Motion alternative for Svelte and SvelteKit.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Svelte Motion brings a Framer Motion-style API to Svelte 5 with motion.<tag> components, gestures, variants, exit animations, layout animation, and utility hooks.
For the latest documentation and examples, visit motion.svelte.page.
npm install @humanspeak/svelte-motion
<script lang="ts">
import { motion } from '@humanspeak/svelte-motion'
</script>
<motion.button initial={{ opacity: 0 }} animate={{ opacity: 1 }} whileTap={{ scale: 0.97 }}>
Hello motion
</motion.button>
Contributing to this repository? See CONTRIBUTING.md for setup and verification.
Goal: Framer Motion API parity for Svelte where common React examples can be translated with minimal changes.
| Capability | Status |
|---|---|
initial / animate / transition | Supported |
variants (string keys + inheritance, function-form custom) | Supported |
whileHover / whileTap / whileFocus / whileDrag / whileInView | Supported (inline + variant keys / arrays) |
Drag (drag, constraints, momentum, controls, callbacks) | Supported |
AnimatePresence (initial, mode, onExitComplete) | Supported |
Layout (layout, layout="position") | Supported (single-element FLIP) |
Shared layout (layoutId, LayoutGroup, layoutScroll) | Supported |
| Reorder (Motion 13.1 auto-axis, wrapped grids, RTL, edge auto-scroll) | Supported |
View Transitions (animateView, shared-element morphs) | Supported |
Vanilla values (motionValue, styleEffect, toMotionValue bridge) | Supported |
Custom effects (createEffect, animate.addEffect, Motion 13.2) | Supported |
Three.js / vgpu adapters (/three, /vgpu subpaths) | Supported |
Pan gesture API (onPan*, onPanSessionStart) | Supported |
MotionConfig (transition, reducedMotion, skipAnimations, transformPagePoint) | Supported |
Remaining MotionConfig options (features, nonce, isValidProp) | Not yet supported |
Motion components are generated from canonical HTML/SVG tag lists and exported from src/lib/html/.
motion.div, motion.button, motion.svg, motion.path, etc.arc() curved motion paths via transition.path (keyframes, layout, animate())script, style, link, meta, title, head, html, body.motion.<tag>Use motion components the same way you use regular elements, with animation props:
<motion.div
initial={{ opacity: 0, y: 8 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.25 }}
/>
MotionConfigMotionConfig supports default transition values, reducedMotion, skipAnimations, and Motion-compatible transformPagePoint coordinate correction for descendant drag and pan gestures. See the coordinate contract for session, scroll, constraints, and controls behavior.
<script lang="ts">
import { MotionConfig, motion } from '@humanspeak/svelte-motion'
</script>
<MotionConfig
transition={{ duration: 0.4 }}
reducedMotion="user"
transformPagePoint={({ x, y }) => ({ x: x / 0.5, y: y / 0.5 })}
>
<motion.div animate={{ scale: 1.05 }} />
</MotionConfig>
AnimatePresenceExit animations on unmount with support for mode="sync" | "wait" | "popLayout" and onExitComplete.
<script lang="ts">
import { AnimatePresence, motion } from '@humanspeak/svelte-motion'
let show = $state(true)
</script>
<AnimatePresence mode="wait" onExitComplete={() => console.log('done')}>
{#if show}
<motion.div
key="card"
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.9, transition: { duration: 0.2 } }}
/>
{/if}
</AnimatePresence>
<motion.button whileTap={{ scale: 0.97 }} onclick={() => (show = !show)}>Toggle</motion.button>
Notes:
AnimatePresence require key.{ duration: 0.35 } < merged transition < exit.transition.whileHover<motion.button whileHover={{ scale: 1.05, transition: { duration: 0.12 } }} />
(hover: hover) and (pointer: fine)).onHoverStart and onHoverEnd.whileTap<motion.button whileTap={{ scale: 0.95 }} />
onTapStart, onTap, onTapCancel.whileFocus<motion.button whileFocus={{ scale: 1.05, outline: '2px solid blue' }} />
onFocusStart and onFocusEnd.whileInView<motion.div
initial={{ opacity: 0, y: 40 }}
whileInView={{ opacity: 1, y: 0 }}
onInViewStart={() => console.log('entered')}
onInViewEnd={() => console.log('left')}
/>
IntersectionObserver.viewport options yet).Supported drag props:
drag: true | 'x' | 'y'dragConstraints: pixel object or element refdragElastic, dragMomentum, dragTransitiondragDirectionLock, dragPropagation, dragSnapToOrigindragListener, dragControlswhileDragonDragStart, onDrag, onDragEnd, onDirectionLock, onDragTransitionEnd<script lang="ts">
import { createDragControls, motion } from '@humanspeak/svelte-motion'
const controls = createDragControls()
</script>
<button onpointerdown={(e) => controls.start(e)}>Start drag</button>
<motion.div
drag="x"
dragControls={controls}
dragListener={false}
dragConstraints={{ left: -120, right: 120 }}
whileDrag={{ scale: 1.03 }}
/>
<script lang="ts">
import { motion, type Variants } from '@humanspeak/svelte-motion'
let open = $state(false)
const parent: Variants = {
open: { opacity: 1 },
closed: { opacity: 0 }
}
const child: Variants = {
open: { x: 0, opacity: 1 },
closed: { x: -16, opacity: 0 }
}
</script>
<motion.ul variants={parent} initial="closed" animate={open ? 'open' : 'closed'}>
<motion.li variants={child}>Item A</motion.li>
<motion.li variants={child}>Item B</motion.li>
</motion.ul>
variants.(custom) => keyframes factory. The custom prop is forwarded — useful for staggered lists where each child needs its own offset or delay. Children without custom inherit the nearest motion ancestor's value.<script lang="ts">
import { motion, type Variants } from '@humanspeak/svelte-motion'
const variants: Variants = {
hidden: { opacity: 0, x: -100 },
visible: (i) => ({
opacity: 1,
x: 0,
transition: { delay: (i as number) * 0.1 }
})
}
const items = ['Alpha', 'Beta', 'Gamma', 'Delta']
</script>
{#each items as item, i}
<motion.li custom={i} {variants} initial="hidden" animate="visible">
{item}
</motion.li>
{/each}
Single-element FLIP layout animation:
<motion.div layout />
<motion.div layout="position" />
layout: translate + scale.layout="position": translate only.layoutDependency: only re-measure when a value changes. In a keyed list, gate on the row's index so every row that moves animates — a per-row data field only changes for the row that triggered the re-sort, and the rows it displaces jump (upstream parity).layoutId animates matching elements between positions, LayoutGroup scopes ids, and layoutScroll marks scroll containers. Full docs: https://motion.svelte.page/docs/layout-animations.useAnimationFrameuseMotionTemplateuseSpringuseTimeuseTransformuseVelocitystyleStringstringifyStyleObject (deprecated)createDragControlsThe package also re-exports core helpers from motion (for example animate, stagger, transform, easings, and utility functions).
initial (or first animate keyframe when initial is empty).initial={false} skips initial enter animation.Validated against current source and test suite (local run):
676 passed290 passed, 2 skippedwhileInView does not yet expose Framer-style viewport options.MotionConfig does not yet support features, nonce, or isValidProp.motionmotion-domPart of the Humanspeak family of runes-native Svelte 5 packages:
| Package | Description |
|---|---|
| @humanspeak/svelte-markdown | Runtime markdown renderer for Svelte |
| @humanspeak/svelte-virtual-list | Virtual scrolling for Svelte |
| @humanspeak/svelte-motion — this package | Framer Motion for Svelte 5 |
| @humanspeak/svelte-headless-table | Headless data tables for Svelte |
| @humanspeak/svelte-virtual-chat | Virtual chat viewport for Svelte 5 |
| @humanspeak/svelte-diff | Diff comparison for Svelte |
| @humanspeak/svelte-purify | HTML sanitisation for Svelte |
| @humanspeak/memory-cache | In-memory cache for TypeScript |
| @humanspeak/svelte-json-view-lite | JSON tree viewer for Svelte 5 |
| @humanspeak/svelte-scoped-props | Scoped class props for Svelte |
MIT © Humanspeak, Inc.
Made with ❤️ by Humanspeak