gsap 配置解读 --6

0 阅读19分钟

什么是CustomBounce

   <div class="card">
      <h1>案例 34:CustomBounce 弹跳</h1>
      <p>根据参数生成弹跳缓动。</p>
      <div class="lane">
        <div class="ball" id="ball"></div>
      </div>
      <button id="play">弹跳起来</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/CustomEase.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/CustomBounce.min.js"></script>
    <script>
      const ball = document.querySelector("#ball");
      const playButton = document.querySelector("#play");

      // 注册 CustomBounce
      gsap.registerPlugin(CustomBounce);

      // 生成弹跳缓动
      CustomBounce.create("myBounce", {
        strength: 0.8,
        squash: 0.4,
        squashID: "myBounce-squash"
      });

      const timeline = gsap.timeline({ paused: true });
      timeline.to(ball, { y: 90, duration: 1.2, ease: "myBounce" });
      timeline.to(ball, { scaleY: 0.7, duration: 1.2, ease: "myBounce-squash" }, 0);

      playButton.addEventListener("click", () => {
        gsap.set(ball, { y: 0, scaleY: 1 });
        timeline.restart();
      });
    </script>

CustomBounceGSAP(GreenSock Animation Platform) 提供的一个高级插件,用于自动生成逼真、可定制的“弹跳”缓动效果(bounce easing),并同步生成配套的“挤压”(squash)缓动,从而轻松实现物理感十足的弹性动画(如球落地时的弹跳 + 变形)。


📌 简单定义:

CustomBounce 能根据你设定的参数(如弹跳强度、挤压程度),自动创建一对缓动函数:

  • 一个用于位置弹跳(上下跳动)
  • 一个用于形状挤压(落地时压扁、弹起时拉伸)

它解决了传统弹跳动画中“只有上下运动,没有形变”的不真实问题。


✅ 核心功能:

1. 一键生成弹跳缓动
CustomBounce.create("myBounce", {
  strength: 0.8,        // 弹跳强度(0~1,值越大弹越高、次数越多)
  squash: 0.4,          // 挤压强度(0~1,值越大落地时越扁)
  squashID: "myBounce-squash" // 挤压缓动的名称(自动生成)
});
  • 调用后,会注册两个缓动:
    • "myBounce" → 用于 y 位置动画(模拟弹跳轨迹)
    • "myBounce-squash" → 用于 scaleY(或 scaleX)动画(模拟挤压变形)
2. 物理感更强
  • 弹跳高度逐次衰减(符合能量损耗)
  • 挤压发生在每次触地瞬间(时间点精准对齐)
  • 无需手动计算关键帧或贝塞尔曲线

🔧 在你的代码中:

// 创建弹跳缓动
CustomBounce.create("myBounce", {
  strength: 0.8,
  squash: 0.4,
  squashID: "myBounce-squash"
});

// 时间轴同步动画
timeline.to(ball, { y: 90, duration: 1.2, ease: "myBounce" }); // 向下弹跳
timeline.to(ball, { scaleY: 0.7, duration: 1.2, ease: "myBounce-squash" }, 0); // 同步挤压

动画效果:

  1. 小球从顶部下落;
  2. 触地瞬间垂直压缩scaleY 变小);
  3. 弹起时恢复原状,并继续多次小幅弹跳
  4. 整个过程自然流畅,像真实的橡胶球。

💡 注意:两个动画必须同时开始(position: 0,才能保证挤压与弹跳同步。


⚙️ 关键参数说明:

参数作用推荐范围
strength控制弹跳次数和高度0.1(轻微回弹) ~ 1(剧烈多次弹跳)
squash控制落地时的压缩程度0.1(微扁) ~ 0.6(明显压扁)
squashID指定挤压缓动的名称任意唯一字符串

🌟 为什么比普通 bounce 缓动更好?

对比项CSS / GSAP 内置 bounceCustomBounce
是否有形变❌ 仅有位置变化✅ 同步挤压/拉伸
可定制性❌ 固定节奏✅ 自由调节强度
物理真实性⚠️ 生硬、机械✅ 接近真实物体
开发效率需手动做两个动画✅ 一行代码生成一对缓动

🎨 典型应用场景:

  • 按钮点击反馈:按下时轻微弹跳+压缩
  • 购物车添加商品:商品图标“掉落”进购物车
  • 游戏元素:角色跳跃、球类运动
  • 加载动画:Logo 弹入
  • 数据可视化:柱状图“生长”时带弹跳

⚠️ 注意事项:

  • 依赖 CustomEase:必须先引入 CustomEase.min.js(因为 CustomBounce 基于它构建);
  • 挤压方向:通常用 scaleY 模拟垂直弹跳的压缩,水平弹跳可用 scaleX
  • 初始状态重置:播放前需还原 yscaleY(如你代码中的 gsap.set);
  • 商业项目需授权CustomBounce 属于 GSAP Club 会员专属插件(免费试用,商用需订阅)。

📚 官方资源:


✅ 总结:

CustomBounce 是 GSAP 中实现“真实弹跳动画”的终极解决方案——它将复杂的物理形变简化为两个同步缓动,让你用极简代码打造出媲美原生应用的生动交互动效。

什么是CustomWiggle

  <div class="card">
      <h1>案例 35:CustomWiggle 摇摆</h1>
      <p>用 CustomWiggle 生成自然的摆动缓动。</p>
      <div class="arm">
        <div class="stick" id="stick"></div>
      </div>
      <button id="play">摇一摇</button>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/CustomEase.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/CustomWiggle.min.js"></script>
    <script>
      const stick = document.querySelector("#stick");
      const playButton = document.querySelector("#play");

      // 注册 CustomWiggle
      gsap.registerPlugin(CustomWiggle);

      // 创建摆动缓动
      CustomWiggle.create("myWiggle", {
        wiggles: 6,
        type: "easeOut"
      });

      const tween = gsap.to(stick, {
        rotation: 40,
        duration: 1.4,
        ease: "myWiggle",
        paused: true
      });

      playButton.addEventListener("click", () => {
        gsap.set(stick, { rotation: 0 });
        tween.restart();
      });
    </script>

CustomWiggleGSAP(GreenSock Animation Platform) 提供的一个高级插件,用于生成自然、可控的“摇摆”或“抖动”缓动效果(wiggle easing)。它能让你的动画在到达目标值的过程中,自动叠加多次平滑的来回摆动,模拟如钟摆、天线晃动、果冻抖动等物理现象。


📌 简单定义:

CustomWiggle 会创建一个特殊的缓动函数,使属性值在变化终点附近产生指定次数的衰减式振荡(摇摆),而无需手动编写复杂的关键帧。

它比简单的 repeat + yoyo 更真实、更流畅,且完全集成于 GSAP 动画系统。


✅ 核心功能:

1. 一键生成摇摆缓动
CustomWiggle.create("myWiggle", {
  wiggles: 6,        // 摆动次数(完整来回算 1 次)
  type: "easeOut"    // 衰减类型(控制摆动幅度如何减小)
});
  • 调用后,注册一个名为 "myWiggle" 的缓动函数;
  • 可直接用于任何 GSAP 动画的 ease 属性。
2. 多种衰减模式(type
类型效果
"easeOut"(默认)摆动幅度快速衰减(最常用)
"easeInOut"先加速后减速,摆动对称
"anticipate"先反向小幅度“预摆”,再正向摆动(类似弹簧回弹前的拉扯)
"uniform"所有摆动幅度相同(机械感强)
"random"随机幅度和方向(模拟不稳定抖动)

CustomWiggle.create("myWiggle", {
  wiggles: 6,
  type: "easeOut"
});

gsap.to(stick, {
  rotation: 40,       // 从 0° 转到 40°
  duration: 1.4,
  ease: "myWiggle"    // 在接近 40° 时,自动左右摇摆 6 次并逐渐停止
});

动画效果:

  • 木棍从垂直位置开始旋转;
  • 接近 40° 时,不会直接停住,而是像被风吹动一样:
    • 先超过 40° → 回摆到 38° → 再超到 41° → 回摆到 39.5° ……
  • 摆动幅度逐次减小,最终稳定在 40°。

💡 这种效果常用于:UI 元素强调、错误提示抖动、卡通角色动作等。


🌟 为什么比手动做更好?

方法控制精度代码量自然度可复用性
手动写 timeline + 多个 to()一般
repeat + yoyo无法衰减机械一般
CustomWiggle极简逼真优秀

⚙️ 常用参数扩展(高级用法):

CustomWiggle.create("jelly", {
  wiggles: 8,
  type: "easeOut",
  strength: 0.7,      // 摆动强度(默认 0.5,越大越夸张)
  timing: 0.6         // 时间分布(影响摆动节奏)
});

🎨 典型应用场景:

场景示例
UI 反馈输入错误时输入框“摇头”
加载指示器图标轻微晃动表示活跃
游戏角色角色受击后头部晃动
品牌动画Logo 入场带弹性摆动
数据图表柱状图增长时顶部抖动

⚠️ 注意事项:

  • 依赖 CustomEase:必须先引入 CustomEase.min.js(因为 CustomWiggle 基于它构建);
  • 仅作用于数值属性:如 rotationxscaleopacity 等;
  • 不适用于颜色或复杂对象
  • 商业项目需授权CustomWiggle 属于 GSAP Club 会员专属插件(可免费试用,商用需订阅)。

📚 官方资源:


✅ 总结:

CustomWiggle 是 GSAP 中实现“生动摇摆动画”的魔法工具——它将复杂的振荡逻辑封装成一行配置,让你轻松赋予界面元素生命力,是打造趣味性与专业感兼备交互动效的秘密武器。

什么是addLabel

<div class="card">
      <h1>案例 36:时间线标签与位置</h1>
      <p>用 label 和位置参数精准控制动画片段。</p>
      <div class="stage">
        <div class="box" id="box"></div>
      </div>
      <div class="controls">
        <button id="to-start">跳到 start</button>
        <button id="to-mid">跳到 mid</button>
        <button class="primary" id="play">播放</button>
      </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
    <script>
      const box = document.querySelector("#box");
      const playButton = document.querySelector("#play");
      const toStartButton = document.querySelector("#to-start");
      const toMidButton = document.querySelector("#to-mid");

      // 创建时间线并加入标签
      const timeline = gsap.timeline({ paused: true });
      timeline.addLabel("start");
      timeline.to(box, { x: 200, duration: 0.6, ease: "power2.out" });
      timeline.addLabel("mid");
      timeline.to(box, { y: -20, duration: 0.4, ease: "power2.out" }, "mid");
      timeline.to(box, { x: 420, duration: 0.6, ease: "power2.inOut" }, "mid+=0.2");
      timeline.to(box, { y: 0, duration: 0.4 }, ">");

      playButton.addEventListener("click", () => {
        timeline.restart();
      });

      toStartButton.addEventListener("click", () => {
        timeline.pause().seek("start");
      });

      toMidButton.addEventListener("click", () => {
        timeline.pause().seek("mid");
      });
    </script>

在 GSAP(GreenSock Animation Platform)中,addLabel()Timeline(时间线) 的一个方法,用于在动画时间轴的特定位置添加一个具名标记(label),就像给视频加书签一样。它让你能用语义化的名称(如 "start""explode""fade-in")代替精确的时间值(如 1.2 秒),从而更直观、灵活地组织和控制复杂动画序列。


📌 简单定义:

addLabel("name", position) 在时间线的某个时刻打上一个“名字标签”,后续可通过这个名称精准跳转、插入动画或同步多个动画片段。


✅ 核心作用:

1. 语义化控制点

不用记“第 1.4 秒发生了什么”,而是用 "mid" 表示“中间状态”。

2. 精准跳转(Seek)
timeline.seek("start"); // 立即跳到 "start" 标签处
timeline.play("mid");   // 从 "mid" 开始播放
3. 作为动画插入的锚点

在构建时间线时,可以用标签名指定新动画的开始时间:

timeline.to(element, { x: 100 }, "mid");        // 与 "mid" 标签同时开始
timeline.to(element, { y: 50 }, "mid+=0.2");    // 在 "mid" 后 0.2 秒开始

const timeline = gsap.timeline({ paused: true });

timeline.addLabel("start"); // 在时间 0 处添加标签 "start"
timeline.to(box, { x: 200, duration: 0.6 });

timeline.addLabel("mid");   // 在当前时间(约 0.6s)处添加标签 "mid"
timeline.to(box, { y: -20, duration: 0.4 }, "mid");      // 与 "mid" 同时开始
timeline.to(box, { x: 420, duration: 0.6 }, "mid+=0.2"); // 在 "mid" 后 0.2s 开始
timeline.to(box, { y: 0, duration: 0.4 }, ">");          // 紧接上一个动画结束
时间线结构可视化:
0s        0.6s       0.6s       0.8s       1.4s       1.8s
│          │          │          │          │          │
├─ start   ├─ x→200   ├─ mid     ├─ x→420   ├─ y→0     ▶
           │          ├─ y→-20   │
           │          │          │
           └──────────┴──────────┴───────────...
  • 点击 “跳到 start” → 盒子回到起点(x=0, y=0
  • 点击 “跳到 mid” → 盒子位于 x=200, y=0(刚完成水平移动,即将向上跳)

⚙️ addLabel() 的完整语法:

timeline.addLabel(labelName, position);
  • labelName:字符串,如 "intro""end"
  • position(可选):
    • 数字:1.2(1.2 秒处)
    • 相对位置:"+=0.5"(当前末尾 +0.5s)
    • 其他标签:"start+=1"
    • 默认:"+=0"(即当前时间线末尾)

💡 你也可以在 to() / from() 等方法中直接定义标签,无需单独调用 addLabel

timeline.to(box, { x: 100 }).add("mid") // 等价于 addLabel("mid")
// 或更简洁:
timeline.to(box, { x: 100, onComplete: () => {} }, "mid"); // 第三个参数是位置

🌟 优势总结:

传统方式使用 addLabel()
timeline.seek(1.2) → 难理解、易出错timeline.seek("explosion") → 自解释、易维护
插入动画需计算时间偏移直接用 "label+=0.3",逻辑清晰
修改动画时长后,所有时间点需重算标签自动跟随上下文,几乎无需调整

🛠️ 实际应用场景:

  • 交互式故事:点击按钮跳到“章节2”
  • 游戏过场"player-jump""enemy-appear"
  • UI 动画"menu-open""loading-complete"
  • 调试复杂时间线:快速定位到关键帧

✅ 总结:

addLabel() 是 GSAP 时间线的“命名书签”系统——它用人类可读的标签替代冰冷的时间数字,让复杂动画的编排、跳转和维护变得直观、可靠且富有表现力,是专业级交互动画开发的必备技巧。

什么是modifiers

 <div class="card">
      <h1>案例 37:modifiers 循环取模</h1>
      <p>把位移限制在固定范围内,实现循环运动。</p>
      <div class="stage">
        <div class="dot" id="dot"></div>
      </div>
      <button id="play">开始循环</button>
      <div class="hint">小球会在 0~480 范围内循环</div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
    <script>
      const dot = document.querySelector("#dot");
      const playButton = document.querySelector("#play");

      // modifiers 可以在每帧修改数值,这里做取模循环
      const tween = gsap.to(dot, {
        x: 1200,
        duration: 6,
        ease: "none",
        modifiers: {
          x: (value) => `${parseFloat(value) % 480}px`
        },
        paused: true
      });

      playButton.addEventListener("click", () => {
        tween.restart();
      });
    </script>

GSAP(GreenSock Animation Platform) 中,modifiers 是一个强大的动画配置选项,它允许你在每一帧动画更新时,对目标属性的计算值进行自定义修改,然后再应用到元素上。

你可以把它理解为:“在 GSAP 计算出新值之后、真正设置到元素之前,插入一个自定义的‘过滤器’或‘转换器’。”


📌 简单定义:

modifiers 是一个对象,其键是属性名(如 xrotation),值是一个函数。该函数接收 GSAP 计算出的原始值,返回你想要实际应用的值。

modifiers: {
  x: (rawValue) => {
    // 对 rawValue 做处理,比如取模、限制范围、单位转换等
    return processedValue;
  }
}

✅ 核心作用:

  • 实现循环/回绕效果(如你的案例:0~480 像素内无限循环)
  • 限制数值范围(如旋转角度始终在 -180° ~ 180°)
  • 单位转换或格式化(如将弧度转角度、数字加单位)
  • 创建非线性映射(如对数缩放、自定义曲线)

modifiers: {
  x: (value) => `${parseFloat(value) % 480}px`
}
动画过程解析:
  1. GSAP 正常计算 x01200 的线性变化(因为 ease: "none");
  2. 但在每一帧modifiers.x 函数会被调用:
    • 接收 GSAP 算出的 value(如 5006001000...)
    • 执行 500 % 480 = 20 → 返回 "20px"
    • 元素实际被设置为 transform: translateX(20px)
  3. 结果:小球看似从 0 移动到 480 后瞬间回到 0,形成无缝循环运动

💡 虽然 GSAP 内部仍在向 1200 推进,但视觉上永远只在 [0, 480) 区间内移动。


🌟 其他典型用法示例:

1. 角度循环(-180° ~ 180°)
modifiers: {
  rotation: (value) => ((parseFloat(value) + 180) % 360) - 180
}
2. 限制在屏幕内
modifiers: {
  x: (value) => Math.min(Math.max(parseFloat(value), 0), window.innerWidth - 50)
}
3. 自定义单位或格式
// 将 scale 值保留两位小数
modifiers: {
  scale: (value) => parseFloat(value).toFixed(2)
}
4. 颜色/复杂值?

❌ 注意:modifiers 仅适用于数值型属性(如 x, y, rotation, opacity, scale 等)。
不能用于颜色、文本、CSS 字符串等非纯数值属性。


⚠️ 注意事项:

  • value 参数是字符串(如 "120px"),通常需用 parseFloat() 提取数字;
  • 返回值必须是有效的 CSS 值(如 "120px""0.5""45deg");
  • 性能敏感:函数会在每帧执行,避免 heavy 计算;
  • onUpdate 的区别:
    • onUpdate 是回调通知,不能修改动画值
    • modifiers直接干预最终赋值,更底层、更强大。

📚 官方文档:

👉 greensock.com/docs/v3/GSA…


✅ 总结:

modifiers 是 GSAP 中实现“动态值约束”和“循环动画”的利器——它让你在不改变动画逻辑的前提下,通过简单的数学变换(如取模 %),创造出无限滚动、角度归一化、边界限制等高级效果,是构建复杂交互动画的秘密武器。

什么是quickSetter

<div class="card">
      <h1>案例 38:quickSetter 高频更新</h1>
      <p>快速设置属性,适合鼠标跟随。</p>
      <div class="stage" id="stage">
        <div class="cursor" id="cursor"></div>
      </div>
      <div class="hint">在区域内移动鼠标</div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
    <script>
      const stage = document.querySelector("#stage");
      const cursor = document.querySelector("#cursor");

      // quickSetter 返回高性能的属性设置函数
      const setX = gsap.quickSetter(cursor, "x", "px");
      const setY = gsap.quickSetter(cursor, "y", "px");

      stage.addEventListener("mousemove", (event) => {
        const rect = stage.getBoundingClientRect();
        const x = event.clientX - rect.left - 20;
        const y = event.clientY - rect.top - 20;
        setX(x);
        setY(y);
      });
    </script>

quickSetterGSAP(GreenSock Animation Platform) 提供的一个高性能工具函数,用于极速设置元素的 CSS 属性或 transform 值,特别适合需要高频更新的场景(如鼠标跟随、拖拽、游戏循环等)。


📌 简单定义:

gsap.quickSetter(target, property, unit?) 返回一个专用函数,该函数能以最高效的方式直接设置目标元素的指定属性值,绕过 GSAP 动画系统的开销。

它不是用来做动画的,而是用来极致优化“即时赋值”性能的。


✅ 为什么需要它?

在普通 JavaScript 中,你可能会这样写鼠标跟随:

// 普通方式(性能较差)
cursor.style.transform = `translate(${x}px, ${y}px)`;

但这种方式存在几个问题:

  • 频繁拼接字符串(内存分配 + GC 压力)
  • 浏览器需解析整个 transform 字符串
  • 如果同时设置多个 transform 属性(x/y/rotation/scale),容易互相覆盖

quickSetter 解决了这些问题!


🔧 核心优势:

1. 零字符串拼接

内部使用预编译的 setter 函数,直接操作数值,避免字符串操作。

2. 智能处理 transform
  • 自动将 xyrotationscale 等映射到 transform 矩阵;
  • 多个 quickSetter(如 xy不会互相覆盖,因为 GSAP 内部维护统一的 transform 状态。
3. 自动单位处理

第三个参数指定单位(如 "px""deg"),调用时只需传数字:

const setX = gsap.quickSetter(el, "x", "px");
setX(100); // 等价于 el.style.transform += " translateX(100px)"
4. 极致性能
  • 比原生 style.transform2~5 倍(尤其在高频调用时);
  • 避免触发不必要的重排(reflow)或样式计算。

const setX = gsap.quickSetter(cursor, "x", "px");
const setY = gsap.quickSetter(cursor, "y", "px");

stage.addEventListener("mousemove", (event) => {
  const x = event.clientX - rect.left - 20;
  const y = event.clientY - rect.top - 20;
  setX(x); // 极速设置 x
  setY(y); // 极速设置 y
});
  • 鼠标移动时,每帧调用 setX/setY
  • 光标元素的 transform 被高效更新,无卡顿、无抖动
  • 即使快速晃动鼠标,也能保持流畅。

🌟 典型应用场景:

场景说明
自定义光标如你的例子,替代系统光标
拖拽交互实时更新被拖元素位置
游戏开发精灵(sprite)位置/旋转高频更新
粒子系统成百上千个点的位置同步更新
手势/触控反馈手指移动时实时响应

⚙️ 支持的属性(部分):

  • Transform 类x, y, z, rotation, rotationX, rotationY, scale, scaleX, scaleY, skewX, skewY
  • CSS 属性opacity, backgroundColor, width, height, borderRadius 等(但 transform 性能提升最显著)

💡 对于非 transform 属性,quickSetter 仍比直接 style.xxx = value 更可靠(自动处理单位、兼容性)。


⚠️ 注意事项:

  • 不触发动画quickSetter 只是“设置值”,没有缓动、时间、回调;
  • 不要用于低频操作:如果只是偶尔更新,用普通方式即可;
  • 单位要匹配:比如 rotation 应传 "deg"x/y"px"
  • 免费可用quickSetter 是 GSAP 核心 API,无需额外插件或会员

📚 官方文档:

👉 greensock.com/docs/v3/GSA…


✅ 总结:

quickSetter 是 GSAP 为高性能交互场景提供的“极速通道”——它剥离了动画系统的冗余开销,让你在需要每秒更新数十次甚至上百次的场景中,依然保持丝滑流畅的用户体验,是构建专业级交互动效的底层利器。

什么是matchMedia

 <div class="card">
      <h1>案例 39:matchMedia 响应式动画</h1>
      <p>不同屏幕宽度执行不同动画。</p>
      <div class="stage">
        <div class="box" id="box"></div>
      </div>
      <button id="play">播放</button>
      <div class="hint">尝试缩放浏览器宽度</div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
    <script>
      const box = document.querySelector("#box");
      const playButton = document.querySelector("#play");

      const mm = gsap.matchMedia();
      let tween;

      // matchMedia 在不同断点创建不同动画
      mm.add(
        {
          desktop: "(min-width: 700px)",
          mobile: "(max-width: 699px)"
        },
        (context) => {
          const { desktop } = context.conditions;
          tween = gsap.to(box, {
            x: desktop ? 460 : 260,
            duration: 1.2,
            ease: "power2.inOut",
            paused: true
          });
        }
      );

      playButton.addEventListener("click", () => {
        if (tween) {
          tween.restart();
        }
      });
    </script>

gsap.matchMedia()GSAP(GreenSock Animation Platform) 提供的一个响应式动画管理工具,用于根据 CSS 媒体查询(media queries) 自动创建、切换或销毁对应的动画,从而实现真正适配不同设备和屏幕尺寸的交互动效


📌 简单定义:

matchMedia 让你用类似 CSS 媒体查询的语法,为桌面端、平板、手机等不同屏幕宽度编写专属动画,并在窗口缩放时自动清理旧动画、启用新动画,避免内存泄漏和逻辑冲突。

它解决了传统响应式动画中“手动监听 resize + 手动 kill 动画”的繁琐与易错问题。


✅ 核心作用:

1. 按屏幕尺寸分发动画
const mm = gsap.matchMedia();

mm.add({
  desktop: "(min-width: 700px)",
  mobile: "(max-width: 699px)"
}, (context) => {
  const { desktop } = context.conditions;
  
  // 根据当前匹配的断点,创建对应动画
  tween = gsap.to(box, {
    x: desktop ? 460 : 260,
    duration: 1.2
  });
});
  • 当屏幕 ≥700px → desktop: true → 移动到 x: 460
  • 当屏幕 <700px → mobile: true → 移动到 x: 260
2. 自动生命周期管理
  • 当媒体查询从匹配变为不匹配时,GSAP 会自动 kill() 掉该上下文中的所有动画
  • 重新匹配时,回调函数重新执行,创建新动画;
  • 无需手动监听 window.resize 或调用 tween.kill()
3. 支持嵌套与复杂查询
mm.add({
  large: "(min-width: 1200px)",
  medium: "(min-width: 768px) and (max-width: 1199px)",
  small: "(max-width: 767px)"
}, context => { ... });

mm.add(
  {
    desktop: "(min-width: 700px)",
    mobile: "(max-width: 699px)"
  },
  (context) => {
    const { desktop } = context.conditions;
    tween = gsap.to(box, {
      x: desktop ? 460 : 260,
      paused: true
    });
  }
);
用户操作流程:
  1. 页面加载时,根据当前窗口宽度选择 desktopmobile
  2. 点击“播放” → 执行对应距离的动画;
  3. 缩放浏览器宽度跨越 700px 临界点
    • 旧动画自动被销毁;
    • 新断点回调触发,创建新 tween(目标位置更新);
  4. 再次点击“播放” → 使用新目标值动画。

💡 这确保了:无论何时播放,动画总是适配当前屏幕尺寸的。


🌟 优势 vs 手动实现:

手动方式gsap.matchMedia()
window.addEventListener('resize', ...)✅ 自动监听
需手动 kill() 旧动画✅ 自动清理
容易内存泄漏(忘记 kill)✅ 安全无泄漏
代码分散、难维护✅ 集中式声明式管理
断点逻辑易出错✅ 与 CSS 媒体查询一致

⚙️ 高级用法:

返回清理函数(可选)
mm.add("(min-width: 700px)", () => {
  const tween = gsap.to(...);
  
  // 可返回一个函数,在上下文失效时调用
  return () => {
    console.log("桌面端动画已销毁");
  };
});
访问原始 MediaQueryList
mm.add("(max-width: 600px)", (context) => {
  const { mq } = context; // 原生 MediaQueryList 对象
  console.log(mq.matches);
});

⚠️ 注意事项:

  • 必须使用 GSAP 3.11.0+matchMedia 是较新特性);
  • 回调函数中的动画会被自动收集并管理,无需手动存储;
  • 如果动画需要跨断点复用(如只改参数),建议在 matchMedia 外创建,内部仅 invalidate().restart()
  • 免费功能matchMedia 是 GSAP 核心 API,无需额外插件或会员。

📚 官方文档:

👉 greensock.com/docs/v3/GSA…


✅ 总结:

gsap.matchMedia() 是 GSAP 为现代响应式 Web 设计提供的“智能动画路由器”——它让开发者用声明式语法,轻松实现多端适配的交互动效,并自动处理复杂的生命周期管理,是构建专业级响应式动画的标准方案。

什么是 context

<div class="card" id="scope">
      <h1>案例 40:context 与自动清理</h1>
      <p>gsap.context() 可以集中创建并一键清理动画。</p>
      <div class="stage">
        <div class="box" id="box"></div>
      </div>
      <div class="controls">
        <button id="create">创建动画</button>
        <button class="primary" id="revert">清理动画</button>
      </div>
      <div class="hint">点击清理后动画会被移除</div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
    <script>
      const scope = document.querySelector("#scope");
      const createButton = document.querySelector("#create");
      const revertButton = document.querySelector("#revert");
      let ctx;

      createButton.addEventListener("click", () => {
        if (ctx) {
          ctx.revert();
        }
        // context 在指定作用域内创建动画,便于统一清理
        ctx = gsap.context(() => {
          gsap.to("#box", { x: 420, duration: 1.2, ease: "power2.inOut" });
        }, scope);
      });

      revertButton.addEventListener("click", () => {
        if (ctx) {
          ctx.revert();
        }
      });
    </script>

GSAP(GreenSock Animation Platform) 中,gsap.context() 是一个用于组织和管理动画生命周期的工具函数。它的核心作用是:

将一组动画“打包”到一个上下文(context)中,并提供一键还原(revert)的能力,自动清理所有相关动画、恢复元素初始状态。


📌 简单定义:

gsap.context(() => { /* 动画代码 */ }, scope) 创建一个受控的动画环境,其中所有通过 GSAP 创建的动画都会被记录下来,后续调用 ctx.revert() 即可:

  • 停止所有动画
  • 将元素属性恢复到动画前的原始值
  • 释放内存,避免泄漏

这特别适合动态创建/销毁组件、单页应用(SPA)路由切换、模态框打开关闭等场景。


✅ 核心功能解析:

1. 自动收集动画

context 回调函数内创建的所有 GSAP 动画(包括 Timeline、Tween、ScrollTrigger 等)都会被自动追踪。

ctx = gsap.context(() => {
  gsap.to("#box", { x: 420 });           // 被记录
  gsap.timeline().to(".item", { opacity: 0 }); // 被记录
  ScrollTrigger.create({ ... });         // 被记录(如果引入了 ScrollTrigger)
});
2. 一键还原(revert()
ctx.revert(); // 执行以下操作:
// - kill 所有动画
// - 将 #box 的 x 恢复为动画前的值(比如 0)
// - 销毁 ScrollTrigger 实例
// - 清理内部引用,防止内存泄漏

💡 关键优势:你不需要手动记住每个 tweenscrollTriggerkill(),GSAP 全部帮你搞定!

3. 作用域限制(scope 参数)

第二个参数 scope(如你的 #scope 元素)用于:

  • 限定选择器的作用范围(类似 jQuery 的 .find()
  • 在 React/Vue 等框架中,通常传入当前组件的根 DOM 节点
gsap.context(() => {
  gsap.to("button", { scale: 1.2 }); // 只会选中 #scope 内的 button
}, scope); // ← 作用域

ctx = gsap.context(() => {
  gsap.to("#box", { x: 420, duration: 1.2 });
}, scope); // scope = .card 元素
  • 点击 “创建动画”
    • 如果已有 ctx,先 revert() 清理旧动画;
    • 创建新 context,启动盒子移动动画。
  • 点击 “清理动画”
    • 调用 ctx.revert()
    • 盒子立即回到原始位置(即使动画正在播放);
    • 所有内部状态被重置。

✅ 这就是为什么提示说:“点击清理后动画会被移除”——不仅是停止,更是完全回滚


🌟 典型应用场景:

场景说明
React / Vue 组件卸载useEffectonUnmounted 中调用 ctx.revert(),防止动画残留
模态框(Modal)关闭关闭时还原所有入场动画
页面切换(SPA)离开页面时清理 ScrollTrigger 和动画
动态内容加载加载新内容前清理旧动画,避免冲突
React 示例:
useEffect(() => {
  const ctx = gsap.context(() => {
    gsap.from(".header", { y: -50, opacity: 0 });
  }, containerRef);

  return () => ctx.revert(); // 组件卸载时自动清理
}, []);

⚠️ 注意事项:

  • revert() 不会删除 DOM 元素,只还原被 GSAP 控制的属性(如 x, opacity, backgroundColor 等);
  • 如果元素的初始状态是通过 CSS 设置的,GSAP 会在 context 创建时快照原始值,确保能正确还原;
  • 免费功能gsap.context() 是 GSAP 3.11+ 的核心 API,无需额外插件或会员;
  • 多次调用 revert() 是安全的(幂等操作)。

📚 官方文档:

👉 greensock.com/docs/v3/GSA…


✅ 总结:

gsap.context() 是 GSAP 提供的“动画沙盒”机制——它让开发者能安全地创建、隔离并一键销毁一组动画,极大简化了复杂应用中的状态管理和内存控制,是现代前端交互动效开发的最佳实践之一。