Last active
August 29, 2015 14:05
-
-
Save ianpgall/20c75181dd9b7db6aef8 to your computer and use it in GitHub Desktop.
JavaScript function that animates an element's style or property
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 animate(element, options) { | |
"use strict"; | |
/* | |
* Options: | |
* style - a numerical style property to animate | |
* property - a numerical property to animate | |
* endValue - the value to animate to | |
* unit - (optional) the value's units; defaults to "" | |
* duration - (optional) how long, in milliseconds, for the animation to complete; defaults to 400 | |
* complete - (optional) a function to call when the animation completes | |
*/ | |
var style, property, | |
startValue, endValue, unit, | |
duration, completeCallback, | |
getProgress, getNextValue, | |
valueChanger, iterator, | |
startTime; | |
// Make sure the element is provided | |
if (!element) { | |
throw new ReferenceError("element is not defined"); | |
} | |
style = options.style; | |
property = options.property; | |
// Make sure the style OR property is provided | |
if (!style && !property) { | |
throw new TypeError("style/property is invalid"); | |
} | |
// Make sure the endValue is provided | |
if (options.endValue === null || options.endValue === undefined) { | |
throw new TypeError("endValue is invalid"); | |
} | |
// Set the startValue based on the element's current style/property | |
if (style) { | |
startValue = parseFloat(getComputedStyle(element)[style]); | |
} else if (property) { | |
startValue = parseFloat(element[property]); | |
} | |
endValue = parseFloat(options.endValue); | |
unit = "" + (options.unit || ""); | |
duration = +options.duration || 400; | |
completeCallback = options.complete; | |
// Determines the progress of the animation (from 0 to 1) | |
getProgress = function () { | |
return Math.min(1, (new Date().getTime() - startTime) / duration); | |
}; | |
// Determines the next value to set for the style/property | |
getNextValue = (function () { | |
var valueDifference = (endValue - startValue); | |
return function (progress) { | |
return (startValue + (progress * (valueDifference))) + unit; | |
}; | |
}()); | |
// Set the function that changes the value on each animation step | |
if (style) { | |
valueChanger = function (nextValue) { | |
element.style[style] = nextValue; | |
}; | |
} else if (property) { | |
valueChanger = function (nextValue) { | |
element[property] = nextValue; | |
}; | |
} | |
// Main animation logic | |
iterator = function () { | |
var progress, nextValue; | |
// Set next value | |
progress = getProgress(); | |
nextValue = getNextValue(progress); | |
valueChanger(nextValue); | |
// Check if animation is done | |
if (progress === 1) { | |
// Check if callback for completion is provided | |
if (completeCallback) { | |
completeCallback(); | |
} | |
return; | |
} | |
// Continue animation if not done | |
setTimeout(iterator, 15); | |
}; | |
// Start animating | |
startTime = new Date().getTime(); | |
iterator(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment