181 lines
5.1 KiB
JavaScript
181 lines
5.1 KiB
JavaScript
/**
|
|
* jQuery Canvas Loader Plugin 1.3
|
|
*
|
|
* Creates an alternative to ajax loader images with the canvas element.
|
|
*
|
|
* Tested on Mobile Safari and Android browsers.
|
|
*
|
|
* By Jamund Xcot Ferguson
|
|
*
|
|
* Twitter: @xjamundx
|
|
* Blog: http://www.jamund.com/
|
|
*
|
|
* Usage:
|
|
*
|
|
* Without options:
|
|
*
|
|
* $("img.ajaxLoader").canvasLoader();
|
|
*
|
|
* With options:
|
|
*
|
|
* $("img.ajaxLoader").canvasLoader({
|
|
* 'radius':10,
|
|
* 'color':'rgb(255,0,0),
|
|
* 'dotRadius':10,
|
|
* 'backgroundColor':'transparent'
|
|
* 'className':'canvasLoader',
|
|
* 'id':'canvasLoader1',
|
|
* 'fps':10
|
|
* });
|
|
*
|
|
* Options:
|
|
*
|
|
* radius - width/height of the loader
|
|
* color - color of the pulsing dots
|
|
* dotRadius - radius of the pulsing dots
|
|
* className - class name of the canvas tag
|
|
* backgroundColor - a background color for the canvas
|
|
* id - id of the canvas tag
|
|
* fps - approximate frames per second of the pulsing
|
|
*
|
|
**/
|
|
|
|
(function($){
|
|
/**
|
|
* Replaces loading images with a canvas alternative
|
|
*
|
|
* @author Jamund Xcot Ferguson
|
|
*/
|
|
$.fn.canvasLoader = function(options) {
|
|
|
|
// holds my canvas loader object
|
|
var loaders = [];
|
|
|
|
// holds my defaults object
|
|
var globalDefaults = {
|
|
'radius':20,
|
|
'color':'rgb(0,0,0)',
|
|
'dotRadius':2.5,
|
|
'backgroundColor':'transparent',
|
|
'className':'canvasLoader',
|
|
'id':'canvasLoader1',
|
|
'fps':10
|
|
};
|
|
|
|
// holds the generic settings objects
|
|
var globalOpts = $.extend(globalDefaults, options);
|
|
|
|
// start drawing right away
|
|
setInterval(draw, 1000/globalOpts.fps);
|
|
|
|
// the main drawing function
|
|
function draw() {
|
|
for (i in loaders) {
|
|
loaders[i].draw();
|
|
}
|
|
}
|
|
|
|
var CanvasLoader = function(ctx, radius, color, dotRadius) {
|
|
this.ctx = ctx;
|
|
this.radius = radius;
|
|
this.x = this.radius/2;
|
|
this.y = this.radius/2;
|
|
this.color = color;
|
|
this.dotRadius = dotRadius;
|
|
this.opacity = 1;
|
|
this.numDots = 8;
|
|
this.dots = {};
|
|
this.degrees = Math.PI*2/this.numDots;
|
|
for (i=1;i<=this.numDots;i++) {
|
|
this.dots[i] = new Dot(Math.cos(this.degrees * i) * this.radius/Math.PI, Math.sin(this.degrees * i) * this.radius/Math.PI, this.dotRadius, this.color, i/this.numDots);
|
|
this.dots[i].parent = this;
|
|
}
|
|
}
|
|
|
|
CanvasLoader.prototype.draw = function() {
|
|
// clear old stuff
|
|
this.ctx.clearRect(0,0,this.radius,this.radius);
|
|
|
|
// draw the background color
|
|
this.ctx.globalAlpha = 1;
|
|
this.ctx.fillStyle = globalOpts.backgroundColor;
|
|
this.ctx.fillRect(0,0,this.radius,this.radius);
|
|
|
|
// fill in the dots
|
|
for (i in this.dots) {
|
|
this.dots[i].changeOpacity();
|
|
this.dots[i].draw();
|
|
}
|
|
}
|
|
|
|
var Dot = function(x, y, radius, color, opacity) {
|
|
this.radius = radius;
|
|
this.color = color;
|
|
this.opacity = opacity;
|
|
this.x = x;
|
|
this.y = y;
|
|
}
|
|
|
|
Dot.prototype.draw = function() {
|
|
this.parent.ctx.beginPath();
|
|
this.parent.ctx.globalAlpha = this.opacity;
|
|
this.parent.ctx.fillStyle = this.color;
|
|
this.parent.ctx.arc(this.x+(this.parent.radius/2), this.y+(this.parent.radius/2), this.radius, 0, Math.PI*2, true);
|
|
this.parent.ctx.fill();
|
|
}
|
|
|
|
Dot.prototype.changeOpacity = function() {
|
|
this.opacity -= 1/this.parent.numDots;
|
|
if (this.opacity < 0) this.opacity = 1;
|
|
}
|
|
|
|
// we can't replace until the image is loaded (webkit bug?)
|
|
return $(this).each(function() {
|
|
if (this.tagName == 'IMG') {
|
|
$(this).load(function() {
|
|
// set some local defaults that change
|
|
var localDefaults = {
|
|
'radius':($(this).width()+$(this).height())/2,
|
|
'dotRadius':($(this).width()+$(this).height())/16,
|
|
'id':'canvasLoader'+(parseInt($(".canvasLoader").size())+1),
|
|
};
|
|
|
|
// extend the global defaults with the local defaults and then the user-supplied defaults.
|
|
var opts = $.extend(globalOpts, localDefaults, options);
|
|
|
|
// create a canvas object and get the context
|
|
var canvas = $("<canvas width='"+opts.radius+"' height='"+opts.radius+"' id='"+opts.id+"' class='"+opts.className+"'></canvas>");
|
|
var ctx = canvas.get(0).getContext("2d");
|
|
|
|
// simple feature detection, needs work
|
|
if (!!ctx) {
|
|
loaders[loaders.length+1] = new CanvasLoader(ctx, opts.radius, opts.color, opts.dotRadius);
|
|
$(this).replaceWith(canvas);
|
|
}
|
|
});
|
|
} else {
|
|
// set some local defaults that change
|
|
var localDefaults = {
|
|
'radius':($(this).width()+$(this).height())/2,
|
|
'dotRadius':($(this).width()+$(this).height())/16,
|
|
'id':'canvasLoader'+(parseInt($("."+globalOpts.className).size())+1),
|
|
};
|
|
|
|
// extend the global defaults with the local defaults and then the user-supplied defaults.
|
|
var opts = $.extend(globalOpts, localDefaults, options);
|
|
|
|
// create a canvas object and get the context
|
|
var canvas = $("<canvas width='"+opts.radius+"' height='"+opts.radius+"' id='"+opts.id+"' class='"+opts.className+"'></canvas>");
|
|
var ctx = canvas.get(0).getContext("2d");
|
|
|
|
// simple feature detection, needs work
|
|
if (!!ctx) {
|
|
loaders[loaders.length+1] = new CanvasLoader(ctx, opts.radius, opts.color, opts.dotRadius);
|
|
$(this).replaceWith(canvas);
|
|
}
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
})(jQuery); |