Core

gsap.utils

gsap.utils is a set of helper functions built into GSAP core for the math that drives animation: `clamp`, `mapRange`, `random`, `snap`, `interpolate`, `wrap`, and `toArray`, among others. They ship with GSAP itself, so there's no plugin to register, and most of them return a reusable function when you omit the final value argument.

Updated June 30, 2026

Mechanics

How gsap.utils works

Every helper lives on gsap.utils and takes plain numbers in, plain numbers out. You call them anywhere: inside a mousemove handler, in a ScrollTrigger callback, or as a function-based value in a tween. The seven you reach for most:

  • clamp(min, max, value) constrains a number to a range. clamp(0, 100, 150) returns 100.
  • mapRange(inMin, inMax, outMin, outMax, value) remaps a number from one range to another. mapRange(0, 1, 0, 360, 0.5) turns a 0-1 progress into 180 degrees.
  • snap(increment, value) rounds to the nearest step, or to the nearest value in an array. snap(10, 23) is 20, snap([0, 100, 200], 150) picks the nearest of the three.
  • random(min, max, snapIncrement) returns a random number in a range. random(["red", "blue"]) picks from an array.
  • interpolate(start, end, progress) blends two values, including colors and objects. interpolate("#ff0000", "#0000ff", 0.5) is the midpoint color.
  • wrap(min, max, value) cycles a number back into a range. wrap(0, 360, 370) is 10, which is how infinite/looping rotations stay in bounds.
  • toArray(target) turns a selector string, NodeList, or single element into a real array so you can map over it.
script.js
Function form

Omit the value to get a reusable function

Most of these take the value to transform as the LAST argument. Leave it off and the helper hands you back a function preconfigured with the range or step. This is the form you want in a handler that fires every frame, so you build the config once instead of passing the same min/max on every call.

script.js

random is the exception

random does NOT use the omit-the-value trick. To get a reusable function, pass true as the last argument: gsap.utils.random(-200, 500, 10, true) returns a function that gives a fresh snapped random value each call. Every other util gives you the function by leaving the value off.

You can also chain them with gsap.utils.pipe(...), which runs the value through each function left to right. pipe(normalize, snap)(input) normalizes then snaps in one call.

When

Use it for

  • Mapping pointer or scroll position to a transform value (cursor X to tilt, scroll progress to rotation) with mapRange
  • Keeping a velocity- or distance-driven value inside safe bounds with clamp so a fast flick doesn't send an element off screen
  • Snapping a dragged or free value to a grid, notch, or set of allowed stops with snap
  • Looping a continuous rotation or carousel index back into range with wrap
  • Randomizing per-element values (x: "random(-100, 100, 5)" directly in tween vars, evaluated per target)
  • Normalizing a selector or NodeList into an array with toArray before you map over targets
Alternatives

Use something else when

  • You need per-frame position smoothing toward a target, that's gsap.quickTo, not a util, it owns its own interpolated tween
  • You're spreading values across many staggered elements, reach for gsap.utils.distribute (or the tween's stagger object) rather than hand-rolling indices
  • The value carries a unit ("100px", "50%"), mapRange and clamp work on raw numbers only, parse the unit first with getUnit / unitize
  • You only ever clamp one value once, plain Math.min/Math.max is fine, the util earns its place when you reuse the config or want the function form
In production

Used in these Annnimate components

These helpers are the quiet plumbing behind any component that turns a pointer or drag into motion. Three in the library lean on the exact math these utils express:

  • The Circular Slider calls gsap.utils.snap(sliceAngle, value) directly to lock the dial to its nearest slice after a drag settles, both in the Inertia snap callback and when restoring rotation
  • The Magnetic Button maps the cursor's position inside the button to a normalized -0.5..0.5 offset, then scales it by the strength, which is mapRange / normalize written out by hand
  • The Custom Cursor clamps its velocity-driven rotation with Math.max(-max, Math.min(max, v)), which is exactly what gsap.utils.clamp(-max, max, v) does in one call

Why this ships with every install

There's nothing to register, gsap.utils is part of GSAP core. That matters because GSAP runs on about 2.2% of all websites (w3techs.com, June 2026) and went 100% free, core plus every former Club plugin, on April 30 2025 (Webflow). So these helpers are available in every GSAP project at no extra cost and no extra import.
Used in components

See it running in production

FAQ

Common questions

What's the difference between gsap.utils.clamp and Math.min/Math.max?
Functionally nothing, clamp(0, 100, v) is Math.min(100, Math.max(0, v)). The win is readability and the function form: const clampFn = gsap.utils.clamp(0, 100) gives you a reusable clampFn(v) you can drop into a handler without repeating the bounds. For a one-off clamp, plain Math is fine.
How do I map scroll progress to a rotation or any other range in GSAP?
Use gsap.utils.mapRange(0, 1, outMin, outMax, progress). Inside a ScrollTrigger onUpdate, self.progress is 0-1, so gsap.utils.mapRange(0, 1, 0, 360, self.progress) gives you degrees. Build the function once with const toDeg = gsap.utils.mapRange(0, 1, 0, 360) and call toDeg(self.progress) each tick to avoid re-passing the range.
Why does gsap.utils.random need true instead of just omitting the value?
random is the one util that breaks the omit-the-value pattern, because it has no value argument to omit, it generates one. So to get a reusable function you pass true as the last argument: gsap.utils.random(-100, 100, 5, true) returns a function that yields a new snapped random number on each call. Every other util gives you the function by leaving the final value off.
Do I need to register a plugin or install anything to use gsap.utils?
No. gsap.utils is part of GSAP core, the same import as gsap.to. There's no gsap.registerPlugin call and no separate package. If you have GSAP, you have clamp, mapRange, snap, random, wrap, interpolate, and toArray.
When should I use gsap.utils.snap vs the snap property inside a tween?
Use gsap.utils.snap(increment, value) when you need to snap a value yourself, in a drag handler, an Inertia snap callback, or before setting a target. Use the tween's snap: { x: 20 } property when you want GSAP to snap the animated value as it lands at the end of a gsap.to. The Circular Slider uses both: the function form inside its Draggable/Inertia config, and direct calls when restoring a saved angle.