/** * 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 = $(""); 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 = $(""); 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);