HTML5 Canvas JavaScript Animation Example

Share this article

Pretty cool HTML5 Canvas Example which uses JavaScript and the Canvas element to create an animation effect controlled by mouseover events. google-html5 Instructions: Mouse over the Google logo to move the balls around, and then watch them reassemble.

< !DOCTYPE HTML>



 
// animation globals
var t=0; 
var frameInterval = 25; // in ms
var canvas = null; // canvas DOM object
var context = null; // canvas context
 
// ball globals
var ballRadius = 10;
 
// physics globals
var collisionDamper = 0.3;
var floorFriction = 0.0005 * frameInterval;
var mouseForceMultiplier = 1 * frameInterval;
var restoreForce =0.002 * frameInterval;
 
var mouseX = 99999;
var mouseY = 99999;
 
var balls = null;
 
function Ball(x,y,vx,vy,color) {
	this.x=x;
	this.y=y;
	this.vx=vx;
	this.vy=vy;
	this.color=color;
 
	this.origX = x;
	this.origY = y;
}
 
function init() {
	canvas=document.getElementById("myCanvas");
	context=canvas.getContext("2d");
	initStageObjects();
	setInterval(updateStage, frameInterval);
}
 
function updateStage() {
	t+=frameInterval; 
	clearCanvas();
	updateStageObjects();
	drawStageObjects();	
}
 
function initStageObjects() {
	balls = new Array();
 
	var blue = "#3A5BCD";
	var red="#EF2B36";
	var yellow = "#FFC636";
	var green="#02A817";
 
	// G
	balls.push(new Ball(173,63,0,0,blue));
	balls.push(new Ball(158,53,0,0,blue));
	balls.push(new Ball(143,52,0,0,blue));
	balls.push(new Ball(130,53,0,0,blue));
	balls.push(new Ball(117,58,0,0,blue));
	balls.push(new Ball(110,70,0,0,blue));
	balls.push(new Ball(102,82,0,0,blue));
	balls.push(new Ball(104,96,0,0,blue));
	balls.push(new Ball(105,107,0,0,blue));
	balls.push(new Ball(110,120,0,0,blue));
	balls.push(new Ball(124,130,0,0,blue));
	balls.push(new Ball(139,136,0,0,blue));
	balls.push(new Ball(152,136,0,0,blue));
	balls.push(new Ball(166,136,0,0,blue));
	balls.push(new Ball(174,127,0,0,blue));
	balls.push(new Ball(179,110,0,0,blue));
	balls.push(new Ball(166,109,0,0,blue));
	balls.push(new Ball(156,110,0,0,blue));
 
	// O
	balls.push(new Ball(210,81,0,0,red));
	balls.push(new Ball(197,91,0,0,red));
	balls.push(new Ball(196,103,0,0,red));
	balls.push(new Ball(200,116,0,0,red));
	balls.push(new Ball(209,127,0,0,red));
	balls.push(new Ball(223,130,0,0,red));
	balls.push(new Ball(237,127,0,0,red));
	balls.push(new Ball(244,114,0,0,red));
	balls.push(new Ball(242,98,0,0,red));
	balls.push(new Ball(237,86,0,0,red));
	balls.push(new Ball(225,81,0,0,red));
 
	// O
	var oOffset = 67;
	balls.push(new Ball(oOffset + 210,81,0,0,yellow));
	balls.push(new Ball(oOffset + 197,91,0,0,yellow));
	balls.push(new Ball(oOffset + 196,103,0,0,yellow));
	balls.push(new Ball(oOffset + 200,116,0,0,yellow));
	balls.push(new Ball(oOffset + 209,127,0,0,yellow));
	balls.push(new Ball(oOffset + 223,130,0,0,yellow));
	balls.push(new Ball(oOffset + 237,127,0,0,yellow));
	balls.push(new Ball(oOffset + 244,114,0,0,yellow));
	balls.push(new Ball(oOffset + 242,98,0,0,yellow));
	balls.push(new Ball(oOffset + 237,86,0,0,yellow));
	balls.push(new Ball(oOffset + 225,81,0,0,yellow));
 
	// G
	balls.push(new Ball(370,80,0,0,blue));
	balls.push(new Ball(358,79,0,0,blue));
	balls.push(new Ball(346,79,0,0,blue));
	balls.push(new Ball(335,84,0,0,blue));
	balls.push(new Ball(330,98,0,0,blue));
	balls.push(new Ball(334,111,0,0,blue));
	balls.push(new Ball(348,116,0,0,blue));
	balls.push(new Ball(362,109,0,0,blue));
	balls.push(new Ball(362,94,0,0,blue));
	balls.push(new Ball(355,128,0,0,blue));
	balls.push(new Ball(340,135,0,0,blue));
	balls.push(new Ball(327,142,0,0,blue));
	balls.push(new Ball(325,155,0,0,blue));
	balls.push(new Ball(339,165,0,0,blue));
	balls.push(new Ball(352,166,0,0,blue));
	balls.push(new Ball(367,161,0,0,blue));
	balls.push(new Ball(371,149,0,0,blue));
	balls.push(new Ball(366,137,0,0,blue));
 
	// L
	balls.push(new Ball(394,49,0,0,green));
	balls.push(new Ball(381,50,0,0,green));
	balls.push(new Ball(391,61,0,0,green));
	balls.push(new Ball(390,73,0,0,green));
	balls.push(new Ball(392,89,0,0,green));
	balls.push(new Ball(390,105,0,0,green));
	balls.push(new Ball(390,118,0,0,green));
	balls.push(new Ball(388,128,0,0,green));
	balls.push(new Ball(400,128,0,0,green));
 
	// E
	balls.push(new Ball(426,101,0,0,red));
	balls.push(new Ball(436,98,0,0,red));
	balls.push(new Ball(451,95,0,0,red));
	balls.push(new Ball(449,83,0,0,red));
	balls.push(new Ball(443,78,0,0,red));
	balls.push(new Ball(430,77,0,0,red));
	balls.push(new Ball(418,82,0,0,red));
	balls.push(new Ball(414,93,0,0,red));
	balls.push(new Ball(412,108,0,0,red));
	balls.push(new Ball(420,120,0,0,red));
	balls.push(new Ball(430,127,0,0,red));
	balls.push(new Ball(442,130,0,0,red));
	balls.push(new Ball(450,125,0,0,red));
 
}
 
function drawStageObjects() {
	for (var n=0; n<balls .length; n++) {	
		context.beginPath();
		context.arc(balls[n].x,balls[n].y,ballRadius,
			0,2*Math.PI,false);
		context.fillStyle=balls[n].color;
		context.fill();
	}
 
 
}
 
function updateStageObjects() {
 
	for (var n=0; n<balls.length; n++) {
 
		// set ball position based on velocity
		balls[n].y+=balls[n].vy;
		balls[n].x+=balls[n].vx;
 
		// restore forces
 
 
 
		if (balls[n].x> balls[n].origX) {
			balls[n].vx -= restoreForce;
		}
		else {
			balls[n].vx += restoreForce;
		}
		if (balls[n].y > balls[n].origY) {
			balls[n].vy -= restoreForce;
		}
		else {
			balls[n].vy += restoreForce;
		}
 
 
 
		// mouse forces
		var distX = balls[n].x - mouseX;
		var distY = balls[n].y - mouseY;
 
		var radius = Math.sqrt(Math.pow(distX,2) + 
			Math.pow(distY,2));
 
		var totalDist = Math.abs(distX) + Math.abs(distY);
 
		var forceX = (Math.abs(distX) / totalDist) * 
			(1/radius) * mouseForceMultiplier;
		var forceY = (Math.abs(distY) / totalDist) * 
			(1/radius) * mouseForceMultiplier;
 
		if (distX>0) { // mouse is left of ball
			balls[n].vx += forceX;
		}
		else {
			balls[n].vx -= forceX;
		}
		if (distY>0) { // mouse is on top of ball
			balls[n].vy += forceY;
		}
		else {
			balls[n].vy -= forceY;
		}
 
 
		// floor friction
		if (balls[n].vx>0) {
			balls[n].vx-=floorFriction;
		}
		else if (balls[n].vx&lt;0) {
			balls[n].vx+=floorFriction;
		}
		if (balls[n].vy>0) {
			balls[n].vy-=floorFriction;
		}
		else if (balls[n].vy&lt;0) {
			balls[n].vy+=floorFriction;
		}
 
		// floor condition
		if (balls[n].y > (canvas.height-ballRadius)) {
			balls[n].y=canvas.height-ballRadius-2;
			balls[n].vy*=-1; 
			balls[n].vy*=(1-collisionDamper);
		}
 
		// ceiling condition
		if (balls[n].y < (ballRadius)) {
			balls[n].y=ballRadius+2;
			balls[n].vy*=-1; 
			balls[n].vy*=(1-collisionDamper);
		}
 
		// right wall condition
		if (balls[n].x > (canvas.width-ballRadius)) {
			balls[n].x=canvas.width-ballRadius-2;
			balls[n].vx*=-1;
			balls[n].vx*=(1-collisionDamper);
		}
 
		// left wall condition
		if (balls[n].x < (ballRadius)) {
			balls[n].x=ballRadius+2;
			balls[n].vx*=-1;
			balls[n].vx*=(1-collisionDamper);
		}	
	}
}
 
function clearCanvas() {
	context.clearRect(0,0,canvas.width, canvas.height);
}
 
function handleMouseMove(evt) {
	mouseX = evt.clientX - canvas.offsetLeft;
	mouseY = evt.clientY - canvas.offsetTop;	
}
 
function handleMouseOut() {
	mouseX = 99999;
	mouseY = 99999;
}
 



	
Source

Frequently Asked Questions (FAQs) about HTML5 Canvas Animation

How can I create smooth animations using HTML5 Canvas?

Creating smooth animations using HTML5 Canvas involves a few key steps. First, you need to create a canvas element in your HTML document. Then, in your JavaScript file, you need to get a reference to this canvas and its 2D context which provides you with a host of methods for drawing on the canvas.

To create an animation, you need to change the properties of the objects you’ve drawn on the canvas over time. This is typically done in a loop that updates the properties and then redraws the objects on every iteration. To make the animation smooth, you can use the requestAnimationFrame method which optimizes the animation for the best performance.

What are some common issues I might face when creating HTML5 Canvas animations and how can I solve them?

One common issue when creating HTML5 Canvas animations is the animation appearing choppy or not smooth. This can be due to a number of reasons such as not using requestAnimationFrame for your animation loop, or having too many objects on the canvas at once. To solve this, you can optimize your code to reduce the number of objects being drawn or use techniques like layering to improve performance.

Another issue is the animation not working at all. This could be due to errors in your code. Make sure to check your browser’s console for any error messages and debug your code accordingly.

How can I add interactivity to my HTML5 Canvas animations?

Adding interactivity to your HTML5 Canvas animations can be achieved by using event listeners. You can add event listeners to the canvas element for various user interactions like clicks, mouse movements, and key presses. In the event handler function, you can then update the properties of your objects based on the user’s interaction, creating an interactive animation.

Can I use HTML5 Canvas animations on mobile devices?

Yes, HTML5 Canvas animations can be used on mobile devices. However, there are a few considerations to keep in mind. First, not all mobile browsers may support all features of the HTML5 Canvas API. Therefore, it’s important to test your animations on various devices and browsers. Second, performance can be an issue on mobile devices due to their limited processing power. Therefore, you may need to optimize your animations for mobile devices.

How can I use HTML5 Canvas to create complex animations?

Creating complex animations with HTML5 Canvas involves using advanced features of the API. For example, you can use transformations to rotate, scale, and skew your objects. You can also use paths to create complex shapes and curves. Additionally, you can use gradients and patterns to fill your objects with complex colors and textures. Finally, you can use clipping paths to control which parts of your objects are visible.

Can I use external libraries to create HTML5 Canvas animations?

Yes, there are several external libraries available that can simplify the process of creating HTML5 Canvas animations. These libraries provide higher-level APIs that can make it easier to create complex animations. Some popular libraries include Three.js for 3D animations, p5.js for 2D animations, and GSAP for timeline-based animations.

How can I optimize my HTML5 Canvas animations for better performance?

Optimizing HTML5 Canvas animations for better performance can involve several strategies. One strategy is to reduce the number of objects being drawn on the canvas. Another is to use layering, where you draw static objects on one canvas and animated objects on another, reducing the amount of redrawing needed. You can also use techniques like sprite sheets and bitmap caching to improve performance.

Can I use HTML5 Canvas animations in a responsive design?

Yes, HTML5 Canvas animations can be used in a responsive design. However, you need to ensure that your canvas and its contents scale properly when the size of the viewport changes. This can be achieved by listening for the window’s resize event and then adjusting the size of the canvas and the properties of the objects accordingly.

How can I debug my HTML5 Canvas animations?

Debugging HTML5 Canvas animations can be done using your browser’s developer tools. The console can be used to log any errors or important information. The debugger can be used to step through your code and inspect the values of variables at different points in time. Additionally, you can use the performance tools to analyze the performance of your animations and identify any bottlenecks.

Can I use HTML5 Canvas animations with other web technologies?

Yes, HTML5 Canvas animations can be used in conjunction with other web technologies. For example, you can use CSS to style your canvas and its surrounding elements. You can use JavaScript libraries like jQuery to handle user interactions. You can also use server-side technologies like PHP or Node.js to generate dynamic canvas content.

Sam DeeringSam Deering
View Author

Sam Deering has 15+ years of programming and website development experience. He was a website consultant at Console, ABC News, Flight Centre, Sapient Nitro, and the QLD Government and runs a tech blog with over 1 million views per month. Currently, Sam is the Founder of Crypto News, Australia.

Google Tutorials & Articleshtml5 canvasjQuery
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week