Created
March 1, 2011 04:38
-
-
Save dgb/848616 to your computer and use it in GitHub Desktop.
Refactored Canvas AJAX Spinner
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Ajax spinning indicator. The constructor accepts two arguments: | |
element - the canvas element of the spinner | |
options - an object of options that are initialized with the instance | |
- check out the code to see what options you have :P | |
This thing is more or less refactored from Adam's work: | |
http://starkravingcoder.blogspot.com/2007/09/canvas-loading-indicator.html | |
No license was specified by Adam, so as a sort-of derivitive work, | |
I'm not going to specify any particular license. | |
*/ | |
function Spinner(element, options){ | |
this.context = element.getContext("2d"); | |
this.animating = false; | |
this.currentOffset = 0; | |
this.options = { | |
bars: 10, | |
center:{ | |
x:100, | |
y:100 | |
}, | |
innerRadius:10, | |
size:{ | |
width:3, | |
height:12 | |
}, | |
color:{ | |
red:0, | |
green:17, | |
blue:58 | |
} | |
}; | |
for(o in options){ | |
this.options[o] = options[o]; | |
} | |
} | |
Spinner.prototype.makeRGBA = function(){ | |
return "rgba(" + [].slice.call(arguments, 0).join(",") + ")"; | |
} | |
Spinner.prototype.drawBlock = function(bar){ | |
var color = this.options.color, | |
bars = this.options.bars, | |
size = this.options.size; | |
this.context.fillStyle = this.makeRGBA(color.red, color.green, color.blue, (bars+1-bar)/(bars+1)); | |
this.context.fillRect(-size.width/2, 0, size.width, size.height); | |
} | |
Spinner.prototype.calculateAngle = function(bar){ | |
return 2 * bar * Math.PI / this.options.bars; | |
} | |
Spinner.prototype.calculatePosition = function(bar){ | |
var angle = this.calculateAngle(bar); | |
var innerRadius = this.options.innerRadius; | |
return { | |
y: (innerRadius * Math.cos(-angle)), | |
x: (innerRadius * Math.sin(-angle)), | |
angle: angle | |
}; | |
} | |
Spinner.prototype.draw = function(offset) { | |
var context = this.context, | |
center = this.options.center, | |
bars = this.options.bars; | |
this.clearFrame(); | |
context.save(); | |
context.translate(center.x, center.y); | |
for(var i = 0; i<bars; i++){ | |
var bar = (offset+i) % bars, | |
pos = this.calculatePosition(bar); | |
context.save(); | |
context.translate(pos.x, pos.y); | |
context.rotate(pos.angle); | |
this.drawBlock(i); | |
context.restore(); | |
} | |
context.restore(); | |
} | |
Spinner.prototype.clearFrame = function(){ | |
var context = this.context; | |
context.clearRect(0, 0, context.canvas.clientWidth, context.canvas.clientHeight); | |
} | |
Spinner.prototype.nextAnimation = function(){ | |
if (!this.animating){ | |
return; | |
}; | |
this.currentOffset = (this.currentOffset + 1) % this.options.bars; | |
this.draw(this.currentOffset); | |
var self = this; | |
this.timer = window.setTimeout(function(){self.nextAnimation()}, 50); | |
} | |
Spinner.prototype.stop = function(){ | |
this.animating = false; | |
this.clearFrame(); | |
clearTimeout(this.timer); | |
} | |
Spinner.prototype.start = function(){ | |
this.animating = true; | |
this.nextAnimation(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment