8 Queens Problem
Abhivadaye
Anagram Finder
Bouncing Spheres
Break Out
Classic Snake
Cycloids
Deflection Demo
Double Pendulum
EV Savings
Flocking
Fog fly through
Forces on Objects
Fractals
Game of Life
Horizontal Stars
Image Scanning
JSON Beautify
Julia Sets
Kaleidoscope
Kock Fractals
Lorenz Attractor
Mandlebrot Set
Meta Balls
Natural Flocking
Number Convert
Number Game
Pandemic Simulator
Particles & Nodes
Perlin Noise
Poisson Disk
QuadTree Search
Ripples
Set Demonstration
Sierpiński Triangles
Simple Pendulum
Sine Waves
Starfield
Super Shapes 2D
Target Finder
Tic Tac Toe
Voronoi Diagram
Who Moved My...
Ripples on an Image
25 Apr 2009

I first came across a ripple effect on images around 2002. The web page doesn't exist anymore, but someone archived the page. You can find it here. There is another implementation of the same that you can find here. I implemented this in Java around 2009 and now in Javascript.

I wanted to attempt to explain here how this works. For this to work, we need two buffers. These buffers are the same size of the number of pixels that need to be shown. These buffers are integer arrays that hold values that we will refer to as "States". A value of this state is just a number. At it's highest this value will be 512 after which it will slowly damp down to 0 each time the frame is refreshed. At its core, the function that generates the wave is this.

for(x in (Every Row in the image)) {
   for(y in (Every Column in the image)) {
      currentBuffer[x][y] = ( previousBuffer[x - 1][y] +
                              previousBuffer[x + 1][y] +
                              previousBuffer[x][y - 1] +
                              previousBuffer[x][y + 1]
                           ) / 2 - currentBuffer[x][y];

      let shading = currentBuffer[xm1][y] - currentBuffer[xp1][y];

      pixelColors[x][y] = shading;

      currentBuffer[x][y] = currentBuffer[x][y] * 0.85; //<--Damp the wave each pass
   }
}
//Switch the pixels every frame.
let temp = previousBuffer;
previousBuffer = currentBuffer;
currentBuffer = temp;
Each pixel on the current buffer is calculated as the sum of the surrounding pixels of the previous buffer. This value is then divided by 2 and is subtracted from its own value. The color or the shading is the left minus the right buffer. This is the one that creates the refractive effect. This can be converted to buffer values to the top and left as well, this creates a different refraction. The value in the current buffer is also dampened down. This helps in dissipating the values. Without this, the waves would go on forever. Finally, the current and the previous buffers are swapped. In effect, the values of each buffer is calculated as the values of the previous buffer and the buffer before that.

Below is a canvas where I have depicted 25 enlarged pixels in a 5 x 5 grid. Each pixel shows 3 values on it. In order they are

  1. Current state
  2. Previous state
  3. The pixel color. The pixel color is a difference between the pixel colors on the left and the right of the current pixel.
You can also speed up the animation on this canvas using the radio buttons below. Once you have seen the calculations in the Slow modes, switch to the Fast mode. This propagation of the waves will look more natural this way, but remember that it is the same calculations that happen in both modes.



And finally here's the actual implementation.


1. ripples.js - Download, index.html
//Code goes here
2. rippleDemo.js - Download, index.html
//Code goes here