GSAP 入门指南

在很长一段时间里,我与 GSAP 的关系,可以说是"最熟悉的陌生人"。

时常,遇到一些 CSS 难以驾驭的复杂动画,我的第一反应就是打开 GPT,描述我想要的效果,然后将它生成的 CSS 或者 GSAP 代码复制粘贴到项目中。它能用,效果也不错,项目也成功上线了。

但问题很快就来了。当我想对动画进行一些微调,比如"让第二个动画提前 0.2 秒开始",或者"当用户滚动到一半时暂停整个动画序列"时,AI 生成的代码就成了一个"黑箱"。我看不懂其中的逻辑,只能回去修改我的提问(Prompt),然后一次次地"抽奖"。

我意识到,我只是一个代码的"搬运工",而不是一个"创造者"。这种感觉不是很好。

最近,项目不忙,我下定决心,花半天时间彻底搞懂 GSAP。我打开官方文档,耐着性子读完了核心概念。结果令我大吃一惊------如此简单!曾经让我望而生畏的那些复杂动画,其底层逻辑,无非是建立在两三个核心概念之上。

补间动画(Tween)

官网中遇到的第一个核心概念,叫做 Tween(补间动画)

这个词听起来很专业,但它的思想却很朴素:"让一个东西,从一个状态,变化到另一个状态。"

GSAP 把这个过程封装成了一个极其简单的函数:gsap.to()。你只需要告诉它两件事:

  1. 谁? (动画的目标是谁?)
  2. 变成什么样? (动画的最终状态和参数是什么?)

比如,我以前让 AI 写一个"方块向右移动并旋转"的动画,它可能会给我一段这样的代码。现在,我能清晰地读懂它的含义。

javascript 复制代码
// 语法: gsap.to(目标, { ...参数 });

gsap.to(".box", {
  duration: 1, // 持续 1 秒
  x: 300, // x 轴移动 300px
  rotation: 360, // 旋转 360 度
});

xrotation 这些都是 GSAP 的简写,它会自动帮你转换为 transform: translateX(300px) rotate(360deg);,并且处理好了所有浏览器兼容性问题。

除了 to(),还有两个几乎一样的函数,只是改变了动画的参照方向:

  • gsap.from() 你给定的状态,运动到它现在的位置。特别适合做入场动画。
  • gsap.fromTo():完全自定义,从 A 状态 ,运动到 B 状态

理解了这三个函数,就等于掌握了 GSAP 的基本"单词"。你可以创造出任何独立的动画效果。

【最小可运行 Demo】

你可以把下面的代码完整复制到一个 HTML 文件中,用浏览器打开,亲眼见证这三个"单词"的威力。

html 复制代码
<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        padding: 20px;
        font-family: sans-serif;
      }
      .box {
        display: block;
        width: 80px;
        height: 80px;
        background-color: #28a745;
        margin-top: 20px;
      }
    </style>
  </head>
  <body>
    <h3>gsap.to (到...)</h3>
    <div class="box box1"></div>

    <h3>gsap.from (从...)</h3>
    <div class="box box2"></div>

    <h3>gsap.fromTo (从...到...)</h3>
    <div class="box box3"></div>

    <script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
    <script>
      // Box 1: 动画"到" x:300 的位置
      gsap.to(".box1", { x: 300, duration: 1.5 });

      // Box 2: "从" x:300 的位置,动画到它当前的位置 (x:0)
      gsap.from(".box2", { x: 300, duration: 1.5 });

      // Box 3: "从" x:-100 的位置,"到" x:300 的位置
      gsap.fromTo(
        ".box3",
        { x: -100, opacity: 0 },
        { x: 300, opacity: 1, duration: 1.5 }
      );
    </script>
  </body>
</html>

时间线 (Timeline)

假设 Tween 是动画组成的"单词",那么 Timeline (时间线) 就是 GSAP 用来"遣词造句"的语法。

我以前最大的困惑,就是如何组织多个动画。比如,先执行 A,A 结束后再执行 B,B 开始的同时执行 C。之前的代码里总是一堆 delay(延迟)参数,彼此依赖,改一个就得改全部,非常脆弱。

Timeline 完美地解决了这个问题。

你可以创建一个时间线,然后把你的所有 Tween(补间动画)按顺序放进去。

javascript 复制代码
// 以前,我可能会看到这样的"延迟地狱"代码
gsap.to(".box1", { x: 200, duration: 1 });
gsap.to(".box2", { y: 100, duration: 0.5, delay: 1 }); // 依赖于第一个动画的时长
gsap.to(".box3", { rotation: 90, duration: 1, delay: 1.5 }); // 依赖于前两个...

// 现在,用时间线,逻辑清晰如画
const tl = gsap.timeline();

tl.to(".box1", { x: 200, duration: 1 });
tl.to(".box2", { y: 100, duration: 0.5 });
tl.to(".box3", { rotation: 90, duration: 1 });

在这段代码里,动画会严格地按照添加顺序一个接一个播放。无论你如何修改某个动画的 duration,后续的动画总能正确地衔接。

更强大的是,你可以控制动画的"插入点",实现复杂的编排。

javascript 复制代码
tl.to(".box1", { x: 200, duration: 1 })
  .to(".box2", { y: 100, duration: 0.5 }, "-=0.5") // 在上个动画结束前 0.5s 开始
  .to(".box3", { rotation: 90, duration: 1 }, "<"); // 和上个动画同时开始

当你了解了 Timeline 之后,过去那些看起来高深莫测的序列动画,都会变得清晰明了。

点击此处查看 Timeline 的 CodePen 演示

缓动效果

掌握了 Tween 和 Timeline,已经能构建出任何复杂的动画结构了。剩下的,就是一些让动画更生动、更优雅的微调。

其中有两个是我过去最常用,但不知其所以然的属性。

  1. stagger(交错)

    场景:让一组元素(比如导航栏的菜单项、文章的标题字母)依次入场。 我以前会告诉 AI:"让它们一个接一个出现"。现在我明白了,只需要一个 stagger 属性。

    javascript 复制代码
    // 让所有的 .dot 元素,以 0.1 秒的间隔,依次从 Y 轴 -20px 的位置下来
    gsap.from(".dot", {
      y: -20,
      opacity: 0,
      duration: 0.5,
      stagger: 0.1, // 核心在这里
    });

    点击此处查看 Stagger 的 CodePen 演示

  2. ease(缓动)

    它决定了动画的速度曲线,是动画的"灵魂"。与其说是"属性",不如说是一种"感觉"。GSAP 内置了海量的缓动效果,比如 power1backelasticbounce 等。 过去我只会说"让它弹一下",现在我可以精确地选择 ease: "back.out(1.7)"(像被拉开后收回)或者 ease: "bounce.out"(像皮球落地)。

    GSAP 官方提供了一个非常直观的缓动效果可视化工具,强烈建议去玩一下,感受不同 ease 带来的节奏变化。

写在最后

这次学习 GSAP 的经历,对我触动很大。

当一个 AI 工具被我们视为"黑箱"时,我们能做的,就只有输入和输出;而当我们理解了它的核心思想,它就成了我们思想的延伸,我们才能真正用它去"创造"。

GSAP 的核心思想,就是 Tween(补间)Timeline(时间线)。用 Tween 定义单个动画,用 Timeline 编排它们。如此简单,却又如此强大。

如果你也像曾经的我一样,对某些技术感到既熟悉又陌生,不妨也静下心来,花一点点时间去阅读它的"第一章"。你可能会发现,那扇你以为很高的大门,其实门槛就在脚下。

(完)

相关推荐
gnip2 小时前
组件循环引用依赖问题处理
前端·javascript
Aotman_3 小时前
el-input textarea 禁止输入中文字符,@input特殊字符实时替换,光标位置保持不变
前端·javascript·vue.js·前端框架·es6
Nan_Shu_6143 小时前
Web前端面试题(1)
前端·面试·职场和发展
EveryPossible3 小时前
选择数据展示
javascript
lypzcgf3 小时前
Coze源码分析-资源库-创建知识库-前端源码-核心组件
前端·typescript·react·coze·coze源码分析·ai应用平台·agent开发平台
百思可瑞教育4 小时前
在Vue项目中Axios发起请求时的小知识
前端·javascript·vue.js·北京百思教育
患得患失9494 小时前
【个人项目】【前端实用工具】OpenAPI to TypeScript 转换器
前端·javascript·typescript
大前端helloworld4 小时前
前端梳理体系从常问问题去完善-基础篇(html,css,js,ts)
前端·javascript·面试
trsoliu5 小时前
前端基于 TypeScript 使用 Mastra 来开发一个 AI 应用 / AI 代理(Agent)
前端·人工智能