photo used without permission from HTTP://ALLABOUTBIRDS.ORG, because F those guys

Infinite Farting Eagle

An introduction to Canvas and Particle Systems

Nicholas Ortenzio
6 min readAug 10, 2013

--

In celebration of Independence day, I thought it’d be nice to do a tutorial on creating a patriotic infinite farting eagle using html 5 CANVAS and a simple particle system.

Setting up the HTML & CSS

Let’s get the basic stuff out of the way. First, we need to create the canvas element in the body of our page. Make sure to specify the height and width and also give it an ID so we can easily access it using JavaScript.

<canvas id=”canvas” height=”500" width=”500"></canvas>

And you actually don’t need to include any CSS. I know you guys aren’t the brightest so I’m trying to keep it as simple as possible.

Now the Javascript

If you’ve made it this far, congratulations. I had my doubts but you proved me wrong. It gets harder from here so put down mommy’s teat and focus. First get a handle to the canvas and then get its 2d context. The context is what allows us to render things to the canvas

var canvas = document.getElementById(“canvas”);
var ctx = canvas.getContext(“2d”);

The next step in prepping our farting eagle is creating a new Image object with the src of image we’d like to use.

var eagle = new Image();
eagle.src = “http://www.allaboutbirds.org/guide/PHOTO/LARGE/bald_eagle_adult2.jpg”;

In order to animate anything, we need to call some rendering function in a loop, doing this every few milliseconds results in silky smooth animations. To do this we use window.requestAnimationFrame(). It’s sort of like window.setTimeout(), but you don’t have to supply a timeout duration. The browser will handle that by itself. Since this is a relatively new JS addition, I could have a vendor prefix, so look for the right one.

var requestAnimationFrame = 
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;

Now that we’ve got a handle to requestAnimationFrame, we need to supply it with a callback function. At the moment the function has just two lines of code. A call to renderEagle() (which I’ll detail in a bit), and at the very end, another call to onFrame using requestAnimationFrame. This is essentially what provides rendering loop.

var onFrame = function(timestamp) {
renderEagle();
requestAnimationFrame(onFrame);
};
// kick off animation
requestAnimationFrame(onFrame);

Next we need to write our renderEagle function. What this does is clear out the canvas by drawing a rectangle over the entire canvas with a fill color (I chose a blueish color to match the sky in the photo I used). Then we use the drawImage function to place the eagle image on the canvas.

var renderEagle = function () {
ctx.fillStyle=”#5881AF”;
ctx.fillRect(0,0,500,700);
ctx.drawImage(eagle, 0, 0);
};

At this point you can sit back and take a look at your handiwork. It should look simliar to this

Magestic

STOP; PARTICLE TIME!

The eagle farts are going to be a collection of simple particles, each with some basic attributes, like size, position, lifespan and color. We do this using, uh I don’t know, a decorator pattern? Whatever it doesn’t fucking matter what it’s called. Create a function called Fart, and inside the body, set the properties needed to describe the particle. This serves as a constructor which we use to instantiate new fart particles.

To give each particle some uniqueness, use the Math.random() function. It generates a random number between 0 & 1. So, to create a random number between any two numbers (x & y) use the formula

(Math.random() * (y-x)) + x)

If you’re generating a number between 0 and Y, the x’s do nothing and the formula looks like this

Math.random() * y

Fart Zone

Getting back to the particle object… I’ve created properties for all the values I need to initalize, track and change through out the life of a particle.

var Fart = function () { this.currSize = 0;
this.minSize = Math.random() * 20;
this.maxSize = Math.random() * 80 + 20;
this.currX = 0;
this.currY = 0;
this.startX = 250;
this.startY = 200;
this.lastY = (Math.random() * 200);
this.lastX = (Math.random() * 400) — 150;
this.borned = Date.now();
this.died = ((Math.random() * 7) * 1000) + this.borned;
this.lifespan = this.died — this.borned;
this.isAlive = true;

this.color = {
r : Math.floor((Math.random() * 80)),
g : Math.floor((Math.random() * 155) + 100),
b : Math.floor((Math.random() * 80)),
a : 1
};

return this;
};

Now everytime we create a new particle, it’ll have a nice random set of initial properties. But that is fairly static. In order for it to animate, there needs to be some change over time. I do this by creating a function that will linearly interpolate between the min and max values we generated based on the current time in a particles lifecycle.

var Fart = function () { this.evolve = function () {
var pct = (Date.now() — this.borned) / this.lifespan;
this.currSize = (pct * this.maxSize + this.minSize)
this.color.a = 1 — (1 * pct)
this.currX = pct * this.lastX + this.startX;
this.currY = pct * this.lastY + this.startY;
this.isAlive = (pct < 1);
return this;
}
};

In the above example, we calculate how far along the particle is in its life by subtracting the current date from the date it was created, and dividing that by the lifespan (a random number between 0 & 7 seconds). pct will have a value between 0 & 1. 0 is babby and 1 is old.

Like I said before, all the other values are calculated by linear interpolation.

Once the value of pct is greater than 1, we set this.isAlive variable to false. this is important.

Rendering Farts

Now that the particle is defined we have to create a collection that can be iterated over for rendering. An array works fine here. maxFarts refers to the maximum number of particles that can be alive at any one time.

var maxFarts = 30;
var fartCloud = [];

Then modify the onFrame function with the following two bits of code.

 if (fartCloud.length < maxFarts) {
fartCloud.push(new Fart());
};

This guy right here just says that if there are less than 30 particles in our collection, its okay to create a new one.

 fartCloud = fartCloud.filter(function (n,i) { 
n.evolve();
renderFart();
return n.isAlive;
});

This guy is doing triple duty. Array.filter() iterates through each element of the array, and inside that function, we call evolve(), which changes the properties of each particle slightly. Then we call the renderFart function (which isn’t written yet); and last we return n.isAlive, which is a true or false value. If it’s false, it is excluded from the array that filter() returns.

The last step is rendering the particle. I’m using canvas to draw circles using the current size, color, opacity, and x and y position of the particle as attributes.

var renderFart = function (fart) {
var c = fart.color;
ctx.beginPath();
ctx.fillStyle= “rgba(“ + c.r + “,” + c.g + “,” + c.b + “,” + c.a + “)”;
ctx.arc(fart.currX, fart.currY, fart.currSize, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();
};

DEMO

http://codepen.io/youbastard/pen/LAhpC

Conclusion

You should have your very own infinitely farting eagle! Well done! And now, like a mother eagle, I encourage you to leave the nest with the knowledge I have given you and use it to feast on rotting fish fillets that some guy left in the back of his pick up truck.

What?

Nicholas Ortenzio is a software developer currently working in the field of avian gender identity.

--

--