10 个 svelte-motion 实战案例:从按钮微交互到完整页面过渡
【免费下载链接】svelte-motionAn animation library for Svelte based on framer-motion.项目地址: https://gitcode.com/gh_mirrors/sv/svelte-motion
在 Svelte 生态中,svelte-motion 是一款基于 framer-motion 打造的 Svelte 动画库,它把 React 世界中最受欢迎的动画能力(手势、拖拽、共享布局、页面过渡)完整移植到了 Svelte 中。本文通过 10 个由浅入深的实战案例,带你从按钮微交互一路做到完整的页面过渡效果,全部开箱即用。
先认识 svelte-motion:为什么值得一试
svelte-motion 的核心设计理念是"声明式动画":你不需要手动管理 rAF 循环或 CSS 类名,只需要告诉组件"从哪到哪、怎么动",剩下的交给库来处理。它由 popmotion 驱动,动画性能出色,同时保留了 Svelte 的简洁语法。
安装方式非常简单,一条命令即可:
npm install --save-dev svelte-motion核心入口主要有MotionDiv、AnimatePresence、AnimateSharedLayout以及一组 hooks,相关实现可以查看 src/index.js 与 MotionDiv.svelte。
案例 1:按钮点击缩放反馈(微交互入门)
最基础的微交互是"按下有反馈"。给按钮加上whileTap属性,点击时就会自动缩放,松手后弹回,配合transition还能控制回弹的弹性:
<MotionDiv whileTap={{ scale: 0.9 }}> <button>点我试试</button> </MotionDiv>MotionDiv是 svelte-motion 中最常用的动画容器,它内部通过use:motion指令把动画能力绑定到 DOM 节点上,细节可以参考 Motion.svelte 和 UseVisualElement.svelte。
案例 2:悬停上浮与阴影过渡
给卡片加whileHover,鼠标悬停时轻微上浮并加深阴影,让交互更生动。这里推荐使用 spring 弹性过渡,手感更自然:
<MotionDiv whileHover={{ y: -6, boxShadow: "0 12px 30px rgba(0,0,0,.15)" }} transition={{ type: "spring", stiffness: 300, damping: 20 }} > <div class="card">悬停我</div> </MotionDiv>whileHover/whileTap属于手势能力,源码位于 use-hover-gesture.js 与 use-tap-gesture.js。
案例 3:汉堡菜单图标变形
经典需求:三条横线点击后变成"×"。使用useCycle钩子让角度在 0 和 45 度之间循环,三条线分别旋转即可:
<script> import { useCycle } from "svelte-motion"; const [open, cycle] = useCycle(0, 45); </script>useCycle的实现见 use-cycle.js,非常适合做状态循环切换类动画。
案例 4:模态框弹出与遮罩淡入
弹窗类组件需要"入场"和"离场"两个方向的动画,这正是AnimatePresence的用武之地。它会在子元素移除后保留 DOM 一小段时间,让exit动画完整播放:
<AnimatePresence show={visible} let:item> <MotionDiv initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.8 }} > {#if item}<div class="modal">弹窗内容</div>{/if} </MotionDiv> </AnimatePresence>AnimatePresence的退出管理逻辑是重点,可以阅读 AnimatePresence.svelte 与 PresenceChild.svelte。
案例 5:列表项增删动画
配合 Svelte 的{#each}与 keyed 渲染,可以让列表项在新增时滑入、删除时滑出。同样由AnimatePresence接管退出动画,用户体验直接上一个档次:
{#each items as item (item.id)} <MotionDiv initial={{ opacity: 0, x: -40 }} animate={{ opacity: 1, x: 0 }} exit={{ opacity: 0, x: 40 }} > <li>{item.name}</li> </MotionDiv> {/each}案例 6:页面切换过渡(路由级动画)
页面过渡是"完整页面动画"的核心。思路是:路由切换时,旧页面执行exit动画,新页面执行initial → animate入场动画,加上exitBeforeEnter可以做到"先出后进",避免两个页面重叠:
<AnimatePresence exitBeforeEnter> <!-- 根据当前路由渲染对应页面 --> </AnimatePresence>过渡编排参数(如staggerChildren、delayChildren)定义在 transitions.js,想要做出惊艳的页面切换,这套编排系统是核心。
案例 7:共享布局动画(元素"变身")
在 React 的 framer-motion 里最惊艳的功能之一,就是layoutId共享布局过渡:两个不同位置的元素共用一个layoutId,切换时元素会"飞"过去。svelte-motion 通过AnimateSharedLayout完整复刻了这一能力:
<AnimateSharedLayout> <MotionDiv layoutId="highlight" /> </AnimateSharedLayout>实现原理是批量测量布局并做差值动画,源码在 AnimateSharedLayout.svelte 以及 batcher.js、crossfader.js。
案例 8:拖拽组件与边界约束
svelte-motion原生支持拖拽,drag属性开启拖拽,dragConstraints限定边界,配合useDragControls还可以实现"按住手柄才能拖动"的精细控制:
<MotionDiv drag dragConstraints={{ left: 0, right: 300, top: 0, bottom: 300 }}> <div class="box">拖动我</div> </MotionDiv>拖拽涉及约束计算与拖拽锁,可参考 use-drag.js 和 constraints.js。
案例 9:滚动驱动动画
滚动监听是长页面最常用的动效。useViewportScroll提供滚动进度,useTransform把进度映射成位移或透明度,实现"图片随滚动上移并淡出"的视差效果:
<script> import { useViewportScroll, useTransform } from "svelte-motion"; const { scrollYProgress } = useViewportScroll(); const y = useTransform(scrollYProgress, [0, 1], [0, -100]); </script>对应实现见 use-viewport-scroll.js 与 use-transform.js。
案例 10:弹簧数值与数字滚动
最后展示 MotionValue 体系的强大:useSpring让数值以弹簧方式逼近目标值,useVelocity读取速度。把它接到进度条或数字计数器上,任何数值变化都会变得丝滑:
<script> import { useMotionValue, useSpring } from "svelte-motion"; const x = useMotionValue(0); const springX = useSpring(x, { stiffness: 300, damping: 20 }); </script>useSpring内部通过 popmotion 的animate实现弹簧物理,源码见 use-spring.js 与 use-motion-value.js。
进阶建议与项目结构速览
如果你想把动画能力封装成可复用的业务组件,建议重点研究这几块源码:
- 手势系统:use-gestures.js、PanSession.js
- 动画编排:animation-state.js、variants.js
- 投影与布局测量:projection 目录
- 无障碍支持:use-reduced-motion.js(尊重系统"减弱动态效果"设置)
动手实践时,也可以直接 clone 仓库到本地阅读完整源码:
git clone https://gitcode.com/gh_mirrors/sv/svelte-motion总结
这 10 个案例覆盖了 svelte-motion 的完整能力地图:从whileTap/whileHover的按钮微交互,到AnimatePresence的列表与弹窗过渡,再到AnimateSharedLayout的共享布局动画和 MotionValue 驱动的滚动、弹簧效果。掌握它们之后,你就能用声明式语法写出媲美原生 APP 的丝滑交互动画,把页面体验提升到新的高度。建议从案例 1 开始动手,逐个跑通后,再向页面级过渡进阶,你会发现 Svelte 动画原来可以这么简单。
【免费下载链接】svelte-motionAn animation library for Svelte based on framer-motion.项目地址: https://gitcode.com/gh_mirrors/sv/svelte-motion
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考