Created
April 11, 2014 19:45
-
-
Save mcordingley/10495884 to your computer and use it in GitHub Desktop.
setInterval, but with easing from one timer value to another
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(root) { | |
'use strict'; | |
// Mapping of returned interval handles to their current timeout handles | |
var intervals = {}, | |
easedIntervalCounter = 0; | |
var isNumeric = function(candidate) { | |
return (!isNaN(parseFloat(candidate)) && isFinite(candidate)); | |
}, | |
partial = function(callback) { | |
var args = Array.prototype.slice.call(arguments, 1); | |
return function() { | |
callback.apply(this, args.concat(arguments)); | |
}; | |
}, | |
// Current time through tween, start value of tween, change between beginning and end values, duration of tween | |
easeLinear = function (time, beginning, change, duration) { | |
return change * time / duration + beginning; | |
}, | |
setTimer = function(intervalInfo) { | |
var timeElapsed = new Date().getTime() - intervalInfo.started; | |
// If we're done easing, drop down to a simple setInterval | |
if (timeElapsed > intervalInfo.easeDuration) { | |
intervalInfo.completed = true; | |
intervalInfo.timeoutHandle = setInterval.apply(root, [intervalInfo.callback, intervalInfo.endInterval].concat(intervalInfo.arguments)); | |
} | |
// Otherwise, keep tweening | |
else { | |
var nextTime = intervalInfo.easeFunction(timeElapsed, intervalInfo.startInterval, intervalInfo.endInterval - intervalInfo.startInterval, intervalInfo.easeDuration); | |
// Update info and run the timer | |
intervalInfo.timeoutHandle = setTimeout(partial(nextInterval, intervalInfo), nextTime); | |
} | |
}, | |
nextInterval = function(intervalInfo) { | |
// Schedule next timer | |
setTimer(intervalInfo); | |
// Mimic setTimeout's behavior with `window` as `this` and addtional arguments passed to the callback | |
intervalInfo.callback.apply(root, intervalInfo.arguments); | |
}; | |
root.setEasedInterval = function(callback, options) { | |
var handle = ++easedIntervalCounter, | |
now = new Date().getTime(); | |
intervals[handle] = { | |
arguments: Array.prototype.slice.call(arguments, 2), | |
callback: callback, | |
easeDuration: options.easeDuration, | |
easeFunction: options.easeFunction || easeLinear, | |
started: now, | |
startInterval: options.startInterval, | |
endInterval: options.endInterval | |
}; | |
setTimer(intervals[handle]); | |
return handle; | |
}; | |
root.clearEasedInterval = function(handle) { | |
var intervalInfo = intervals[handle]; | |
if (intervalInfo.completed) { | |
clearInterval(intervals[handle].timeoutHandle); | |
} | |
else { | |
clearTimeout(intervals[handle].timeoutHandle); | |
} | |
delete intervals[handle]; | |
}; | |
})(this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
It's a native script, meant to run as-is.