shake a DOM element
function shake(e, oncomplete, distance, time) {
// Handle arguments
if (typeof e === "string") e = document.getElementById(e);
if (!time) time = 500;
if (!distance) distance = 5;
var originalStyle = e.style.cssText; // Save the original style of e
e.style.position = "relative"; // Make e relatively positioned
var start = (new Date()).getTime(); // Note the animation start time
animate(); // Start the animation
// This function checks the elapsed time and updates the position of e.
// If the animation is complete, it restores e to its original state.
// Otherwise, it updates e's position and schedules itself to run again.
function animate() {
var now = (new Date()).getTime(); // Get current time
var elapsed = now-start; // How long since we started
var fraction = elapsed/time; // What fraction of total time?
if (fraction < 1) { // If the animation is not yet complete
// Compute the x position of e as a function of animation
// completion fraction. We use a sinusoidal function, and multiply
// the completion fraction by 4pi, so that it shakes back and
// forth twice.
var x = distance * Math.sin(fraction*4*Math.PI);
e.style.left = x + "px";
// Try to run again in 25ms or at the end of the total time.
// We're aiming for a smooth 40 frames/second animation.
setTimeout(animate, Math.min(25, time-elapsed));
}
else { // Otherwise, the animation is complete
e.style.cssText = originalStyle // Restore the original style
if (oncomplete) oncomplete(e); // Invoke completion callback
}
}
}