What is a canvas?
A canvas is similar to a real life physical canvas used by painters. It is basically a space that can be used to draw on. Unlike a real canvas an HTML canvas can have the image data added and removed with ease. Canvases are usually used when you want to have some form of interaction with the user or you want the users computer to do all the computation instead of the server.
What is Javascript?
If you don’t know what Javascript is then I don’t even know why you’re here. Where do you live? where do you come from? is this your first time on this planet? All jokes aside Javascript is just a scripting language used a lot on websites that want some computation done on teh users computer instead of the server.
Create and Inject a canvas
The first thing we need is to create a canvas. We could create a canvas in HTMLthen just get a reference to it in javascript or we can create on in Javascript and inject it into the webpage. I will be showing you the inject method as this allows you to add this script to any HTML page without the need for the HTML to be edited. We add 4 variables for storing information used in other functions and then the setupCanvas function itself. The comments should explain what each part of the code does.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
var w = window.innerWidth; // ge the width of the browser window var h = window.innerHeight; // get the height of teh browser window var bgcan // something to store our canvas var ctx // something to store our canvas context function setupCanvas(){ bgcan = document.createElement('canvas'); // make a new canvas object bgcan.id = 'bgcan'; // give it a name // set the webpage body's margin and padding to 0 (no gap between webpage contents and browser wall) document.body.style.margin = "0" document.body.style.padding = "0" document.body.appendChild(bgcan); // adds the canvas to the webpage body bgcan.width = w; // set width of canvas to window width bgcan.height = h; // same as above for height bgcan.style.position = "fixed" // set position (absolute,fixed) bgcan.style.top = "0" // pixels from top bgcan.style.left = "0" // pixels from left bgcan.style.zIndex = "-99" // place behind ctx = bgcan.getContext("2d"); // set canvas to 2d mode } |
The code above will add a canvas the same height and width of the browser window to the web page when we call it with setupCanvas()
If the browser windo is resized the canvas will no longer be the correct size and this is not what we want. So we will add a resize finction for when this happens:
1 2 3 4 5 6 7 |
// if window is resized do canvas too function resize(){ w = window.innerWidth; h = window.innerHeight; bgcan.width = w; bgcan.height = h; } |
Handling Events
The setupCanvas function isnt going to run itself and needs some sort fo event to start it. We will want it to run once the page has finished loading so that the correct window width and height is captured. While were doing this will will set up the other events we want to capture for this example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// MAIN // // when page finishes loading window.addEventListener("load", function(){ // create and add canvas setupCanvas("bgcanvas"); // run 1 frame every 16 milliseconds window.setInterval(update, 16); // listen for resize event from browser window.addEventListener('resize', resize, false); // when mouse moves onmousemove = function(e){ storemp(e.x, e.y)} }); |
The window.addEventListener(“load”… function will run once the page finishes loading. Here we create the canvas with setupCanvas, add a timer to run the update function once every 16 milliseconds, run the resize function when the resize event is fired and run the storemp function when the mouse is moved. Dont worry abuot the missing function we are going to add them now:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
var x = 0 // store mouse pointer x var y = 0; // store mouse pointer y // store mouse pointer position function storemp(mpx,mpy){ x = mpx; y = mpy } function update(){ } |
We now have everything in place except the animation code that draws the images on the canvas.
Drawing on the Canvas
This is the meat of the project where we get to use cool maths..(yeah I said it..COOL MATHS) to draw lines and shapes to the canvas. But before we do that we will add a few variabls which we wil use in the code:
1 2 3 |
var initMS = 0 // store the milliseconds since page load var pitwo = 2*Math.PI; // pi * 2 for drawing circles var sndrop = [] // an array for storing each drawn object |
Now we add the drawing code inside our update function we already made:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
function update(){ initMS=initMS+1 //increase our timer //clear canvas ctx.fillStyle ='#ffffff'; ctx.fillRect(0, 0, w,h); ctx.beginPath() // create new drop if(initMS%4 == 0){ // once every 4 frames // create new drop/snowflake at a random width and add to array sndrop.push({posx:Math.random()*w,posy:-10,size:1+Math.floor(Math.abs(Math.sin(initMS*0.1))*10)}) } ctx.fillStyle='#f0f0f0'; // set drop colour //draw drop falling/flowwing sndrop.forEach(function(item,index){ ctx.beginPath(); // start a new drawing path ctx.arc(item.posx,item.posy,item.size,0,pitwo); // draw a filled circle item.posx += Math.sin(initMS*0.01) * item.size*0.15 ; //add hosrizontal motion item.posy += item.size*0.15; //add vertical motion ctx.fill(); // fill the drawn shape(works as endpath) // if item is off screen if(item.posy > ((item.size*2)+h)){ sndrop.splice( index, 1 ); // removes element at index position } }); // make drop avoid mouse sndrop.forEach(function(item,index){ //is close to mp var xdist = (item.posx - x) // x distance from mouse var ydist = (item.posy - y) // y distance from mouse var squaredDist = xdist * xdist + ydist * ydist // squared distance var incircl = (squaredDist < 50000) // is less than roughly 707 squared var invertCircle = (50000 - squaredDist)/50000 //0-1 range ofr items in 707px range //if in range if(incircl){ item.posx +=xdist * invertCircle * 0.05 // move away from mouse item.posy +=ydist * invertCircle * 0.05 } }); } |
View Source Code or check out some other effects here with links to source code
If you like javascript you could try JSMatter which is a physics engine for javascript
Using setInterval() for animation is bad. setInterval() has tons of issues that can degrade performance. You should use requestAnimationFrame() instead.