Flood fill - image transition effect


In just 16 lines of vanilla JavaScript you can recreate this simple image transition effect and practice your bitmap skills on the HTML5 Canvas.

Let's start with a simple version with just one image:

<html>
<body>
<canvas id="myCanvaswidth="600height="373"></canvas>
<script>
let image = new Image();
image.src = "example1.jpg";
let canvas = document.getElementById("myCanvas");
let context = canvas.getContext("2d");
let rowimageWidthimageHeight;
 
image.onload = function() {
  imageWidth = image.width;
  imageHeight = image.height;
  row = imageHeight;
  requestAnimationFrame(animate);
};
 
function animate() {
  context.drawImage(image0rowimageWidth100imageWidthrow);
  if (row > 0row--;
  else
    row = imageHeight;
  requestAnimationFrame(animate);
}
 
</script>
</body>
</html>



Here's how it works:

[5-6] set up the source image, which is not visible on the screen.
[7-8] set up the target Canvas
[11-13] once the image is loaded, get its dimensions
[15] start the animation

[18-24] The animation function is where all the action is and [19], which draws the 'falling block' is the most complicated part, so let's look at it in more detail:
It copies one row (a horizontal stripe with the height of one pixel) of the source image and puts it on top of the target Canvas, but stretches it vertically: its height is equal the value of 'row' .
In short, it copies a bitmap at coordinates (0,row) and size of (imageWidth, 1) from the source and pastes it at (0,0) with dimensions (imageWidth,row) to the destination.
The value of the variable 'row' starts equal to the height of the image [14] and then is reduced in every iteration.
You can read here about the drawImage function works.

It's easier to see it with an example. Let's say this is our source picture:

1
2
3
4
5

(the numbers correspond to the row numbers, so let's pretend our picture is only 5 pixels high)
The part drawn in the given iteration below is in red.

In the first iteration 'row' equals 5, so the code takes the lowest row from the source and puts it in all the rows of the target.

5
5
5
5
5

2nd iteration, row = 4. It takes row 4 from source and puts it in the top 4 rows of target:

4
4
4
4
5

3rd iteration:

3
3
3
4
5

4th:

2
2
3
4
5

And finally in the 5th iteration we copy the top row and the image is complete:
1
2
3
4
5


Back to our code: [20-23] decreases the value of 'row' and resets it to the bottom if the entire picture has been drawn.

Now for the full version of the code - with a couple of extra lines, we add an array of images [5-9] and the toggling mechanism [28-31]:

<html>
<body>
<canvas id="myCanvaswidth="600height="373"></canvas>
<script>
let image = [];
image[0] = new Image();
image[1] = new Image();
image[0].src = "example0.jpg";
image[1].src = "example1.jpg";
 
let canvas = document.getElementById("myCanvas");
let context = canvas.getContext("2d");
let rowimageWidthimageHeight;
let currentImage = 0;
 
image[0].onload = function() {
  imageWidth = image[0].width;
  imageHeight = image[0].height;
  row = imageHeight;
  requestAnimationFrame(animate);
};
 
function animate() {
  context.drawImage(image[currentImage], 0rowimageWidth100imageWidthrow);
  if (row > 0row--;
  else {
    row = imageHeight;
    if (currentImage == 1)
      currentImage = 0;
    else
      currentImage = 1;
  }
  requestAnimationFrame(animate);
}
 
</script>
</body>
</html>


You can try modifying the code so that the transition happens from a different direction, or even from multiple directions simultaneously, meeting in the center. Also, see what happens if you replace the '1' in drawImage with different values. Have fun!



Check out these programming tutorials:

JavaScript:

Optical illusion (18 lines)

Spinning squares - visual effect (25 lines)

Oldschool fire effect (20 lines)

Fireworks (60 lines)

Animated fractal (32 lines)

Physics engine for beginners

Physics engine - interactive sandbox

Physics engine - silly contraption

Starfield (21 lines)

Yin Yang with a twist (4 circles and 20 lines)

Tile map editor (70 lines)

Sine scroller (30 lines)

Interactive animated sprites

Your first program in JavaScript: you need 5 minutes and a notepad


Fractals in Excel

Python in Blender 3d:

Domino effect (10 lines)


Wrecking ball effect (14 lines)

3d fractal in Blender Python