JavaScript Tween function
This is a small library I wrote for creating simple and complicated easing effects without using JQuery, MooTools or other JS libraries.
The library is small 13.4 KB or 5.6 KB compressed,
The function can be called as follows:
tween(element, property, from, to, duration,[optional]function)
Parameters
element: The idĀ of the HTML element you want to animate likeĀ “my_div”, “left_sidebar”, DOM objects are also accepted
property: The CSS property that you want to animate like “color”, background-color”, “left”, “margin-top”…
from: The initial value, like 0px, top, none, 0.5…
to: The final value
duration: the animation duration in ms
function (optional): the easing function to use, by default the tween function uses the linear tween, there are nine other functions included (easeInBack, easeOutBack, easeInOutBack, easeInCirc, easeOutCirc, easeInOutCirc, easeInBounce, easeOutBounce & easeInOutBounce)
Examples
Minified version
Full version
var fps = 40; var debugging = 0; var tw = []; var rand_str = generatePassword(); var float_pcre = new RegExp("(\\+|-)?(\\d*\\.)?\\d+",'g'); var color_at_end = new RegExp("[Cc]olor$"); function tween(element, property, from, to, duration){ if (arguments.length < 5) return false; // Let's first remove old tweens from the tw table to gain performance if(Math.random()>=0.75){ for(var i=0; i<=tw[tw_id]["steps"] && tw[tw_id]["step"]!==0 && tw[tw_id]["status"] === 'playing'){ if(tw[tw_id]["is_color_tween"]){ var red = parseInt(eval(tw[tw_id]["f"])(tw[tw_id]["step"], parseInt(tw[tw_id]["from"]["red"]) , parseInt(tw[tw_id]["change"]["red"]) , tw[tw_id]["steps"])); var green = parseInt(eval(tw[tw_id]["f"])(tw[tw_id]["step"], parseInt(tw[tw_id]["from"]["green"]) , parseInt(tw[tw_id]["change"]["green"]) , tw[tw_id]["steps"])); var blue = parseInt(eval(tw[tw_id]["f"])(tw[tw_id]["step"], parseInt(tw[tw_id]["from"]["blue"]) , parseInt(tw[tw_id]["change"]["blue"]) , tw[tw_id]["steps"])); tw[tw_id]["ez"] = "rgb("+red+","+green+","+blue+")"; } else{ tw[tw_id]["ez"] = parseInt(eval(tw[tw_id]["f"])(tw[tw_id]["step"], tw[tw_id]["from"], tw[tw_id]["change"], tw[tw_id]["steps"])*100)/100; tw[tw_id]["ez"] = tw[tw_id]["prefix"]+ tw[tw_id]["ez"] + tw[tw_id]["suffix"]; } tw[tw_id]["timer"] = setTimeout("ease_repeat("+tw_id+")",tw[tw_id]["interval"]); } if(tw[tw_id]["step"]>=tw[tw_id]["steps"]){ tw[tw_id]["status"] = "complete"; } } function ease_repeat(tw_id){ try{ tw[tw_id]["element"].style[tw[tw_id]["property"]] = tw[tw_id]["ez"]; ease(tw_id); } catch(e){} } /* Keep it simple with these nice functions */ function h2d(h) { // hex to decimal return parseInt(h,16); } function str_replace (search, replace, subject, count) { // version: 908.406 // discuss at: http://phpjs.org/functions/str_replace var i = 0, j = 0, temp = '', repl = '', sl = 0, fl = 0, f = [].concat(search), r = [].concat(replace), s = subject, ra = r instanceof Array, sa = s instanceof Array; s = [].concat(s); if (count) this.window[count] = 0; for (i=0, sl=s.length; i < sl; i++) { if (s[i] === '') continue; for (j=0, fl=f.length; j < fl; j++) { temp = s[i]+''; repl = ra ? (r[j] !== undefined ? r[j] : '') : r[0]; s[i] = (temp).split(f[j]).join(repl); if (count && s[i] !== temp) { this.window[count] += (temp.length-s[i].length)/f[j].length;} } } return sa ? s : s[0]; } function resolve_element(element){ if(typeof(element) == "object") ; else if(typeof(element) == "string") element = document.getElementById(element); if(element.tagName != "undefined") return element; return false; } function resolve_property(property){ // resolve_property("-moz-border-radius") => "MozBorderRadius"; var matched; var dash_letter = new RegExp("-[a-z]"); while(1){ if(matched = property.match(dash_letter)){ matched = matched.toString(); property = str_replace(matched, matched.charAt(1).toUpperCase(), property); } else break; } return property; } function resolve_color(color){ // return an array containing R, G and B values if(color === 'transparent')// IE (6 and ?) color = '#FFF'; var r,g,b; var hex_color_pcre = new RegExp("^#[0-9a-f]{3}([0-9a-f]{3})?$",'gi'); var rgb_color_pcre = new RegExp("rgb\\(\\s*((?:[0-2]?[0-9])?[0-9])\\s*,\\s*((?:[0-2]?[0-9])?[0-9])\\s*,\\s*((?:[0-2]?[0-9])?[0-9])\\s*\\)$",'gi'); var rgb_percent_color_pcre = new RegExp("rgb\\(\\s*((?:[0-1]?[0-9])?[0-9])%\\s*,\\s*((?:[0-1]?[0-9])?[0-9])%\\s*,\\s*((?:[0-1]?[0-9])?[0-9])%\\s*\\)$",'gi'); if(color.match(hex_color_pcre)){ if(color.length == 4){ r = color.charAt(1)+""+color.charAt(1); g = color.charAt(2)+""+color.charAt(2); b = color.charAt(3)+""+color.charAt(3); } else{ r = color.charAt(1)+""+color.charAt(2); g = color.charAt(3)+""+color.charAt(4); b = color.charAt(5)+""+color.charAt(6); } r = h2d(r); g = h2d(g); b = h2d(b); } else if(color.match(rgb_color_pcre)){ r = RegExp.$1; g = RegExp.$2; b = RegExp.$3; } else if(color.match(rgb_percent_color_pcre)){ r = parseInt((RegExp.$1)*2.55); g = parseInt((RegExp.$2)*2.55); b = parseInt((RegExp.$3)*2.55); } else return false; var returned =[]; returned['red'] = r; returned['green'] = g; returned['blue'] = b; return returned; } function getStyle(oElm, strCssRule){ // http://robertnyman.com/2006/04/24/get-the-rendered-style-of-an-element/ var strValue = ""; if(document.defaultView && document.defaultView.getComputedStyle){ strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule); } else if(oElm.currentStyle){ strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){ return p1.toUpperCase(); }); strValue = oElm.currentStyle[strCssRule]; } return strValue; } function generatePassword(len){ // http://www.kadimi.com/en/javascript/random-password-string/ len = parseInt(len); if(!len) len = 6; var password = ""; var chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; var charsN = chars.length; var nextChar; for(i=0;i< 0) { f_start += f_string.length; } if (f_length == undefined) { f_length = f_string.length; } else if (f_length < 0){ f_length += f_string.length; } else { f_length += f_start; } if (f_length < f_start) { f_length = f_start; } return f_string.substring(f_start, f_length); } function microtime (get_as_float) { // Returns either a string or a float containing the current time in seconds and microseconds // discuss at: http://phpjs.org/functions/microtime // + original by: Paulo Ricardo F. Santos // * example 1: timeStamp = microtime(true); // * results 1: timeStamp > 1000000000 && timeStamp < 2000000000 var now = new Date().getTime() / 1000; var s = parseInt(now, 10); return (get_as_float) ? now : (Math.round((now - s) * 1000) / 1000) + ' ' + s; } // My favorite $() function $() { //http://v3.thewatchmakerproject.com/code/extended-dollar.txt var elements = new Array(); for (var i=0,len=arguments.length;i< 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b; return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b; }; //Circulat easeInCirc = function (t, b, c, d) { return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b; }; easeOutCirc = function (t, b, c, d) { return c * Math.sqrt(1 - (t=t/d-1)*t) + b; }; easeInOutCirc = function (t, b, c, d) { if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b; return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b; }; //Bounce easeInBounce = function (t, b, c, d) { return c - easeOutBounce (d-t, 0, c, d) + b; }; easeOutBounce = function (t, b, c, d) { if ((t/=d) < (1/2.75)) { return c*(7.5625*t*t) + b; } else if (t < (2/2.75)) { return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b; } else if (t < (2.5/2.75)) { return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b; } else { return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b; } }; easeInOutBounce = function (t, b, c, d) { if (t < d/2) return easeInBounce (t*2, 0, c, d) * .5 + b; return easeOutBounce (t*2-d, 0, c, d) * .5 + c*.5 + b; }; //*/
Feel free to contact me at any time, I accept support requests, just make sure your question is related to topics covered on this site.
Thanks Kadimi for sharing this tween() javascript function:
I have taken the original ‘minimized’ tween() js code and expanded it back to a human readable source. I have corrected some JSLint issues presented with code and additionally corrected two js ‘if conditionals’ that had no ‘TRUE’ state code to execute. I think this code you have created is educational in human readable code format:
>————————————-<
// Use: tween(element, property, from, to, duration, [optional] function)
// Where: element: ID of HTML element, property: CSS property for tween'ing, from: initial value, to: final value
var fps = 40;
var debugging = 0;
var tw = [];
[...] code removed by Nabil Kadimi
>-------------------------------------<
Peter Bowey
Thank you for your interest, this small library is a draft and I will put more effort on improving if I see that people like you are willing to support it by providing bug reports and feedback.
I posted the full version of the function and I will – in the near future – have a repository and a bug tracker.
Notes: The two (original) failed ‘if’ conditionals occur on the following code:
1) if (tw[f]["from_orig"] === ‘current’); // line 53
2) if (typeof(a) == “object”); // line 155
There is no ‘TRUE’ state code to execute after either of the above condtions. Note the semicolon; ending each condition
Peter Bowey
I wrote that on purpose, this doesn’t hurt but sure there is a better way to write it.
Actually I should have wrote a comment to remember me why I coded it that way… oops.
But the way, I forgot to tell you that I was very busy with my personal life, I apologize for not responding to your comments/requests earlier.