The default wiggle() is random, so if you loop your comp, there'll be a visible "jump" at the loop point. Here's how to make it seamless.
The problem: wiggle() generates pseudo-random values based on the current time. At the loop point (frame 0 vs last frame), the random values don't match.
The solution — Seamless Wiggle Expression:
freq = 2;
amp = 30;
loopDur = thisComp.duration;
t = time % loopDur;
wiggle1 = wiggle(freq, amp, 1, 0.5, t);
wiggle2 = wiggle(freq, amp, 1, 0.5, t - loopDur);
linear(t, 0, loopDur, wiggle1, wiggle2)
How it works:
1. Creates two wiggle calculations — one for the current loop position, one for the "previous" loop position
2. Uses linear() to crossfade between them over the duration
3. At the start of the loop, it's 100% wiggle1. At the end, it's 100% wiggle2
4. Since wiggle2 is calculated with the same parameters but offset by one loop duration, the crossfade creates a seamless transition
Simpler alternative (less smooth but easier):
freq = 2;
amp = 30;
posterizeTime(24);
wiggle(freq, amp)posterizeTime() makes the wiggle step-based rather than continuous, which can hide the loop point if your loop is long enough.
Best practices:
- Set your comp duration to an even number of seconds
- Test the loop by placing two instances of the comp side by side in a parent comp
- Lower frequencies (0.5-2) loop more convincingly than high frequencies
Pro tip: This technique is essential for creating looping backgrounds, animated textures, and seamless GIFs for social media.
Want a personalized answer for your project?
Ask Oliver for Free →