Seamless Looping Wiggle Expression in After Effects

Creating a seamless, jump-free looping wiggle in Adobe After Effects requires replacing the standard wiggle() function with an expression that blends two offset noise calculations across a set duration. While the standard wiggle function generates infinite, non-repeating procedural noise, this guide details the exact expression needed to create perfectly repeating loops for properties like position, rotation, and opacity without relying on manual keyframing.

The Problem with the Standard Wiggle

The standard After Effects expression wiggle(frequency, amplitude) calculates continuous Perlin-style noise over time. When your composition loops back from the last frame to the first frame, the start and end values do not match, causing a sudden, visible jump.

To eliminate this jump, you must calculate two separate wiggle states over a defined loop period and use a linear interpolation function to transition smoothly between them.


The Seamless Looping Wiggle Expression

Alt-click (Windows) or Option-click (macOS) on the stopwatch of the property you want to animate (e.g., Position, Rotation, or Opacity) and paste the following expression:

freq = 1;        // Wiggles per second
amp = 50;        // Amount of wiggle
loopTime = 4;    // Loop duration in seconds

t = time % loopTime;
wiggle1 = wiggle(freq, amp, 1, 0.5, t);
wiggle2 = wiggle(freq, amp, 1, 0.5, t - loopTime);

linear(t, 0, loopTime, wiggle1, wiggle2);

How to Configure the Parameters

  1. freq (Frequency): Dictates how many times the value shifts per second. Lower values (e.g., 0.5 to 2) create slow, smooth movement; higher values create rapid shaking.
  2. amp (Amplitude): Dictates the intensity or maximum distance the property can travel from its original value. For rotation, this represents degrees; for position, this represents pixels.
  3. loopTime (Loop Duration): Must match the exact length of your loop or composition in seconds. If your loop is 5 seconds long, set loopTime = 5;.

How the Expression Works

  • t = time % loopTime; keeps the evaluation within the bounds of your loop duration using the modulo operator, resetting the timeline evaluation every time it reaches the loopTime.
  • wiggle1 evaluates the wiggle starting at time 0 and moving forward to loopTime.
  • wiggle2 evaluates the exact same wiggle pattern, but samples it from negative time (-loopTime) forward to 0.
  • linear(t, 0, loopTime, wiggle1, wiggle2) smoothly crossfades between wiggle1 and wiggle2. At the start of the loop (t = 0), the value is 100% wiggle1 (which matches what wiggle2 reaches at the end). At the end of the loop (t = loopTime), the value is 100% wiggle2. This mathematical alignment ensures that the first frame and the frame following the last frame are identical, creating a continuous loop with no sudden jumps.