Skip to content

Instantly share code, notes, and snippets.

@marlun78
Last active December 12, 2015 03:29
Show Gist options
  • Save marlun78/4707550 to your computer and use it in GitHub Desktop.
Save marlun78/4707550 to your computer and use it in GitHub Desktop.
A simple <canvas> spinner
/**
* Canvas Loading Spinner
* Copyright (c) 2013, marlun78
* MIT License, https://gist.github.com/marlun78/bd0800cf5e8053ba9f83
*/
(function(){
'use strict';
var _lineCaps = ['butt', 'round', 'square'],
_rgba = 'rgba(color,alpha)';
function Spinner(options) {
var el,
opt = options || {};
this.created = +new Date();
this.fgRgb = _toRGB(opt.color) || [0, 0, 0];
this.fps = opt.fps || 1000 / 25;
this.lines = opt.lines || 16;
this.lineCap = _lineCaps[typeof opt.lineCap !== 'undefined' ? opt.lineCap : 1];
this.element = el = document.createElement('canvas');
this.context = el.getContext('2d');
this.bgHex = el.style.backgroundColor = opt.background || 'transparent';
this.height = el.height = opt.height || 50;
this.width = el.width = opt.width || 50;
if (opt.appendTo) {
this.appendTo(opt.appendTo);
if (opt.autoPlay) {
this.play();
}
}
}
function _draw() {
var color = _rgba.replace('color', this.fgRgb.join(',')),
created = this.created,
ctx = this.context,
lines = this.lines,
lineCap = this.lineCap,
height = this.height,
width = this.width;
function spin() {
var i = 0,
diff = new Date() - created,
rotation = parseInt((diff / 1000) * lines, 10) / lines;
ctx.save();
ctx.clearRect(0, 0, width, height);
ctx.translate(width / 2, height / 2);
ctx.rotate(Math.PI * 2 * rotation);
for (; i < lines; i++) {
ctx.beginPath();
ctx.rotate(Math.PI * 2 / lines);
ctx.lineCap = lineCap;
ctx.lineWidth = width / 30;
ctx.strokeStyle = color.replace('alpha', i / lines);
ctx.moveTo(width / 10, 0);
ctx.lineTo(width / 4, 0);
ctx.stroke();
}
ctx.restore();
}
return spin;
}
function _toRGB (hex) {
var r, g, b, isShort;
if (typeof hex !== 'string') {
return false;
}
hex = hex.replace('#', '');
isShort = hex.length === 3;
return [
parseInt(isShort ? Array(2).join(hex[0]) : hex.substr(0, 2), 16),
parseInt(isShort ? Array(2).join(hex[1]) : hex.substr(2, 2), 16),
parseInt(isShort ? Array(2).join(hex[2]) : hex.substr(4, 2), 16)
];
}
Spinner.prototype.appendTo = function(container) {
container.appendChild(this.element);
return this;
};
Spinner.prototype.play = function() {
this.intervalId = setInterval(_draw.call(this), this.fps);
return this;
};
Spinner.prototype.stop = function() {
clearInterval(this.intervalId);
return this;
};
Spinner.prototype.remove = function() {
var el = this.element;
this.stop();
el.parent.removeChild(el);
return this;
};
//Spin away...
new Spinner({
appendTo: document.body,
autoPlay: true
});
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment