前言
在前端开发中,我们经常需要实现一些比简单的直线平移更具动感的动画效果。虽然 CSS 的 transition 和 animation 能够处理大部分基础动画,但一旦涉及到复杂的贝塞尔曲线运动 或路径跟随动画,原生 CSS 实现起来就不太容易。
今天我们要介绍的主角是 GSAP (GreenSock Animation Platform) 。它是业界公认的动画标杆,不仅性能卓越,更重要的是,它提供了一套极其优雅的 API,让我们只需几行代码就能实现复杂的曲线运动。
为什么选择 GSAP?
GSAP 的强大之处在于其全能性:
- 极高性能: 经过高度优化的内核,甚至在处理数千个 SVG 元素时也能保持 60fps。
- 零兼容性烦恼: 自动处理不同浏览器的前缀和属性差异。
- 强大的插件系统: 比如我们今天要重点讨论的
MotionPathPlugin,专门为路径动画而生。 - 时间轴管理: 通过
Timeline可以非常直观地编排一连串复杂的动画。
在项目中引入 GSAP
- 使用 NPM/Yarn(推荐)
js
npm install gsap
# 或者
yarn add gsap
- 在项目中使用
js
import { gsap } from "gsap";
import { MotionPathPlugin } from "gsap/MotionPathPlugin";
// 使用插件前需要手动注册
gsap.registerPlugin(MotionPathPlugin);
- 使用 CDN 引入
js
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/MotionPathPlugin.min.js"></script>
实现元素做曲线运动
要让元素沿着曲线运动,GSAP 提供了 MotionPathPlugin 插件。它支持两种主要的路径定义方式:SVG 路径 和坐标点数组。
方案一:让元素跟随现有的 SVG 路径
这是最常用的场景,可以直接在设计稿中画好一段 SVG 路径(Path),然后让 HTML 元素"贴"上去运行。 HTML:
HTML
<svg width="400" height="200" viewBox="0 0 400 200">
<path id="route" d="M10,100 Q100,0 200,100 T390,100" stroke="lightgray" fill="transparent" />
</svg>
<div class="ball"></div>
JS:
js
gsap.to(".ball", {
duration: 5,
repeat: -1,
ease: "power1.inOut",
motionPath: {
path: "#route", // 引用 SVG 路径的选择器
align: "#route", // 将元素对齐到路径上
autoRotate: true, // 元素随路径方向自动旋转
alignOrigin: [0.5, 0.5] // 以元素的中心点进行对齐
}
});
方案二:通过坐标数组自定义曲线
如果你没有 SVG,也可以直接传入一组坐标点,GSAP 会自动为你计算出平滑的贝塞尔曲线。
js
gsap.to(".ball", {
duration: 4,
motionPath: {
path: [
{x: 100, y: -50},
{x: 250, y: 100},
{x: 400, y: 50},
{x: 600, y: 200}
],
curviness: 1.5 // 数值越大曲线越圆润
}
});
关键参数深度解析
在 motionPath 对象中,有几个参数非常实用:
- align (对齐): 如果不设置
align,元素会基于自己当前的初始位置进行相对运动。设置后,它会"吸附"到目标路径上。 - autoRotate (自动旋转): 对于像"小车"或"纸飞机"这样的元素,设置为
true或指定旋转偏移量,可以让物体的头部始终指向运动方向。 - start & end: 你可以指定动画从路径的 10% 处开始,到 90% 处结束(取值 0 到 1)。
start: 0.1, end: 0.9
进阶:结合 ScrollTrigger 实现滚动曲线动画
GSAP 最强悍的组合就是将 MotionPath 与 ScrollTrigger 结合。你可以实现当用户向下滚动页面时,一个元素沿着预设的曲线路径飞过。
js
import { ScrollTrigger } from "gsap/ScrollTrigger";
gsap.registerPlugin(ScrollTrigger);
gsap.to(".ball", {
scrollTrigger: {
trigger: ".container",
start: "top center",
end: "bottom center",
scrub: 1, // 动画随滚动条进度平滑移动
},
motionPath: {
path: "#route"
}
});