关于 gsap-utils
面向使用 gsap.utils 的开发者,介绍动画中的数值映射、随机化、吸附、单位解析和集合处理等纯辅助函数。适用于 tween、ScrollTrigger 回调及驱动 GSAP 的 JavaScript 代码。
主要功能
- 01限制数值范围并映射区间
- 02生成随机值并吸附到步进值
- 03按目标位置分配动画属性
- 04解析单位与颜色
- 05处理选择器和数组集合
适用场景
- 01将滚动进度映射为动画数值
- 02为元素生成随机或网格位置
- 03在多个目标间分配动画参数
- 04在组件内限定元素选择范围
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nexu-io/ open-design --skill gsap-utils安装后在 Claude Code 中输入/gsap-utils确认已加载。
附带文件LICENSESOURCES.md
详细介绍
gsap.utils
整理自 GreenSock 官方 GSAP skills:https://github.com/greensock/gsap-skills
何时使用此技能
编写或审查使用 gsap.utils 进行数学运算、数组/集合处理、单位解析或动画值映射的代码时使用(例如,将滚动位置映射为某个值、随机化、对齐到网格,或对输入进行归一化)。
相关技能: 构建动画时与 gsap-core、gsap-timeline 和 gsap-scrolltrigger 配合使用;CustomEase 和其他缓动工具位于 gsap-plugins 中。
概述
gsap.utils 提供纯辅助函数;无需注册。可在补间变量(例如基于函数的值)、ScrollTrigger 或 Observer 回调中使用,也可用于任何驱动 GSAP 的 JS。所有工具都位于 gsap.utils 中(例如 gsap.utils.clamp())。
省略值:函数形式。 许多工具都接受要转换的值作为最后一个参数。省略该参数时,工具会返回一个稍后接受该值的函数。当需要使用相同配置对多个值进行限制、映射、归一化或对齐时,请使用函数形式(例如在 mousemove 处理程序或补间回调中)。例外:random()——将 true 作为最后一个参数传入,即可获取可复用函数(不要省略值);请参阅 random()。
// With value: returns the result
gsap.utils.clamp(0, 100, 150); // 100
// Without value: returns a function you call with the value later
let c = gsap.utils.clamp(0, 100);
c(150); // 100
c(-10); // 0
限制范围与映射范围
clamp(min, max, value?)
将值限制在 min 和 max 之间。省略 value 可获取一个函数:clamp(min, max)(value)。
gsap.utils.clamp(0, 100, 150); // 100
gsap.utils.clamp(0, 100, -10); // 0
let clampFn = gsap.utils.clamp(0, 100);
clampFn(150); // 100
mapRange(inMin, inMax, outMin, outMax, value?)
将值从一个范围映射到另一个范围。适用于将滚动位置、进度(0–1)或输入范围转换为动画范围。省略 value 可获取一个函数:mapRange(inMin, inMax, outMin, outMax)(value)。
gsap.utils.mapRange(0, 100, 0, 500, 50); // 250
gsap.utils.mapRange(0, 1, 0, 360, 0.5); // 180 (progress to degrees)
let mapFn = gsap.utils.mapRange(0, 100, 0, 500);
mapFn(50); // 250
normalize(min, max, value?)
返回给定范围内归一化为 0–1 的值。当目标范围为 0–1 时,这是映射的逆运算。省略 value 可获取一个函数:normalize(min, max)(value)。
gsap.utils.normalize(0, 100, 50); // 0.5
gsap.utils.normalize(100, 300, 200); // 0.5
let normFn = gsap.utils.normalize(0, 100);
normFn(50); // 0.5
interpolate(start, end, progress?)
按给定进度(0–1)在两个值之间进行插值。支持数字、颜色以及键匹配的对象。省略 progress 可获取一个函数:interpolate(start, end)(progress)。
gsap.utils.interpolate(0, 100, 0.5); // 50
gsap.utils.interpolate("#ff0000", "#0000ff", 0.5); // mid color
gsap.utils.interpolate({ x: 0, y: 0 }, { x: 100, y: 50 }, 0.5); // { x: 50, y: 25 }
let lerp = gsap.utils.interpolate(0, 100);
lerp(0.5); // 50
随机与对齐
random(minimum, maximum[, snapIncrement, returnFunction]) / random(array[, returnFunction])
返回 minimum–maximum 范围内的随机数,或从 array 中返回一个随机元素。可选参数 snapIncrement 会将结果对齐到最接近的倍数(例如,5 → 5 的倍数)。要获取可复用函数,将 true 作为最后一个参数(returnFunction)传入;返回的函数不接受参数,每次调用都会返回一个新的随机值。这是唯一一种使用 true 而非省略值来获取函数形式的工具。
// immediate value: number in range
gsap.utils.random(-100, 100); // e.g. 42.7
gsap.utils.random(0, 500, 5); // 0–500, snapped to nearest 5
// reusable function: pass true as last argument
let randomFn = gsap.utils.random(-200, 500, 10, true);
randomFn(); // random value in range, snapped to 10
randomFn(); // another random value
// array: pick one value at random
gsap.utils.random(["red", "blue", "green"]); // "red", "blue", or "green"
let randomFromArray = gsap.utils.random([0, 100, 200], true);
randomFromArray(); // 0, 100, or 200
补间变量中的字符串形式: 使用 "random(-100, 100)"、"random(-100, 100, 5)" 或 "random([0, 100, 200])";GSAP 会针对每个目标进行求值。
gsap.to(".box", { x: "random(-100, 100, 5)", duration: 1 });
gsap.to(".item", { backgroundColor: "random([red, blue, green])" });
snap(snapTo, value?)
将值对齐到 snapTo 的最接近倍数,或对齐到允许值数组中的最接近值。省略 value 可获取一个函数:snap(snapTo)(value)(或 snap(snapArray)(value))。
gsap.utils.snap(10, 23); // 20
gsap.utils.snap(0.25, 0.7); // 0.75
gsap.utils.snap([0, 100, 200], 150); // 100 or 200 (nearest in array)
let snapFn = gsap.utils.snap(10);
snapFn(23); // 20
用于补间,实现基于网格或步进的动画:
gsap.to(".x", { x: 200, snap: { x: 20 } });
shuffle(array)
返回一个包含相同元素、但顺序随机的新数组。用于随机打乱顺序(例如,与副本一起使用从 "random" 开始的 stagger)。
gsap.utils.shuffle([1, 2, 3, 4]); // e.g. [3, 1, 4, 2]
distribute(config)
返回一个函数,根据目标在数组(或网格)中的位置为每个目标分配一个值。内部用于高级错开效果;当需要为多个元素分配值(如缩放、透明度、x、延迟)时,可使用此方法。返回的函数接收 (index, target, targets)——可以手动调用,也可以将结果直接传入补间动画;GSAP 会针对每个目标调用该函数,并传入索引、元素和数组。
配置项(均为可选):
| 属性 | 类型 | 描述 |
|---|---|---|
base | Number | 起始值。默认为 0。 |
amount | Number | 要分配给所有目标的总量(加到 base 上)。例如,100 个目标使用 amount: 1 → 每个目标之间相差 0.01。若要为每个目标设置固定步长,请改用 each。 |
each | Number | 每个目标之间增加的量(加到 base 上)。例如,4 个目标使用 each: 1 → 0、1、2、3。若要将一个总量分配给所有目标,请改用 amount。 |
from | Number | String | Array | 分配的起始位置:索引,或 "start"、"center"、"edges"、"random"、"end",也可以是 [0.25, 0.75] 这样的比例。默认为 0。 |
grid | String | Array | 使用网格位置而不是平面索引:[rows, columns](例如 [5, 10]),或使用 "auto" 自动检测。若为平面数组则省略。 |
axis | String | 对于网格:限制为单个轴("x" 或 "y")。 |
ease | Ease | 沿缓动曲线分配值(例如 "power1.inOut")。默认为 "none"。 |
**在补间动画中:**将 distribute(config) 的结果作为属性值传入;GSAP 会针对每个目标调用该函数,并传入 (index, target, targets)。
// Scale: middle elements 0.5, outer edges 3 (amount 2.5 distributed from center)
gsap.to(".class", {
scale: gsap.utils.distribute({
base: 0.5,
amount: 2.5,
from: "center"
})
});
**手动使用:**使用 (index, target, targets) 调用返回的函数,以获取对应索引的值。
const distributor = gsap.utils.distribute({
base: 50,
amount: 100,
from: "center",
ease: "power1.inOut"
});
const targets = gsap.utils.toArray(".box");
const valueForIndex2 = distributor(2, targets[2], targets);
更多信息请参阅 distribute()。
单位和解析
getUnit(value)
返回值的单位字符串(例如 "px"、"%"、"deg")。可用于规范化或转换值。
gsap.utils.getUnit("100px"); // "px"
gsap.utils.getUnit("50%"); // "%"
gsap.utils.getUnit(42); // "" (unitless)
unitize(value, unit)
为数字附加单位;如果值已有单位,则原样返回。可用于构建 CSS 值或补间动画的结束值。
gsap.utils.unitize(100, "px"); // "100px"
gsap.utils.unitize("2rem", "px"); // "2rem" (unchanged)
splitColor(color, returnHSL?)
将颜色字符串转换为数组:[red, green, blue](0–255),或 [red, green, blue, alpha](存在或需要 alpha 时,RGBA 对应 4 个元素)。将 true 作为第二个参数(returnHSL)传入,可改为获取 [hue, saturation, lightness] 或 [hue, saturation, lightness, alpha](HSL/HSLA)。支持 "rgb()"、"rgba()"、"hsl()"、"hsla()"、十六进制和命名颜色(例如 "red")。可用于对颜色分量进行动画处理或构建渐变。参阅 splitColor()。
gsap.utils.splitColor("red"); // [255, 0, 0]
gsap.utils.splitColor("#6fb936"); // [111, 185, 54]
gsap.utils.splitColor("rgba(204, 153, 51, 0.5)"); // [204, 153, 51, 0.5] (4 elements)
gsap.utils.splitColor("#6fb936", true); // [94, 55, 47] (HSL: hue, saturation, lightness)
数组和集合
selector(scope)
返回一个限定作用域的选择器函数,仅查找给定元素(或 ref)内的元素。在组件中使用时,".box" 这样的选择器只会匹配该组件的后代元素,而不会匹配整个文档。接受 DOM 元素或 ref(例如 React ref;可处理 .current)。
const q = gsap.utils.selector(containerRef);
q(".box"); // array of .box elements inside container
gsap.to(q(".circle"), { x: 100 });
toArray(value, scope?)
将值转换为数组:选择器字符串(限定在指定元素内)、NodeList、HTMLCollection、单个元素或数组。在向 GSAP 传入混合输入(例如目标)且需要真正的数组时使用。
gsap.utils.toArray(".item"); // array of elements
gsap.utils.toArray(".item", container); // scoped to container
gsap.utils.toArray(nodeList); // [ ... ] from NodeList
pipe(...functions)
组合函数:pipe(f1, f2, f3)(value) 返回 f3(f2(f1(value)))。可在补间动画或回调中应用一系列转换时使用(例如规范化 → mapRange → snap)。
const fn = gsap.utils.pipe(
(v) => gsap.utils.normalize(0, 100, v),
(v) => gsap.utils.snap(0.1, v)
);
fn(50); // normalized then snapped
wrap(min, max, value?)
将值环绕到 min–max 范围内(包含 min,不包含 max)。可用于无限滚动或循环值。省略 value 可获取一个函数:wrap(min, max)(value)。
gsap.utils.wrap(0, 360, 370); // 10
gsap.utils.wrap(0, 360, -10); // 350
let wrapFn = gsap.utils.wrap(0, 360);
wrapFn(370); // 10
wrapYoyo(min, max, value?)
将值环绕到指定范围内,并在两端进行 yoyo(反弹)。可用于在范围内来回变化。省略 value 可获取一个函数:wrapYoyo(min, max)(value)。
gsap.utils.wrapYoyo(0, 100, 150); // 50 (bounces back)
let wrapY = gsap.utils.wrapYoyo(0, 100);
wrapY(150); // 50
最佳实践
- ✅ 当多次使用相同的范围/配置时,省略
value参数以获取可复用函数(例如滚动处理函数、补间回调):let mapFn = gsap.utils.mapRange(0, 1, 0, 360); mapFn(progress)。 - ✅ 对齐网格或按步进变化的值使用 snap;当 GSAP 或你的代码需要从选择器或 NodeList 获取真正的数组时,使用 toArray。
- ✅ 在组件中使用 gsap.utils.selector(scope),让选择器限定在容器或 ref 范围内。
请勿
- ❌ 假设 mapRange / normalize 会处理单位;它们只适用于数字。涉及单位时,请使用 getUnit / unitize。
- ❌ 覆盖或依赖未记录的行为;请遵循文档说明的 API。