Files
2024-12-17 17:34:10 +01:00

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 );