Wrapping Your Head Around Canvas: Part 6

It’s been sometime since I’ve updated this HTML5 Canvas series, but this article should round out the tutorial series as article 6. We’ve covered creating 2D shapes, images, how to animate said shapes and images, and WebGL basics. In my example from Part 5 we coded together a basic cube with materials. With these foundations set in place we can start diving deeper into WebGL through animating the objects and even piecing together particle effects. If you have any questions please take a moment to revisit my previous articles concerning Canvas:

One of the basics in learning how to work with basic motion in an animation setting, you learn about the physics and force that cause a basic bouncing ball. In the case of creating our particle effect, you can create falling particle that might mimic snowfall or simulate a dynamic ball pit. When we begin coding out our Canvas the pattern we’ll create will seem rather chaotic at first, but we can wrangle it all in to make something amazing. Hopefully by the end of this we can create a group of soft glowing edge particle with random paths that resemble fireflies.

Check out the results of the code in this article here.

Let’s put our canvas in place with the HTML:

```<canvas id="myCanvas" width="640" height="480">
Im sorry youre browser doesnt seem to support the CANVAS element.
Try upgrading to a modern browser like <a href="http://chrome.com">Chrome</a>.
</canvas>​```

You can proceed by either writing your corresponding Javascript in an external JS file, for all intensive purposes of this article, I’ll be writing the Javascript in the section of the HTML file.

```var canvas = document.getElementById('myCanvas');
var context = canvas.getContext("2d");```

Although the dimensions of our canvas have already been defined in the tag in our HTML, we need to define the dimensions with the Javascript as variables.

```var W = 640; var H = 480;
ctx.fillStyle = "#333";
ctx.fillRect (0,0,W,H);```

We’ve filled the space with a dark gray, something to make our particle pop against the background. And we’ve positioned the canvas on the page at a left and right of 0. You’ll notice that the variables for our width and height have already been used, this will allow us to dynamically change the dimensions. Getting down to the meat and potatoes of the article we’ll begin adding our first particle against the background.

```ctx.beginPath();
ctx.fillStyle = '#FFF';
ctx.arc(100, 100, 15, Math.PI*2, false);
ctx.fill();```

The arc method helps us create a circle element with the x and y coordinates at 100 and it has a radius of 15. For a more in depth explanation of the arguments for the arc method, read Part 1 of this series. The last method tells our canvas to fill in the particle we just created. Now that we’ve created the particle, let’s bring it to life with a little animation. Let’s wrap our particle in a ‘draw’ function.

```function draw {
ctx.beginPath();
ctx.fillStyle = '#FFF';
ctx.arc(x, y, 15, Math.PI*2, false);
ctx.fill();

x++;
y++;
}

var x = 100; var y = 100;

setInterval(draw, 110);```

By using setInterval we’re telling Javascript which element we want to animate in our first argument, and the speed of acceloration in the 2nd argument. If we increase the interval number, you can begin to see the particle slow down. Adversely if we decrease that interval number, the speed of our particle increases. For the time being ‘110’ seems to be an ideal speed. We’ve also introduced 2 new variables for the x and y properties of said particle.

From this point we’ll need to create an array above our draw function to help create multiple particle on the canvas like so:
```var particles = [];
for (var i = 0; i<50; i++) {
//we'd like to keep track of the particles, so we'll
add it to the bottom of our array

particles.push(new create_particle());
}```

If you noticed, we’ve created a new function in the last code code snippet, now it’s time for us to define the function:

```function create_particle() {
//the following will place the particles at random places on our canvas
this.x = Math.random()*W;
this.y = Math.random()*H;
}```

We can begin to play around with the velocity of each particle to make it appear as if each particle has it’s own random pattern it follows. Just below the code we just wrote about placing the particles around the canvas, place these two lines of code:

```function create_particle() {
//the following will place the particles
at random places on our canvas
this.x = Math.random()*W;
this.y = Math.random()*H;

this.vx = Math.random()*20-10;
this.vy = Math.random()*20-10;

//sizing the particles
}```

Setting the particle size to a random diameter gives us two things, one, not every particle in our scene should be uniform. Uniform is boring. And two, it provides us with a small sense of depth of field. One thing that you’ll notice is that some of our particles have a trail behind them. If we’re setting up a night time scene and mimicking fireflies you would notice a small trail of light but not noticeable enough for you to point it out. We’re going to go back to our ‘draw’ function and play around with the properties a little:

```function draw() {
ctx.globalCompositeOperation = 'source-over';

ctx.fillStyle = 'rgb(40, 31, 64);
ctx.fillRect(0, 0, W, H);

ctx.globalCompositeOperation = 'lighter';

for(var t = 0; t < particles.length; t++) {
var p = particles[t];

ctx.beginPath();

ctx.arc(p.x, p.y, p.radius, Math.PI*2, false);
ctx.fill();

p.x += p.vx;
p.y += p.vy;
}
}```

Let’s take a second or so to back up and review our new draw function. the very first line we’re introducing a globalCompositeOperation with the value of ‘source-over’. The reason being is that we’ve already colored the background a black color, that color shouldn’t blend with the previous color or else out background will disappear. From the on the second line we set the red, green, blue, and alpha properties of each particle, then finishing out that section with a fillRect method with properties for our x and y positions, then calling the width and height variables. now that we have those in place we can begin to blend the particle with the background with another globalCompositeOperation with a property of ‘lighter’. This is going to help us setup our gradient glow around each particle.

Now we can begin to draw each particle in the array we setup earlier with our t and p variables. To actually get each particle to appear on stage we round it out with ctx.beginPath();. Here we can start creating the glow around our ‘fireflies’. You can see that we’ve setup a variable of gradient that calls the createRadialGradient method. The gradient.addColorStop method helps us color the particles. For the purpose of this article we’ll be staying with certain shades of yellow, to give us that lighting bug glow. If you place close attention to the progression of the gradient, you can tell that the colors work their way from the inside out, with black being the last color. Then just like our background we create a fillStyle and then an arc.

Congratulations folks! you have successfully created random particles to populate. We can keep moving forward by adding things like velocity by adding the velocities after our gradient fillStyle before we close out the for {} in our draw function:

```p.x += p.vx;
p.y += p.vy;```

The code that follows the velocity portion of our Javascript constrains the particles to the stage. Like so:

```if(p.x < -50) p.x = W+50;
if(p.y < -50) p.y = H+50;
if(p.x > W+50) p.x = -50;
if(p.y > H+50) p.y = -50;```

If you have any questions about the results, check out my JSFiddle I built the scene in.

Alternatives

There are options out there to aid you with your particle needs. If someone has gone before you and done the leg work, why reinvent the wheel? Sparks.js is a simple and lightweight javascript library that creates 3D particles for you. It does require you to load three.js in order to work properly, but once combined they can work as a pretty powerful combo. If you want to try your hand at it, check out the in browser editor by Jerome Etienne.

Example

Today’s example has been brought to us by Dan Gries.

Josh is currently the Creative Director at Rappsody Studios located in Jacksonville, FL and has been working in across the web for close to eight years. He has a soft spot for front-end development and comics. More articles by Joshua Rapp