// bouncydiv.js - v 1.0
2//
3// by Dejapong L. Suwaratana
4// www.dejapong.com
5// released 3/21/2009
6//
7// This script makes a div scroll down with the screen. Its most useful for
8// advertising blocks that you want to always be in front of the user. To use
9// this script, set the variable 'scrollerId' to the id of the div you want to
10// be bouncy. Remember to also set the div's style position to
11// "position:relative;" as this will allow the div to move. Then simply add the
12// javascript file to your webpage.
13//
14// Feel free to use this as you see fit. Credit would be appreciated or at least
15// just a link to dejapong.com if you can find it in your heart to do so.
16//
17// Have fun.
var bouncyTime = 2 //seconds - depends on computer some slower computer will take longer
var stickyness = 4; //if we are using the easy method, this restricts bouncyness
var useRealDHO = false //use realistic dynamic harmonic oscillations. This can be slower.
//these variables are used with realistic DHO. this is overkill for most webapps.
var mass = 1; //mass of object affects momentum
var dampingConst =3; //think of this as friction
var frequency = 3; //cycles per second
var scrollerId = 'advertblock' //id of the div to scroll
var offset = 310; //keep at least this far from the top
var waitTime = '600' //Time to wait before starting animation (milliseconds)
var startPoint;
var endPoint;
var intval
var timeout
var t = 0;

//helper function
function byId(id){
return document.getElementById(id);
}

//trim 'px' helper function
function trimPx(strg){
strip=/[px,pt,em]/gi;
strg?null:strg="0px";
strg.replace(strip,'');
return parseInt(strg);
}

//kick off our animation
function init(){
//if we have an animation already in progress, cancel it
(intval?window.clearInterval(intval):null)
//reset our time to zero
t = 0;
//get the starting point by finding the top of our div
startPoint = trimPx(byId(scrollerId).style.top);
endPoint = f_scrollTop()+(offset/2);
intval = window.setInterval("oscillate()",10);
}

function oscillate(){
//if we are at the end of our time //then stop the animation//else, increment the time for our equation
(t == 1000?window.clearInterval(intval):t += 10/bouncyTime)
//scale it for our equation
ts = t/100;
//if we are using real Damped harmonic oscillation
if (useRealDHO){
od = dampingConst/(2*mass);
oprime = Math.sqrt(frequency*frequency - od*od);
moveto = (startPoint-endPoint) * Math.pow(Math.E,-ts*od) * Math.cos(2*Math.PI+(ts*oprime)) + endPoint ;
}else{
//else, do the quick method
moveto = (startPoint-endPoint) * Math.pow(Math.E,-ts) * Math.cos(2*Math.PI*(ts/stickyness)) + endPoint;
}
//keep it from going up too far
moveto < 0 ? moveto = 0 : null;
byId(scrollerId).style.top = Math.round(moveto) + "px";
}

 //return the location of the scroll in any browser
function f_scrollTop() {
return f_filterResults (
window.pageYOffset ? window.pageYOffset : 0,
document.documentElement ? document.documentElement.scrollTop : 0,
document.body ? document.body.scrollTop : 0
);
}

//helper function to return scroll location
function f_filterResults(n_win, n_docel, n_body) {
var n_result = n_win ? n_win : 0;
if (n_docel && (!n_result || (n_result > n_docel)))
n_result = n_docel;
return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
 }

 //whenever the scrolling happens, wait half a second and kick start our animation
 window.onscroll = function(evt){
//if the offset is not set, then set it
offset ? null : offset = document.getElementById(scrollerId).offsetTop * -1 + 30;
(timeout?window.clearTimeout(timeout):null);
timeout = window.setTimeout("init()",waitTime);
};

// window.onload += function(evt){
function startBounce(){
//if the offset is not set, then set it
offset ? null : offset = document.getElementById(scrollerId).offsetTop * -1 +30;
(timeout?window.clearTimeout(timeout):null);
timeout = window.setTimeout("init()",waitTime);
}; 
