2013-08-11

DIY Canvas Fountain

Intro

Another post in the "canvas drawing series". You can look up the basics of drawing etc. in the previous posts:

  1. Canvas Crossroad
  2. Canvas Balloons
  3. Canvas Bus
  4. Canvas Trains
  5. Canvas, circular motions and networks
  6. Canvas Wipers

DIY Canvas Fountain

Particle fountains are very common inspiration for the graphical demos. To be honest I didn't feel I had much to contribute to this area. Then It came to me that perhaps it would be a nice demo to build an interface that would enable the users to construct their very own fountain. An important part of this demo is "dat.gui".

Mouse events

Handling the mouse events is the backbone of this demo. Two basic events are mousedown and mousemove. First, we have to register our functions to the events:

 canvas.addEventListener.apply(canvas, ['mousedown', mouseClick, false]);
 canvas.addEventListener.apply(canvas, ['mousemove', mouseMove, false]);

Mouse coordinates

As a parameter to the above registered function an event is passed. The event has coordinates clientX and clientY, but the coordinates are not corresponding to the coordinates on the canvas, so there is a short pattern that we have to apply to convert event coordinates to canvas coordinates:

 var mouseX = event.clientX - document.documentElement.scrollLeft 
     - canvas.offsetLeft;
    var mouseY = event.clientY - document.documentElement.scrollTop 
        - canvas.offsetTop;

Particle physics

Every particle is fired at an angle with initial speed. This is 2D space, so we'll split the speed into two parts. After that on every draw call we'll update the coordinates.

 this.dx = speed * Math.cos(angle - Math.PI / 2);
 this.dy = speed * Math.sin(angle - Math.PI / 2);
 // and then in the draw function
 this.x += this.dx;
 this.y += this.dy;

Gravity

Gravity is an important part of this example. I've given a lot of thought on how to simulate it and found a simple solution. Since the gravity is a force the falling speed has to increase over time. The simplest method is to increase the y speed with a gravity constant ... as simple as one line:

 this.dy += fountainProps.gravity;

And here's my example on:
Codepen

No comments: