BACK

Perfect Loops for Coders

Project

Endless Loops of Controlled Chaos The process behind

  • Date of release: 2019-2021
  • Format: Gif Loops Generative
  • Plateforme: Objkt.com
  • Code: P5.js WEBGL
  • Link: Visit

Seamless Loops of Animated Chaos

Perfectly synchronized 1-3 second GIFs, crafted with p5.js.
Hundreds of particles move in endless, chaotic-looking cycles.
Each piece is meticulously coded to create smooth, invisible transitions, combining physical forces and phase shifts for an undetectable loop.



Loop with noise and dispersion

(Watch the progress bar as the end loops back to the start.)

Why Loops Are So Cool

Dark on netflix

I've always been captivated by sci-fi stories, especially those centered on the concept of time loops.
There’s a fascinating, almost unsettling quality to being caught in a cycle where events loop back to the beginning, repeating with eerie precision.
Stories like The Time Machine by H.G. Wells, which opened my imagination to the possibilities and paradoxes of time, films like Predestination and 12 Monkeys, and especially the German series Dark on Netflix, took this idea to new heights, exploring the dark consequences of time looping back on itself.

In a different way, visual loops capture a similar fascination. A perfectly synchronized, seamless animation loop has a hypnotic, almost meditative quality.Watching it, you get a sense of calm, like a visual heartbeat that’s forever in rhythm, pulling you into its infinite return. It’s as if you’re witnessing a closed-off world, one that’s set to replay forever, its own tiny universe obeying a law of perpetual motion.

Now picture this entire scene cycling flawlessly every few minutes, as if time itself were on repeat.

Imagine yourself standing in an office building on Broadway, looking down at the bustling street below. You see a sea of people, cars weaving through intersections, the energy of the city flowing in a dynamic rhythm. Imagine that this entire scene repeats on a perfect loop every few minutes—every person, every vehicle returning to the same spot, over and over, as if time itself is stuck in a loop (see Very Important Ants by Maciej Drabik who illustrates this idea very concretely).
It’s a vision that’s both captivating and surreal, and it’s this concept that has guided all the loops I create—a chance to capture that haunting, mesmerizing feeling of being suspended in an endless, perfectly recurring moment.


Aha Moment in Generative Design

My journey into perfect loops truly began with a revelation— a single tutorial by Daniel Shiffman, The Coding Train: Looping GIFs. This tutorial opened up a whole new world of creative possibilities, showing me how to craft endlessly repeating GIFs with seamless transitions. Through Shiffman’s guidance, I discovered how to create the illusion of infinite motion, using p5.js on the HTML canvas to bring my ideas to life. What made this process even more exciting was the introduction of Perlin noise, a method of adding randomness that retains fluidity. By incorporating Perlin noise 4D (but not always necessary), I could generate a unique variation of the same loop every time, allowing me to produce an array of distinct GIFs from the same underlying code.
This approach quickly became the foundation for countless experiments, sparking the creation of an entire collection of generative loops.

Code in p5 editor

Inspiration & ressources

Creating seamless loops requires both skill and artistry, and I’ve been fortunate to learn from and be inspired by several incredible creative coders who push the boundaries of generative art. Here are a few whose work has influenced me deeply, each offering unique perspectives and techniques for crafting mesmerizing loops:

  • Etienne Jacob (BleuJe) – Known for his intricate and often hypnotic black-and-white loops, Etienne’s work combines mathematics with generative art, creating complex animations that feel both organic and mechanical.
  • Dave Whyte (Bees and Bombs) – Dave’s loops are celebrated for their vibrant color schemes and satisfying, endlessly repeating patterns. His work, which often features abstract, playful animations, has been a major influence on the visual rhythm and aesthetic of my own creations.
  • Lionel Radisson (Makio135) – Lionel combines 3D and 2D techniques to create loops that are visually rich and deeply engaging. His expertise in blending generative processes with design principles has been invaluable, providing both inspiration and technical insights.

Each of these artists has contributed immensely to the field of generative loops, not only through their art but also by sharing insights into their creative processes. Their work continues to be a source of motivation as I explore the endless possibilities of looped animations.


The Dawn of My Loops

My initial steps into creating seamless loops started with simple 2D animations. These early experiments were a way to familiarize myself with the HTML canvas and explore its potential through p5.js.
2019 was a year of exploration and learning , where I focused on creating visual loops—often with mixed results. Many of the loops were rough, not always hitting the mark, but each attempt taught me something new about the intricacies of timing, transitions, and movement.

In total, I made over 200 gifs that year, sharing some with a private Facebook group dedicated to p5.js. It was here that I received valuable feedback and learned from others, allowing me to refine my approach and gain new insights. This small but vibrant community of creative coders became a source of motivation and support, and it was an incredible environment for growth.

Looking back, these early loops may not have been polished, but they laid the foundation for everything that followed, helping me understand the canvas as a tool and the art of looping as a craft.


Perfect loops with oscillations algorithms

Creating a seamless loop requires that the beginning aligns perfectly with the end of the sequence.

In creative coding, if you want a continuous, repeating progression where the beginning seamlessly matches the end, oscillation is a powerful solution. Here’s why :

  • Smooth Flow
    Oscillations create a continuous, mirrored wave that flows naturally.
  • Automatic Cycles
    Unlike linear movement, oscillations reset naturally, forming a perfect loop.
  • Rhythm Control
    Easily adjust speed and frequency for varied cycle pacing.
  • No Jarring Resets
    The smooth reversal in oscillations avoids abrupt jumps at loop boundaries.
  • Simple with Sine & Cosine
    Sine and cosine provide a flexible, cyclic pattern, perfect for continuous looping.

Maybe a loop would be more explicite

Oscillation Cycle - Offsets

By using oscillation, you create a loop that flows naturally and predictably—perfect for some situations where you want an evolving value to seamlessly repeat without noticeable breaks.

In this simple gif below, our animation cycles over 180 keyframes of a starry sky, without oscillations.

Each star has a lifespan, so the sequence must start with stars that were 'born' at the end and will 'die' shortly after the loop begins again. It’s the paradox of temporal loops... And honestly, I find this kind of challenge incredibly fun!

Non Looped animation - See the code

With oscillations, our animation cycle over 180 keyframes without interruptions.

Looped animation - See the code
And how can we achieve this with JavaScript code?

We'll do this in about 20 lines of code.

  • 1. Normalize Time for the Loop Cycle:
    To control the timing and create a seamless loop, we calculate a normalized time variable, tms:
    tms = (frameCount / nbFrames) % 1;
    This line ensures that tms smoothly cycles from 0 to 1, then resets at the start of each loop.
  • 2. Create an Array of Particles:
    We generate an array of particles with an initial loop:
    for (let i = 0; i < 1000; i++) {
      p = new Particle();
      particles.push(p);
    }
    Each particle is initialized with random x, y positions, and a unique phase.
  • 3. Offset Each Particle Within the Global Cycle:
    Each particle’s radius oscillates independently based on its phase in the class Particle. tms shifts it within the overall cycle. This technique allows all particles to oscillate together but with unique offsets:
    this.r = sin(this.phase + tms * TAU) * 2;
    Here there's Two sequences in the cycle.

See the code in p5 Editor below for more explanations (click on above )

Some loops I made with this technique (click for animated versions):
Limits of Oscillations in Perfect Cycles

While this cyclic system forms the basis of many loops, there are cases where movement cannot rely on oscillations alone.


In fact, most loops in WebGL require physical properties such as mass, velocity, acceleration, and attraction to simulate realistic forces.
These types of properties are not easily managed through oscillations, as they involve more dynamic, physics-based calculations that add depth and complexity to motion.

Perfect loops with physics algorithms

Now look at this kind of generative animation

Non looped animation - See the code

This animation captures a field of particles, each following its own unique trajectory across the canvas.

Imagine standing high above a city street, observing countless individuals and vehicles moving with purpose, yet each with their own path and pace.
Here, however, lies the challenge: How do we take this scene and make it loop seamlessly, creating an endless cycle where each particle returns to its starting position, recreating the exact same dynamic?

Particles in javascript are small, self-contained objects that can move, interact, and respond to forces, creating complex visuals when used together in a particles. Each particle usually has properties like position, velocity, and lifespan, allowing it to follow a unique path across the canvas.

How Do You Create a Perfect Loop with Objects Under Natural Forces?

To gain a deeper understanding of the physics and looping techniques behind particle systems, I recommend Chapter "Forces" from Daniel Shiffman's book The Nature of Code, which delves into the mechanics of particle movement.

At first glance, it might seem logical to ensure that every particle in the animation follows its path precisely so that, after a certain number of frames, it returns to its exact starting position. Each particle would "remember" its journey, repeating it endlessly in perfect synchronization.
However, this approach, while intuitive, is deceptively complex and ultimately unnecessary.

A simpler and more elegant solution, inspired by the concept of reincarnation.

A conversation with a friend who practices Buddhism revealed a simpler and more elegant solution, inspired by the concept of reincarnation.
In Buddhist philosophy, when someone is reborn, their physical form is replaced entirely—they do not return in the same body. Instead, it's the spiritual properties that carry forward into a new incarnation.
Applying this idea to our looping particles, we don’t need each particle to retrace its path to create a seamless cycle. Instead, each particle can "die" when it moves off-screen, and a new particle, with identical properties, can be "reborn" on the opposite side.

Destruction and rebirth (a reincarnated soul)

In this way, each new particle reincarnates the properties—velocity, direction, and size—of its corresponding particle from the previous cycle through the karma array.

This approach allows us to create an organized chaos that feels like a single, endless loop without the particles needing to remember their previous positions. It’s a looping illusion that feels organic, yet is achieved through strategic destruction and rebirth, much like a reincarnated soul.

Looped animation - See the code

However, achieving a perfect loop comes with a subtle challenge: if a particle’s velocity is too low, it might not have enough time to travel fully across the screen within the defined loop cycle.
This can lead to visible breaks in the loop where particles appear to "freeze" or disappear unexpectedly, breaking the illusion of seamless motion.
To address this, it’s essential to set a minimum velocity for each particle, ensuring that it completes its journey across the screen within the temporal bounds of the loop. This way, every particle can "live" its entire cycle and contribute to the fluidity of the animation, enhancing the illusion of infinite, uninterrupted motion.

When recording the loop as a GIF or video, it’s essential to avoid starting the capture from the very beginning of the cycle. Instead, allow the slowest particle enough time to travel across the entire screen, ensuring that it completes at least one full cycle. This approach prevents visible "jumps" or disruptions in the loop, as every particle will already be in synchronized motion. By capturing after the particles have naturally settled into their paths, we achieve a more seamless, hypnotic loop, where each element appears to flow endlessly without interruption.

Ensuring a Perfect, Seamless Loop
  • Set a minimum velocity for each particle to avoid breaks in the loop.
  • Ensure particles complete their full journey within the loop cycle.
  • Avoid starting the recording at the beginning of the loop cycle.
  • Let particles naturally settle into synchronized paths before capturing.
  • Start recording after particles have completed at least one full cycle for a smooth, uninterrupted loop.
Here are a few loops I crafted using this technique (click for animated versions):

In many of the GIFs above, randomness is substituted with a Perlin noise, a technique that brings a more organic and natural quality to the animation. Unlike pure randomness, which can feel abrupt and disjointed, noise produces a smooth, flowing variation that resembles patterns found in nature. This subtle change gives each element a lifelike movement, adding a cohesive, almost rhythmic quality to the visuals, making them feel more connected and pleasing to the eye.

In reality, there’s more happening in these GIFs than meets the eye to give them a natural, organic quality. The most impactful technique is animating a particle system rather than individual particles on each keyframe. By programming an entire system, I can create a far denser and more intricate flow of motion. Each particle interacts within the system, contributing to a collective visual that feels seamless and richly layered. This approach not only provides continuity but also introduces subtle variations and depth, making the final result look far more complex and immersive.


Perfect loops with particles system

If you’re not already familiar with particles or if you just want to understand the looping techniques used here, let’s start with a quick refresher. In JavaScript, particles are small, self-contained objects that can move, interact, and respond to forces, creating complex visuals when used together in a particle system. Each particle usually has properties like position, velocity, and lifespan, allowing it to follow a unique path across the canvas.

By organizing these particles into a system, we can simulate intricate behaviors like flowing water, drifting smoke, or, as in this case, a perfectly looping animation.

To gain a deeper understanding of the physics and looping techniques behind particle systems, I recommend Chapter "Forces" from Daniel Shiffman's book The Nature of Code, which delves into the mechanics of particle movement. Additionally, Shiffman’s Particle System tutorial on The Coding Train offers insights into particle-based visuals and is a helpful reference for implementing looped particle systems.

Non Looped animation - See the code
Looped animation - See the code

In this particle system, the logic remains similar to the previous chapter: each particle "reincarnates" into the next cycle, preserving certain properties. Here, however, each particle's position and velocity are influenced by noise, giving it a smooth, natural motion while adhering to the loop cycle. Here’s how it works:

  • Setting the Offset:
    const xoff = map(sin(tms * TAU), -1, 1, 0, 2); // x offset changes sinusoidally over the loop cycle
    We start by creating a sinusoidal oscillation (sin(tms * TAU)) to serve as a cyclic time marker. Mapping this value from -1 to 1 into 0 to 2 allows us to use xoff as an input for the noise function (the range -1 to 1 creates a mirror effect because negative values in the noise space behave similarly to positive ones).
  • Generating Smooth, Cyclic Horizontal Motion with Noise:
    this.pos.x = noise(xoff) * width;
    The noise (xoff) function provides a smooth, pseudo-random value that changes gradually based on the offset in the cycle.
  • Adding Vertical Velocity with Variation:
    this.vel = createVector(map(noise(1000 + xoff * 20), 0, 1, -2, 2), -1); Here, we add an upward velocity with some horizontal variation by mapping the noise value to a range of -2 to 2 for the x component. This ensures that particles move upward consistently (y = -1), while the horizontal component varies, adding depth and complexity to the loop. By using in 1000 + xoff * 20 "1000" as an offset and "xoff * 20" ensures that each particle has a unique x-velocity. Otherwise, we would get a smoke trail effect (try changing 20 to 0.1 in the code to see the difference).

By synchronizing noise with the cyclic time marker tms, each particle’s path flows smoothly within the loop, maintaining an organic motion that feels continuous, even over repeated cycles.

The vast majority of my GIFs use this technique to create natural, seamless loops.

Selection of Perfect Loops Using a Particle System (click for animated versions):

Final Reflections

Revisiting my creations from 2019 to 2021 has sparked a renewed desire to dive back into this world, bringing these works to specialized platforms dedicated to generative coding. The GIFs I previously shared on objkt.com were carefully curated; each piece was the result of code capable of generating infinite variations, yet I would only select three or four outputs to export as seamless loops, whether in GIF or video form. Now, I’m inspired to take one of these GIFs to a new level, refining it into a long-form generative piece that could endlessly evolve, captivating viewers in a continuous, organic flow.

If you enjoy this project, you can still acquire a few remaining editions as NFTs on Objkt.com.

Cheers for making it all the way through!

⇱ Back to Projects

  1. Why Loops Are So Cool
  2. Aha Moment in Generative Design
  3. Inspiration & ressources
  4. The Dawn of My Loops
  5. Perfect loops with oscillations
  6. Perfect loops with physics
  7. Perfect loops with particles system
  8. Final Reflexions