gsap.utils
使用時機
在編寫或審閱使用 gsap.utils 進行數學運算、陣列/集合處理、單位解析或動畫數值映射(例如將滾動位置映射到某個值、隨機化、捕捉到網格或正規化輸入)的程式碼時採用。
相關技能: 在建立動畫時與 gsap-core、gsap-timeline 和 gsap-scrolltrigger 搭配使用;CustomEase 及其他緩動工具則在 gsap-plugins 中。
概述
gsap.utils 提供純輔助函式;無需註冊。可在補間變數(例如函式值)、ScrollTrigger 或 Observer 回呼,或任何驅動 GSAP 的 JavaScript 中使用。所有方法都位於 gsap.utils(例如 gsap.utils.clamp())。
省略值:函式形式。 許多工具接受要轉換的值作為最後一個引數。如果省略該引數,工具會回傳一個函式,該函式稍後再接受值。當你需要以相同配置對許多值進行 clamp、map、normalize 或 snap 操作時(例如在 mousemove 處理器或補間回呼中),請使用函式形式。例外:random() — 傳遞 true 作為最後一個引數以取得可重複使用的函式(不要省略值);請參閱 random()。
// 有值:回傳結果
gsap.utils.clamp(0, 100, 150); // 100
// 無值:回傳一個函式,稍後再用值呼叫
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(進度到角度)
let mapFn = gsap.utils.mapRange(0, 100, 0, 500);
mapFn(50); // 250
normalize(min, max, value?)
回傳指定範圍內正規化到 0–1 的值。當目標範圍為 0–1 時,是 map 的反向操作。省略 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); // 中間色
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 作為函式形式(而非省略值)的工具。
// 立即值:範圍內的數字
gsap.utils.random(-100, 100); // 例如 42.7
gsap.utils.random(0, 500, 5); // 0–500,捕捉到最近的 5
// 可重複使用的函式:傳遞 true 作為最後一個引數
let randomFn = gsap.utils.random(-200, 500, 10, true);
randomFn(); // 範圍內的隨機值,捕捉到 10
randomFn(); // 另一個隨機值
// 陣列:隨機選取一個值
gsap.utils.random(["red", "blue", "green"]); // "red"、"blue" 或 "green"
let randomFromArray = gsap.utils.random([0, 100, 200], true);
randomFromArray(); // 0、100 或 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 或 200(陣列中最近的值)
let snapFn = gsap.utils.snap(10);
snapFn(23); // 20
用於補間以實現網格或基於步驟的動畫:
gsap.to(".x", { x: 200, snap: { x: 20 } });
shuffle(array)
回傳一個包含相同元素但順序隨機的新陣列。用於隨機排序(例如使用副本進行 "random" 的交錯)。
gsap.utils.shuffle([1, 2, 3, 4]); // 例如 [3, 1, 4, 2]
distribute(config)
回傳一個函式,該函式根據目標在陣列(或網格)中的位置為每個目標指派值。內部用於進階交錯;當你需要將值分散到許多元素(例如 scale、opacity、x、delay)時使用。回傳的函式接收 (index, target, targets) — 可以手動呼叫,或直接將結果傳入補間;GSAP 會為每個目標以 index、element 和 array 呼叫它。
設定(皆可選):
| 屬性 | 類型 | 描述 |
|---|---|---|
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) 為每個目標呼叫該函式。
// 縮放:中間元素 0.5,外側邊緣 3(從中心分散總量 2.5)
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); // ""(無單位)
unitize(value, unit)
為數字附加單位,或如果數值已有單位,則原樣回傳。用於建構 CSS 值或補間結束值。
gsap.utils.unitize(100, "px"); // "100px"
gsap.utils.unitize("2rem", "px"); // "2rem"(不變)
splitColor(color, returnHSL?)
將顏色字串轉換為陣列:[red, green, blue](0–255),或當存在 alpha 或需要時為 [red, green, blue, alpha](4 個元素,RGBA)。傳遞 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 個元素)
gsap.utils.splitColor("#6fb936", true); // [94, 55, 47](HSL:色相、飽和度、明度)
陣列與集合
selector(scope)
回傳一個作用域選擇器函式,該函式僅在指定元素(或 ref)內尋找元素。用於元件中,使 ".box" 這類選擇器僅匹配該元件的子元素,而非整個文件。接受 DOM 元素或 ref(例如 React ref;處理 .current)。
const q = gsap.utils.selector(containerRef);
q(".box"); // container 內部的 .box 元素陣列
gsap.to(q(".circle"), { x: 100 });
toArray(value, scope?)
將值轉換為陣列:選擇器字串(作用域到元素)、NodeList、HTMLCollection、單個元素或陣列。用於將混合輸入傳遞給 GSAP(例如目標)且需要真正陣列時。
gsap.utils.toArray(".item"); // 元素陣列
gsap.utils.toArray(".item", container); // 作用域到 container
gsap.utils.toArray(nodeList); // 從 NodeList 轉換的 [ ... ]
pipe(...functions)
組合函式:pipe(f1, f2, f3)(value) 回傳 f3(f2(f1(value)))。用於在補間或回呼中應用轉換鏈(例如 normalize → mapRange → snap)。
const fn = gsap.utils.pipe(
(v) => gsap.utils.normalize(0, 100, v),
(v) => gsap.utils.snap(0.1, v)
);
fn(50); // 先正規化再捕捉
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?)
在範圍內以溜溜球方式包裝數值(在邊界處反彈)。用於在範圍內來回移動。省略 value 以取得函式:wrapYoyo(min, max)(value)。
gsap.utils.wrapYoyo(0, 100, 150); // 50(反彈回來)
let wrapY = gsap.utils.wrapYoyo(0, 100);
wrapY(150); // 50
最佳實踐
- ✅ 當相同範圍/配置被多次使用時(例如滾動處理器、補間回呼),省略值引數以取得可重複使用的函式:
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。