Skip to content

Instantly share code, notes, and snippets.

@mcordingley
Created April 11, 2014 19:45
Show Gist options
  • Save mcordingley/10495884 to your computer and use it in GitHub Desktop.
Save mcordingley/10495884 to your computer and use it in GitHub Desktop.
setInterval, but with easing from one timer value to another
(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);
@mcordingley
Copy link
Author

It's a native script, meant to run as-is.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment