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