122 lines
3.4 KiB
JavaScript
122 lines
3.4 KiB
JavaScript
/*! Overthrow. An overflow:auto polyfill for responsive design. (c) 2012: Scott Jehl, Filament Group, Inc. http://filamentgroup.github.com/Overthrow/license.txt */
|
|
(function( w, o, undefined ){
|
|
|
|
// o is overthrow reference from overthrow-polyfill.js
|
|
if( o === undefined ){
|
|
return;
|
|
}
|
|
|
|
// Easing can use any of Robert Penner's equations (http://www.robertpenner.com/easing_terms_of_use.html). By default, overthrow includes ease-out-cubic
|
|
// arguments: t = current iteration, b = initial value, c = end value, d = total iterations
|
|
// use w.overthrow.easing to provide a custom function externally, or pass an easing function as a callback to the toss method
|
|
o.easing = function (t, b, c, d) {
|
|
return c*((t=t/d-1)*t*t + 1) + b;
|
|
};
|
|
|
|
// tossing property is true during a programatic scroll
|
|
o.tossing = false;
|
|
|
|
// Keeper of intervals
|
|
var timeKeeper;
|
|
|
|
/* toss scrolls and element with easing
|
|
|
|
// elem is the element to scroll
|
|
// options hash:
|
|
* left is the desired horizontal scroll. Default is "+0". For relative distances, pass a string with "+" or "-" in front.
|
|
* top is the desired vertical scroll. Default is "+0". For relative distances, pass a string with "+" or "-" in front.
|
|
* duration is the number of milliseconds the throw will take. Default is 100.
|
|
* easing is an optional custom easing function. Default is w.overthrow.easing. Must follow the easing function signature
|
|
|
|
*/
|
|
o.toss = function( elem, options ){
|
|
o.intercept();
|
|
var i = 0,
|
|
sLeft = elem.scrollLeft,
|
|
sTop = elem.scrollTop,
|
|
// Toss defaults
|
|
op = {
|
|
top: "+0",
|
|
left: "+0",
|
|
duration: 50,
|
|
easing: o.easing,
|
|
finished: function() {}
|
|
},
|
|
endLeft, endTop, finished = false;
|
|
|
|
// Mixin based on predefined defaults
|
|
if( options ){
|
|
for( var j in op ){
|
|
if( options[ j ] !== undefined ){
|
|
op[ j ] = options[ j ];
|
|
}
|
|
}
|
|
}
|
|
|
|
// Convert relative values to ints
|
|
// First the left val
|
|
if( typeof op.left === "string" ){
|
|
op.left = parseFloat( op.left );
|
|
endLeft = op.left + sLeft;
|
|
}
|
|
else {
|
|
endLeft = op.left;
|
|
op.left = op.left - sLeft;
|
|
}
|
|
// Then the top val
|
|
if( typeof op.top === "string" ){
|
|
|
|
op.top = parseFloat( op.top );
|
|
endTop = op.top + sTop;
|
|
}
|
|
else {
|
|
endTop = op.top;
|
|
op.top = op.top - sTop;
|
|
}
|
|
|
|
o.tossing = true;
|
|
timeKeeper = setInterval(function(){
|
|
if( i++ < op.duration ){
|
|
elem.scrollLeft = op.easing( i, sLeft, op.left, op.duration );
|
|
elem.scrollTop = op.easing( i, sTop, op.top, op.duration );
|
|
}
|
|
else{
|
|
if( endLeft !== elem.scrollLeft ){
|
|
elem.scrollLeft = endLeft;
|
|
} else {
|
|
// if the end of the vertical scrolling has taken place
|
|
// we know that we're done here call the callback
|
|
// otherwise signal that horizontal scrolling is complete
|
|
if( finished ) {
|
|
op.finished();
|
|
}
|
|
finished = true;
|
|
}
|
|
|
|
if( endTop !== elem.scrollTop ){
|
|
elem.scrollTop = endTop;
|
|
} else {
|
|
// if the end of the horizontal scrolling has taken place
|
|
// we know that we're done here call the callback
|
|
if( finished ) {
|
|
op.finished();
|
|
}
|
|
finished = true;
|
|
}
|
|
|
|
o.intercept();
|
|
}
|
|
}, 1 );
|
|
|
|
// Return the values, post-mixin, with end values specified
|
|
return { top: endTop, left: endLeft, duration: o.duration, easing: o.easing };
|
|
};
|
|
|
|
// Intercept any throw in progress
|
|
o.intercept = function(){
|
|
clearInterval( timeKeeper );
|
|
o.tossing = false;
|
|
};
|
|
|
|
})( this, this.overthrow );
|