Easing

CustomWiggle

CustomWiggle is a GSAP easing plugin that makes a value oscillate back and forth a set number of times before settling on its end value. You tell it how many wiggles you want and which shape the oscillation should taper with, and it builds a CustomEase you can drop into any tween.

Updated July 1, 2026

Mechanics

How CustomWiggle works

A normal ease moves from 0 to 1 once. CustomWiggle instead crosses back and forth across the target several times inside a single tween, so the property overshoots, comes back past the start, overshoots less, and keeps damping until it lands on the end value. The number of crossings is the wiggles option, and the type option controls how the swings taper off.

The amplitude of the wiggle comes from the tween itself, not the ease. If you tween rotation to 10, the value swings between roughly +10 and -10 and settles at 10. CustomWiggle needs CustomEase registered alongside it because it builds a CustomEase under the hood.

script.js

The type option has five values: easeOut (default, swings shrink toward the end), easeInOut (small at both ends, biggest in the middle), anticipate (winds up before the main swing), uniform (every swing the same size), and random (irregular amplitudes for an organic shake).

When

Use it for

  • Error and rejection feedback (a form field shaking left-right on a bad submit)
  • Attention nudges on a button or icon that needs a glance without a full animation
  • Playful hover states where an element jiggles a few degrees and settles
  • Randomized rotation on a grid of items so each tile wobbles slightly differently
  • Character-by-character text that pops in with a little overshoot on each letter
Alternatives

Use something else when

  • You want a single overshoot-and-settle, not repeated swings, use back.out(1.7) instead
  • You want a springy, decaying bounce with weight, use elastic.out(1, 0.3)
  • You want a physical drop-and-bounce (a ball landing), use CustomBounce
  • You need a fully hand-drawn curve that isn't an oscillation at all, use CustomEase directly
  • The motion is continuous rather than a one-shot reaction (a looping idle animation), reach for a repeating timeline with yoyo: true
In production

Used in these Annnimate components

A wiggle ease reads as personality, so we keep it to components that are meant to feel reactive rather than smooth.

  • Random Rotate leans on the wiggle idea per tile, each item swings through a few degrees with a slightly different amplitude so the grid never looks mechanically synced
  • Popping Text uses a short overshoot-and-settle on each character as it appears, the same back-and-forth-then-rest shape CustomWiggle produces at low wiggle counts

Respect reduced motion

A wiggle is attention-grabbing motion by design, so it's exactly the kind of thing users with prefers-reduced-motion want turned off. Adoption of that query jumped from 34% of sites in 2022 to over 50% of mobile sites by 2024 (HTTP Archive Web Almanac 2024), so gate the wiggle behind gsap.matchMedia() and drop to a plain fade or an instant state when reduce is set.
Used in components

See it running in production

FAQ

Common questions

Do I need to register CustomEase to use CustomWiggle?
Yes. CustomWiggle builds a CustomEase internally, so register both: gsap.registerPlugin(CustomWiggle, CustomEase). If you only register CustomWiggle you'll get an error or a silent no-op. Both are free, as is every GSAP plugin since version 3.13 (2024).
How do I set how far the element wiggles?
You don't set the distance on the ease, you set it on the tween. CustomWiggle only shapes the oscillation. Tween rotation to 15 and the value swings between about +15 and -15 before settling on 15. Want a bigger shake? Increase the tween's target value, not a wiggle option.
What's the difference between wiggle type easeOut and uniform?
easeOut (the default) makes each successive swing smaller, so it looks like the motion is damping down and coming to rest, which is what most UI feedback wants. uniform keeps every swing the same size, which reads as a steady mechanical vibration with no sense of settling. Use easeOut for reactions, uniform for a constant buzz.
How many wiggles should I use?
For a quick error shake or a button nudge, 4 to 6 wiggles over 0.5s to 0.8s feels right. Fewer than 3 barely reads as a wiggle, and more than about 8 at a short duration turns into a blur. If you want a single overshoot with no repeat, you don't want CustomWiggle at all, use back.out.
Can I use the wiggle ease without pre-creating it with CustomWiggle.create?
Yes. GSAP accepts the shorthand string form directly on a tween: ease: "wiggle({ wiggles: 6, type: easeOut })". Pre-create with CustomWiggle.create("name", {...}) only when you want to reuse the same named ease across many tweens.