Some time ago I was looking for an HTML5 spinner to include in my project CanvaMap.
I found some interesting tools such as CanvasLoader, but as usual I wanted to create a custom one. Something barebones, simple and lightweight.
So here is the code. The javascript part is the following:
var spinner; function Spinner(element) { this.canvasElement = document.getElementById(element); this.ctx = this.canvasElement.getContext('2d'); this.ctx.translate(0, 0); this.ctx.scale(1, 1); }; Spinner.prototype.drawLoadingAnimation = function() { var r=255, g=255, b=255; //Color var main_radius = 20; //Radius of the spinner var small_radius = 3; //Radius of the small circles var extension = Math.PI*2 //Length of the trail var increment = Math.PI/40; //Animation smoothness var increment1 = Math.PI/20; //Shape smoothness var penal = 50; //Extend trail length var numberOfIterations = (extension / increment); var rSteps = r / (numberOfIterations+penal); var gSteps = g / (numberOfIterations+penal); var bSteps = b / (numberOfIterations+penal); var circleSteps = small_radius / numberOfIterations; var angle = 0; this.loadingAnimation = setInterval(function() { spinner.ctx.save(); spinner.ctx.translate(spinner.ctx.canvas.width/2, spinner.ctx.canvas.height/2); spinner.ctx.fillStyle = "rgba("+0+", "+0+", "+0+", "+1+")"; spinner.ctx.fillRect(-spinner.ctx.canvas.width/2, -spinner.ctx.canvas.height/2, spinner.ctx.canvas.width, spinner.ctx.canvas.height); angle += increment1; angle %= Math.PI*2; spinner.ctx.rotate(angle); spinner.ctx.save(); var r1=r, g1=g, b1=b; var radius1 = small_radius; for(var a=0; a<extension; a+=increment) { spinner.ctx.rotate(-increment); spinner.ctx.fillStyle = "rgba("+r1+","+g1+","+b1+","+1+")"; spinner.ctx.beginPath(); spinner.ctx.arc(0, main_radius, radius1, 0, Math.PI*2, true); spinner.ctx.closePath(); spinner.ctx.fill(); r1 = Math.floor(r1-rSteps); g1 = Math.floor(g1-gSteps); b1 = Math.floor(b1-bSteps); radius1 = radius1-circleSteps; } spinner.ctx.restore(); spinner.ctx.restore(); }, 40); };
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:
<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>