10 个 svelte-motion 实战案例:从按钮微交互到完整页面过渡
2026/8/21 18:01:24 网站建设 项目流程

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

核心入口主要有MotionDivAnimatePresenceAnimateSharedLayout以及一组 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>

过渡编排参数(如staggerChildrendelayChildren)定义在 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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询