HTML5 Canvas loading spinner


Some time ago I was looking for an HTML5 spinner to include in my project. I found some interesting tools such as loading.io, but as usual I wanted to create a custom one. Something barebones, simple and lightweight.

CanvaMap.

So here is the code. The javascript part is the following:

 1function Spinner(element) {
 2	this.canvasElement = document.getElementById(element);
 3	this.ctx = this.canvasElement.getContext('2d');
 4	this.ctx.translate(0, 0);
 5    this.ctx.scale(1, 1);
 6};
 7 
 8Spinner.prototype.drawLoadingAnimation = function() {
 9	var r=255, g=255, b=255; 		//Color
10	var main_radius = 20;			//Radius of the spinner
11	var small_radius = 3;			//Radius of the small circles
12	var extension = Math.PI*2		//Length of the trail
13	var increment = Math.PI/40;		//Animation smoothness
14	var increment1 = Math.PI/20;	//Shape smoothness
15	var penal = 50;					//Extend trail length
16 
17	var numberOfIterations = (extension / increment);
18	var rSteps = r / (numberOfIterations+penal);
19	var gSteps = g / (numberOfIterations+penal);
20	var bSteps = b / (numberOfIterations+penal);
21	
22	var circleSteps = small_radius / numberOfIterations;
23	var angle = 0;
24 
25	this.loadingAnimation = setInterval(function() {
26    	spinner.ctx.save();
27    	spinner.ctx.translate(spinner.ctx.canvas.width/2, spinner.ctx.canvas.height/2);
28    	spinner.ctx.fillStyle = "rgba("+0+", "+0+", "+0+", "+1+")";
29    	spinner.ctx.fillRect(-spinner.ctx.canvas.width/2, -spinner.ctx.canvas.height/2, spinner.ctx.canvas.width, spinner.ctx.canvas.height);
30        angle += increment1;
31        angle %= Math.PI*2;
32        spinner.ctx.rotate(angle);
33        spinner.ctx.save();
34		var r1=r, g1=g, b1=b;
35		var radius1 = small_radius;
36		for(var a=0; a<extension; a+=increment) {
37			spinner.ctx.rotate(-increment);
38			spinner.ctx.fillStyle = "rgba("+r1+","+g1+","+b1+","+1+")";
39			spinner.ctx.beginPath();
40			spinner.ctx.arc(0, main_radius, radius1, 0, Math.PI*2, true); 
41			spinner.ctx.closePath();
42			spinner.ctx.fill();
43			r1 = Math.floor(r1-rSteps);
44			g1 = Math.floor(g1-gSteps);
45			b1 = Math.floor(b1-bSteps);
46			radius1 = radius1-circleSteps;
47		}
48		spinner.ctx.restore();
49		spinner.ctx.restore();
50    }, 40);
51};

It can be customized by playing with the initial variables as shown in the comments. It uses an interval rather than a Timeout/AnimationFrame for simplicity, but it should be quite simple to make the switch. The html part to run the script is:

 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
<html>
	<head>
		<title>A simple HTML5 spinner example</title>
		<script type="text/javascript" src="spinner.js"></script>	
		<script type="text/javascript">
			function startSpinner() {
				spinner = new Spinner("spinner");
				spinner.drawLoadingAnimation();
			}
		</script>
		<style>
			body {
				margin: 0;
				padding: 0;
			}
			#spinner {
				width: 100%;
				height: 100%;
			}
		</style>
	</head>
	<body onLoad="startSpinner()">
		<canvas id="spinner">Canvas not supported</canvas>
	</body>
</html>