(function($){ /*---------------------------------------------------------------------------------- Class: FloatObject -------------------------------------------------------------------------------------*/ function FloatObject(jqObj, params) { this.jqObj = jqObj; switch(params.speed) { case 'fast': this.steps = 5; break; case 'normal': this.steps = 10; break; case 'slow': this.steps = 20; break; default: this.steps = 10; }; var offset = this.jqObj.offset(); this.currentX = offset.left; this.currentY = offset.top; this.width = this.jqObj.width(); this.height = this.jqObj.height(); this.alwaysVisible = params.alwaysVisible; this.alwaysTop = params.alwaysTop; this.origX = typeof(params.x) == "string" ? this.currentX : params.x; this.origY = typeof(params.y) == "string" ? this.currentY : params.y; //now we make sure the object is in absolute positions. this.jqObj.css({'position':'absolute' , 'top':this.currentY ,'left':this.currentX}); } FloatObject.prototype.updateLocation = function() { this.updatedX = $(window).scrollLeft() + this.origX; if( this.alwaysTop == false ){ this.updatedY = $(window).scrollTop()+ this.origY; if( this.alwaysVisible ){ if( this.origX + this.width > this.windowWidth() ) this.updatedX = this.windowWidth() - this.width + $(window).scrollLeft(); if( this.origY + this.height > this.windowHeight() ) { this.updatedY = $(window).scrollTop() + this.windowHeight() - this.height; if( this.updatedY < this.origY ) this.updatedY = this.origY; } } } else { if( $(window).scrollTop() > this.origY ) { this.updatedY = $(window).scrollTop() + 5; } else { this.updatedY = this.origY + 5; } } this.dx = Math.abs(this.updatedX - this.currentX ); this.dy = Math.abs(this.updatedY - this.currentY ); return this.dx || this.dy; } FloatObject.prototype.windowHeight = function() { var de = document.documentElement; return self.innerHeight || (de && de.clientHeight) || document.body.clientHeight; } FloatObject.prototype.windowWidth = function() { var de = document.documentElement; return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth; } FloatObject.prototype.move = function() { if( this.jqObj.css("position") != "absolute" ) return; var cx = 0; var cy = 0; if( this.dx > 0 ) { if( this.dx < this.steps / 2 ) cx = (this.dx >= 1) ? 1 : 0; else cx = Math.round(this.dx/this.steps); if( this.currentX < this.updatedX ) this.currentX += cx; else this.currentX -= cx; } if( this.dy > 0 ) { if( this.dy < this.steps / 2 ) cy = (this.dy >= 1) ? 1 : 0; else cy = Math.round(this.dy/this.steps); if( this.currentY < this.updatedY ) this.currentY += cy; else this.currentY -= cy; } this.jqObj.css({'left':this.currentX, 'top': this.currentY }); } /*---------------------------------------------------------------------------------- Object: floatMgr -------------------------------------------------------------------------------------*/ $.floatMgr = { FOArray: new Array() , timer: null , initializeFO: function(jqObj,params) { var settings = $.extend({ x: 0 , y: 0 , speed: 'normal' , alwaysVisible: false , alwaysTop: false},params||{}); var newFO = new FloatObject(jqObj,settings); $.floatMgr.FOArray.push(newFO); if( !$.floatMgr.timer ) $.floatMgr.adjustFO(); //now making sure we are registered to all required window events if( !$.floatMgr.registeredEvents ) { $(window).bind("resize", $.floatMgr.onChange); $(window).bind("scroll", $.floatMgr.onChange); $.floatMgr.registeredEvents = true; } } , adjustFO: function() { $.floatMgr.timer = null; var moveFO = false; for( var i = 0 ; i < $.floatMgr.FOArray.length ; i++ ) { FO = $.floatMgr.FOArray[i]; if( FO.updateLocation() ) moveFO = true; } if( moveFO ) { for( var i = 0 ; i < $.floatMgr.FOArray.length ; i++ ) { FO = $.floatMgr.FOArray[i]; FO.move(); } if( !$.floatMgr.timer ) $.floatMgr.timer = setTimeout($.floatMgr.adjustFO,50); } } , stopFloatChk: false , onChange: function() { if( !$.floatMgr.timer && !$.floatMgr.stopFloatChk ) $.floatMgr.adjustFO(); } }; /*---------------------------------------------------------------------------------- Function: makeFloat -------------------------------------------------------------------------------------*/ $.fn.makeFloat = function(params) { var obj = this.eq(0); //we only operate on the first selected object; $.floatMgr.initializeFO(obj,params); if( $.floatMgr.timer == null ) $.floatMgr.adjustFO(); return obj; }; $.fn.stopFloat = function(params) { $.floatMgr.stopFloatChk = true; }; $.fn.restartFloat = function(params) { $.floatMgr.stopFloatChk = false; }; })(jQuery);