How to Create Seamless Loop Animations for X (Twitter)

Beautiful wave shape made with Processing programming code.


Want to create that "hypnotic" effect on social media where a video seems to play forever? The secret lies in making the first and last frames identical. In this post, I'll show you how to achieve a perfect seamless loop using Processing and some clever math.

 

Animating Sine Waves with Triple Perlin Noise

This creative coding piece uses a simple sine curve base, layered with Perlin noise for organic movement. To give the wave its complex, fluid feel, I combined three different noise values:


float lNoise = noise(lineRatio, radRatio);
float fNoise = noise(sin(PI * frmRatio));
float eNoise = noise(sin(PI * easeRatio));

The Logic Behind the Loop

The key to the seamless loop is the code sin(PI * frmRatio). Since sin(0) and sin(π) both equal zero, the noise value starts at a specific point, evolves, and eventually returns to exactly where it began. This ensures the Start value = End value, creating a gapless transition when replayed.

 

Source Code: "The Tide Is High" (Processing)

This code is available under the GPL. I would be honored to see any variations you create based on this logic!

Note: This script doesn't render to the screen in real-time. Instead, it exports each frame to a directory so you can compile them into a high-quality video file. (And no, it's not a candlestick chart! XD)




/**
 * 
 * The Tide Is High.
 * 
 * Processing 3.2.1
 * @author @deconbatch
 * @version 0.1
 * created 0.1 2019.12.29
 */

void setup() {
  size(720, 380);
  colorMode(HSB, 360, 100, 100, 100);
  blendMode(SCREEN);
 rectMode(CENTER);
  noStroke();
  noLoop();
}

void draw() {

  int   frmMax  = 24 * 12; // for 24fps x 12s animation
  int   lineMax = 50;
  int   speed   = 3;
  float rectDiv = 0.15;
  float rectWid = 10.0;
  float baseHue = random(360.0);
  
  translate(0.0, height * 0.5);
  for (int frmCnt = 0; frmCnt < frmMax; ++frmCnt) {

    float frmRatio = map(frmCnt, 0, frmMax, 0.0, 1.0);
    background(baseHue, 100.0, 40.0, 100.0);

    for (int lineCnt = 0; lineCnt < lineMax; lineCnt++) {

     float lineRatio = map(lineCnt, 0, lineMax, 0.0, 1.0);
      float easeRatio = easeInOutCubic((frmRatio + lineRatio) % 1.0); // add a difference to each line.

     for (float rad = 0; rad < TWO_PI; rad += rectDiv) {
        float radRatio = map(rad, 0.0, TWO_PI, 0.0, 1.0);
        float lNoise = noise(lineRatio, radRatio);
        float fNoise = noise(sin(PI * frmRatio));
        float eNoise = noise(sin(PI * easeRatio));

        float rectX = width * radRatio;
        float rectW = (0.2 + lineRatio) * rectWid;
        float waveShape = 0.4 * height * sin(rad + TWO_PI * speed * frmRatio + PI * lNoise);
        float rectY = waveShape * sin(PI * radRatio) * eNoise;
        float rectH = 20.0 + abs(waveShape) * fNoise;
        float rectHue = baseHue + 360.0 + sin(TWO_PI * (radRatio + easeRatio)) * 30.0;

        fill(rectHue % 360.0, 90.0, 10.0, 100.0);
        rect(rectX, rectY, rectW, rectH);
     }
    }
    saveFrame("frames/" + String.format("%04d", frmCnt) + ".png");
  }
  exit();
}

/**
 * easeInOutCubic easing function.
 * @param  t     0.0 - 1.0 : linear value.
 * @return float 0.0 - 1.0 : eased value.
 */
private float easeInOutCubic(float t) {
  t *= 2.0;
  if (t < 1.0) {
    return pow(t, 3) / 2.0;
  }
  t -= 2.0;
  return (pow(t, 3) + 2.0) / 2.0;
}


/*
Copyright (C) 2019- deconbatch

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>
*/



 

Gallery: Visual Variations

Beautiful wave shape made with the Perlin noise.

Beautiful wave shape made with the Perlin noise.

 

Next Post Previous Post
No Comment
Add Comment
comment url