react-motion-layout 与 react-router-dom 无缝集成:RouterLink 打造 Instagram 式 Hero 转场
【免费下载链接】react-motion-layout🦸 Beautiful immersive React hero animations.项目地址: https://gitcode.com/gh_mirrors/re/react-motion-layout
react-motion-layout 是一个专为 React 打造的共享元素动画库,它能与 react-router-dom 无缝集成,让你用一行 RouterLink 就能实现 Instagram 式的 Hero 转场动画——列表页的图片点击后,平滑"飞入"详情页,带来沉浸式视觉体验。
为什么需要跨路由的 Hero 转场?
大多数动画库(如 framer-motion)擅长处理组件的挂载/卸载动画,但遇到这类场景就会无能为力:
- 列表页和详情页使用同一张图片,但位置和尺寸不同
- 点击卡片进入详情时,希望图片从原位置连续变形到详情页的大图位置
- 退出时动画反向回放,回到列表页原位
这正是 Instagram、Pinterest 等产品标志性的 Hero 动画。react-motion-layout 的核心理念就是:把两个路由中的组件关联起来,在切换视图时一起动画。
它的主要优势:
| 特性 | 说明 |
|---|---|
| 🧩 声明式 | 只需把图片或文字包进 SharedElement 组件即可 |
| 🔌 路由友好 | 内置 RouterLink,点击链接自动触发转场 |
| 📦 零依赖 | 不需要额外的状态管理库 |
| 🌐 兼容性好 | 支持 Chrome 56+、Firefox 27+、Safari、Edge 等主流浏览器 |
核心组件全景
要打通路由转场,react-motion-layout 提供了 4 个关键角色:
- MotionLayoutProvider:应用根级 Provider,建立全局动画上下文
- MotionScreen:把当前路由视图标记为一个"屏幕",帮助系统识别要动画的元素
- MotionScene:编排动画、管理共享元素的相对位置与滚动同步
- RouterLink:封装 react-router-dom 的 Link,点击时先派发退场动画再跳转
这些组件都在 src/index.js 中统一导出,源码位于 src/components/RouterLink.jsx。
RouterLink:一个链接搞定转场
RouterLink 本质上是 react-router-dom 的 Link 增强版。它的使用方式几乎零成本——把<Link>换成<RouterLink>即可:
import { RouterLink, MotionScreen, MotionScene, SharedElement } from 'react-motion-layout'; <RouterLink to="/posts/1"> <SharedElement.Div animationKey="hero-1"> <img src="..." /> </SharedElement.Div> </RouterLink>它背后做了什么?
查看 src/components/RouterLink.jsx 的 onClick 逻辑,流程非常巧妙:
- 拦截默认跳转行为(
e.preventDefault()) - 按屏幕名对当前已注册的场景分组
- 仅当当前屏幕只有一个 MotionScene 时,派发
view.setExitView动作,标记退场元素 - 最后调用
history.push完成真正的路由跳转
详情页加载后,同名的 SharedElement 会自动识别源位置,播放"飞行"进场动画。还支持replace(replace 而非 push)、to传函数动态计算目标路由等用法。
三步接入你的项目
第 1 步:安装依赖
需要 React 16.8+,一条命令装齐:
npm i react-router-dom react-motion-layout --save第 2 步:列表页——标记屏幕与共享元素
用MotionScreen包裹页面,用SharedElement包裹需要转场的元素,并保证animationKey在两个页面一致:
<MotionScreen name="list"> <MotionScene name="list"> <RouterLink to="/posts/1"> <SharedElement.Image animationKey="hero-1" src="..." /> </RouterLink> </MotionScene> </MotionScreen>第 3 步:详情页——同 Key 自动接棒
<MotionScreen name="detail"> <MotionScene name="detail" scrollUpOnEnter> <SharedElement.Image animationKey="hero-1" src="..." /> </MotionScene> </MotionScreen>页面跳转时,animationKey="hero-1"的两个元素就被"关联"起来,完成从缩略图到大图的连续过渡。
关键 Props 速查表
MotionScreen(详见 website/docs/motionScreen.md)
| Prop | 类型 | 说明 |
|---|---|---|
| name | string | 屏幕标识,用于多场景路由定位 |
| onEnter / onExit | boolean | 是否播放进/退场动画(默认 true),可做单向动画 |
MotionScene(详见 website/docs/motionScene.md)
| Prop | 类型 | 说明 |
|---|---|---|
| name | string | 必填,场景唯一标识 |
| easing | string | 自定义缓动曲线 |
| scrollUpOnEnter | boolean | 进场时滚动到顶部,详情页必备 |
SharedElement提供Image、Text、Div三种元素,Div可动画 borderRadius、背景、位置、尺寸、阴影,适合卡片整体转场(详见 website/docs/sharedElementDiv.md)。
常见问题与最佳实践
Q:为什么动画没触发?检查两点:① 两个页面是否都用MotionScreen包裹;② 当前屏幕是否只有一个MotionScene——RouterLink 源码中明确要求num[store.screen].length === 1才派发退场动作。一个屏幕含多个场景时,需配合MotionScreen的name让系统定位。
Q:详情页有滚动怎么办?给详情页的MotionScene加上scrollUpOnEnter,避免进场动画起点偏移。
Q:只想播放单向动画?设置onEnter={false}或onExit={false},例如列表页退出时不回放动画。
总结
react-motion-layout 用最小的 API 面解决了"跨路由共享元素转场"这一痛点:MotionScreen定义舞台、MotionScene编排动画、SharedElement标记元素、RouterLink一键触发。四者配合 react-router-dom,即可用不到 20 行代码为 React 应用加上 Instagram 级的沉浸感 🚀。
【免费下载链接】react-motion-layout🦸 Beautiful immersive React hero animations.项目地址: https://gitcode.com/gh_mirrors/re/react-motion-layout
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考