(function () { var animation = (function () { // // Our animation module // var canvas, ctx, size, animating; window.requestAnimFrame = (function (){ // // requestAnim shim layer by Paul Irish // // http://paulirish.com/2011/requestanimationframe-for-smart-animating/ // return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(/* function */ callback, /* DOMElement */ element) { window.setTimeout(callback, 1000 / 60); }; }()); window.cancelRequestAnimFrame = (function () { // // cancelRequestAnim shim layer by Jerome Etienne // // http://notes.jetienne.com/2011/05/18/cancelRequestAnimFrame-for-paul-irish-requestAnimFrame.html // return window.cancelAnimationFrame || window.webkitCancelRequestAnimationFrame || window.mozCancelRequestAnimationFrame || window.oCancelRequestAnimationFrame || window.msCancelRequestAnimationFrame || clearTimeout }()); function init(options) { size = options.size || 256; canvas = document.createElement('canvas'); canvas.width = canvas.height = size; ctx = canvas.getContext('2d'); $('body').prepend(canvas); draw(0); return this; } function play(duration) { var start = (new Date).getTime(), finish = start + duration; if (animating) { // // Ensure the animation is not already being performed // return; } console && console.log("[%s] Let's animate while %sms!", start, duration); /* Old fashion way ----------------- animating = setInterval(function () { var time = (new Date).getTime(), pos = time > finish ? 1 : (time - start) / duration; // [0, 1] pos = ease(pos); draw(pos); if (time > finish) { console && console.log("[%s] That was fun!", finish); stop(); } }, 10);*/ (function animloop(time) { var pos = time > finish ? 1 : (time - start) / duration; // [0, 1] pos = ease(pos); draw(pos); animating = requestAnimFrame(animloop); if (time > finish) { console && console.log("[%s] That was fun!", finish); stop(); } }(start)); // Notice the start argument as first time value } function stop() { //clearInterval(animating); cancelRequestAnimFrame(animating); animating = null; draw(0); } function ease(pos) { // // Easing ('bounce' here for example) // // Notice easing just deal with // if (pos < (1 / 2.75)) { return (7.5625 * pos * pos); } else if (pos < (2 / 2.75)) { return (7.5625 * (pos -= (1.5 / 2.75)) * pos + .75); } else if (pos < (2.5 / 2.75)) { return (7.5625 * (pos -= (2.25 / 2.75)) * pos + .9375); } else { return (7.5625 * (pos -=(2.625 / 2.75)) * pos + .984375); } } function draw(pos) { // // Draw a red dot along a radius circle // // The function takes a position [0, 1] to // determine the dot position along the circle // var a = 10, r = size / 2 - a, teta = 2 * Math.PI * pos, // 2π * [0, 1] = [0, 2π] x = r * Math.cos(teta) + size / 2, y = r * Math.sin(teta) + size / 2; console && console.log(x, y); // Clean the board ctx.clearRect(0, 0, size, size); // Take your pencil and draw the shape (a red circle) ctx.fillStyle = 'rgb(255, 0, 0)'; ctx.beginPath(); ctx.arc(x, y, a, 0, 2 * Math.PI, true); ctx.closePath(); ctx.fill(); } // Public API return { init: init, play: play, stop: stop }; }()).init({ size: 100 }); (function () { // // Bind some module's actions on controls // $('#start').click(function (event) { event.preventDefault(); animation.play(+$('#duration').val()); }); $('#stop').click(function (event) { event.preventDefault(); animation.stop(); }); }()); }());