I have moved...

This website is no longer being updated. I have a new home for my art and photography at:


Please come say hi!

Tag Archive: Fountain

HTML5 Canvas Fountain

May 22, 2010

HTML5 Fountain Animation Screenshot

A bit more arsing about with HTML5. Purely decorative, completely non-interactive this time. An animated fountain based on one I wrote in AS3 which in turn was based closely on one from the absolutely brilliant Foundation ActionScript 3 Animation: Making Things Move! (seriously, if you need a good basis in programmed animation/interaction this book is a godsend, explained in simple terms and with a brilliant separation of concept from code so the information and tutorials can be easily applied to languages other than Actionscript 3).

View Demo.

Converting to Javascript was pretty straight forward, after all the syntax has the same origins. It’s slightly easier to achieve in Actionscript as Flash has built in the concepts of independent visual objects, wheras the canvas tag does not and so you need to roll your own, which for a simple example as this is not a problem, and I’m guessing there will be some nice JS frameworks around fairly soon which will make the job easier. Strongly tempted to convert a load of the other tutorials from Foundation AS3 to Javascript as well but not a great use of time and the author may (understandably) hunt me down and beat me to death.

The app is pretty simple, it generates a load of circles, each with it’s own direction, velocity, colour and size which move away from the center, when they are off the screen they are reset with new velocity, colour, size, etc and put back to the center again. That’s it. Here’s the code, it’s not very polished but it works…

(download the js source)


Just the required bits…

  1. <canvas width="500" height="400" id="MyCanvas">I AM A CANVAS!</canvas>

That was easy. You just need a canvas tag. I’ve given it the original id of ‘MyCanvas’. Next up…

The Javascript

Once again, I’ve used jQuery to get things moving quickly, you don’t need to but it makes life easier.

  1. var tId;
  2. var cHeight = 0;
  3. var cWidth = 0;
  4. var numBalls = 100;
  5. var balls = new Array();

First we set some global variables as follows:

  • tId: A variable to hold the interval id. We don’t actually need this but it’s handy if we wanted to add more functionality later, and good practice (IMHO).
  • cHeight, cWidth: The canvas dimensions. Will be set shortly.
  • numBalls: The number of balls you wish to display. Change this if you fancy.
  • balls: An array of ball objects.
  1. function Ball(){
  2.         this.xPos = 0;
  3.         this.yPos = 0;
  4.         this.vx = 0;
  5.         this.vy = 0;
  6.         this.radius = 5;
  7.         this.colour;
  8.         this.wind;
  9.         this.gravity;
  10.         this.sizeWobble;
  12.         this.reset = function() {
  13.                 this.xPos = cWidth / 2;
  14.                 this.yPos = cHeight / 2;
  15.                 this.vx = Math.random() * 10 5;
  16.                 this.vy = Math.random() * 10 5;
  17.                 this.colour = randomColour();
  18.                 this.wind = Math.random() * 2 1;
  19.                 this.gravity = Math.random() * 2 1;
  20.                 this.radius = Math.random() * 20 + 5;
  21.                 this.sizeWobble = Math.random() * 2 1;
  22.         }
  23. }

Define a ‘Ball’ class. The xPos/yPos determine the ball’s current position in the canvas. vx and vy are the Ball’s x and y velocity. Wind and Gravity and horizontal and vertical force. The strangely named ‘sizeWobble’ is the amount the ball radius changes each frame. The reset function sets up the ball, most parameters are randomly generated, xPos and yPos are set to the center of the canvas.

  1. jQuery(document).ready(function($){
  3.         // Set canvas values
  4.         cHeight = parseInt($(‘#MyCanvas’).height());
  5.         cWidth = parseInt($(‘#MyCanvas’).width());
  7.         // Generate balls
  8.         for(var i = 0;i < numBalls;i++){
  9.                 balls.push(new Ball());
  10.                 balls[i].reset();
  11.         }
  13.         tId = setInterval(‘drawBalls()’, 50);
  15. });

The core of the script. Wrapped up in a nice jQuery document ready handler. First we set the globals for the canvas dimensions (as used by the reset method in the Ball class). Then we loop as many times as we want balls, create a new ball each loop instance, add it to the balls array and reset it.

Once our balls are created we use setInterval to call the ‘drawBalls’ function every 50 microseconds.

  1. function drawBalls(){
  2.         clearCanvas();
  3.         var context = document.getElementById(‘MyCanvas’).getContext(‘2d’);
  4.         for(var i = 0;i < numBalls;i++){
  5.                 drawCircle(balls[i].xPos, balls[i].yPos, balls[i].radius, balls[i].colour);
  6.                 balls[i].vy += balls[i].gravity;
  7.                 balls[i].vx += balls[i].wind;
  8.                 balls[i].xPos += balls[i].vx;
  9.                 balls[i].yPos += balls[i].vy;
  10.                 if(balls[i].radius > 2){
  11.                         balls[i].radius += balls[i].sizeWobble;
  12.                 }
  14.                 if(
  15.                         balls[i].xPos balls[i].radius > cWidth||
  16.                         balls[i].xPos + balls[i].radius < 0||
  17.                         balls[i].yPos balls[i].radius > cHeight||
  18.                         balls[i].yPos + balls[i].radius < 0
  19.                         ){
  20.                                 balls[i].reset();
  21.                         }
  23.         }
  24. }

This is the function that’s called each ‘frame’ by the setInterval command. First we clear the canvas. Next we get a context for the canvas. Then we loop through the array of balls. For each one we:

  1. Draw it using drawCircle, passing it’s current position, radius and colour
  2. Adjust it’s x and v velocity modifiers using the gravity/wind values
  3. Update it’s stored position using it’s velocity modifiers
  4. If it’s radius is greater than 2 adjust it by it’s sizeWobble! (the min size check ensures it doesn’t completely disappear)
  5. If it is no longer on the canvas, reset it.

That’s pretty much it, the remaining three functions are helpers. clearCanvas clears the canvas by setting it’s width (must find a more logical method of doing this). randomColour returns a random colour in the appropriate format and drawCircle draws a circle to the canvas…

  1. function clearCanvas(){
  2.         $(‘#MyCanvas’).attr(‘width’,$(‘#MyCanvas’).attr(‘width’));
  3. }
  5. function randomColour(){
  6.         var red = Math.round(Math.random() * 255);
  7.         var green = Math.round(Math.random() * 255);
  8.         var blue = Math.round(Math.random() * 255);
  9.         return "rgb(" + red + ", " + green + ", " + blue + ")";
  10. }
  12. function drawCircle(cx, cy, radius, colour){
  13.     var ctx = document.getElementById(‘MyCanvas’).getContext(‘2d’);
  14.     ctx.fillStyle = colour;
  15.     ctx.strokeStyle = "rgb(60, 80, 50)";
  16.     ctx.beginPath();
  17.     ctx.arc(cx,cy,radius,0,Math.PI*2,true); // Outer circle
  18.     ctx.fill();
  19.     ctx.stroke();
  20. }

View Demo.

Follow Me…

  • Follow me on Facebook
  • Follow me on Instagram
  • Follow me on Tumblr
  • Follow me on Flickr
  • Follow me on YouTube
  • Follow me on Pinterest
  • Follow me on Twitter

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.


I am Bob. This is my blog. It is an outlet and a substitute for real life. It contains my art, photography, illustration and thoughts on mental health (I deal with anxiety on a pretty much constant basis).

Buy My Stuff

Help fund my existence. Buy my stuff (t-shirts, art prints, stock images & graphics)

Currently Reading

A Bookkeepers Guide to Practical Sorcery

Why? *+-Because it's brilliant.

The Daily Stoic

Why? *+-It was one of the best gifts in a while. I read it every morning.

Light: Science and Magic

Why? *+-I'm learning to be a better photographer.

How to write a novel using the snowflake method

Why? *+-I'm learning to write and reading any book on the subject that looks interesting.

Symmetry: The Ordering Principle

Why? *+-Inspiration and research.

Dungeon Master’s Guide

Why? *+-Because I'm a massive geek in the middle of a nostalgia episode

I Tell It Like It Is - T-shirts for your inner straight talking idiot

I’m on Patreon

I’m on Patreon

*+-Come visit me on Patreon for further art and photography.
Organic Contrast Nature Art Postcards

Organic Contrast Nature Art Postcards

*+-Silhouettes of nature in stasis combined with geometric forms. On actual card!
Winter Branch Snowflake T-shirt Forest Shrine – T-shirt and Mug

Let's Keep In Touch!

Enter your details below for updates on art and photography projects, discount codes on merchandise and other esoterica.

Your information will absolutely not be shared with any third parties and you can unsubscribe at any time. I use Campaign Monitor to manage my mailing list.

No thanks. Stop pestering me.