// // Twease 1.01 - AS2 tweening engine and sequencer // // Copyright (c) 2007 Andrew Fitzgerald - MIT License // Creation: 07/07/07 // Author: Andrew Fitzgerald // Homepage: http://play.visualcondition.com/twease/ // class com.visualcondition.twease.Twease { static var version:Number = 1.01; static var updatedepth:Number = 9876543; static var active:Boolean; static var roundresults:Boolean = false; static var tweens:Object = {}; static var activetweens:Object = {}; static var queue:Array = []; static var collectionrate:Number = 2048; static var gcid:Number; static function setActive(setactive:Boolean, target:Object, prop:String):Void { var ust:Function = function(apro:Array){ apro[0].starttime = getTimer()-(apro[0].lasttime-apro[0].starttime); } if(prop == undefined){ if(setactive) for ( var i in tweens[target] ) if(tweens[target][i].active) ust(tweens[target][i]); tweens[target].active = setactive; } else { if(setactive && !tweens[target][prop].active) ust(tweens[target][prop]); tweens[target][prop].active = setactive; } activetweens = {}; for ( var j in tweens ) { if(tweens[j].active) { activetweens[j] = {}; for ( var i in tweens[j] ) if(tweens[j][i].active && i != 'active' && i != 'propcount') activetweens[j][i] = true; } } if(target == undefined){ if(setactive){ if(setactive) for ( var j in tweens ) for ( var i in tweens[j] ) if(tweens[j][i].active) ust(tweens[j][i]); _root.createEmptyMovieClip("updater", updatedepth).onEnterFrame = update; gcid = setInterval(Twease.garbagecollect, collectionrate); } else { delete _root.updater.onEnterFrame; _root.updater.removeMovieClip(); clearInterval(gcid); } active = setactive; } }; static function garbagecollect():Void { var tc:Number = 0; for ( var i in tweens ){ tc++; if(tweens[i].propcount == 0) {delete tweens[i]; delete activetweens[i]}; }; if(tc == 0) setActive(null); } static function advance(id:Number, position:Number):Number { var np:Number = queue[id].position = (position == undefined) ? ++queue[id].position : position; if(queue[id].length-1 < np) queue[id] = []; if(queue[id].length == 0){ for ( var i in queue ) if(queue[i].length != 0) return null; queue = []; } else { var o:Object = {}; for ( var r in queue[id][np]){ o[r] = queue[id][np][r]; }; if(queue[id].target != undefined) { var oc:Number = 0; for ( var l in o ) oc++; if(o.func != undefined && o.target == undefined && oc <= 2){} else o.target = queue[id].target; } o.queue = [id, np]; tween(o); } return id; }; static function none(t:Number, b:Number, c:Number, d:Number):Number { return c*t/d+b; } static function easeIn(t:Number, b:Number, c:Number, d:Number):Number { return c*(t /= d)*t*t*t*t+b; } static function easeOut(t:Number, b:Number, c:Number, d:Number):Number { return c*((t=t/d-1)*t*t*t*t+1)+b; } static function update():Void { for (var i in activetweens){ for (var j in activetweens[i]){ var o:Object = tweens[i][j][0]; if(tweens[i][j].length > 0){ var gtt:Number = getTimer(); var tmr:Number = gtt-o.starttime; if(tmr >= (o.time+o.delay)) { o.target[o.prop] = (o.round) ? Math.round(o.newval) : o.newval; if(o.cycles != undefined) o.cycles--; if(o.func != undefined) o.func(o.target, o.prop, o.queue[0]); if(o.cycles == undefined || o.cycles == 0){ tweens[i][j].shift(); if(o.queue != undefined && queue[o.queue[0]].position == o.queue[1]) advance(o.queue[0], o.queue[1]+1); } var ocyc:Number = o.cycles; o = tweens[i][j][0]; if(o != undefined){ if(o.oldelay != 0 && o.oldelay != undefined) o.delay = o.oldelay; o.value = (ocyc != 0) ? (typeof(o.value) == 'string') ? String(-1*o.value) : o.startpos : o.value; o.starttime = gtt; o.startpos = o.target[o.prop]; o.newval = (typeof(o.value) == 'string') ? o.startpos + Number(o.value) : o.value; o.dif = (o.startpos > o.newval) ? -1*Math.abs(o.target[o.prop]-o.newval) : Math.abs(o.target[o.prop]-o.newval); } } else { if(o.delay == 0){ if(o.startfunc != undefined){ o.startfunc(o.target, o.prop, o.queue[0]); delete o.startfunc; } var res:Number = o.ease(tmr, o.startpos, o.dif, o.time); o.target[o.prop] = (o.round) ? Math.round(res) : res; if(o.upfunc != undefined) o.upfunc(o.target, o.prop, o.queue[0]); } else { if(gtt >= o.starttime+o.delay){ o.oldelay = o.delay; o.delay = 0; o.starttime = gtt; } } o.lasttime = gtt; } } else { delete tweens[i][j]; delete activetweens[i][j]; tweens[i].propcount--; } } } }; static function tween(ao:Object, target:Object):Object { if(ao[0] != undefined){ if(queue == undefined) queue = []; var nqp:Number = queue.push(ao)-1; queue[nqp].target = target; return advance(nqp, 0); } else { if(active == undefined || active == null) setActive(true); var delay:Number = (ao.delay == undefined) ? 0 : ao.delay*1000; var tarr:Array; if(ao.func != undefined && ao.target == undefined){ var tg:Object = (tweens.functions == undefined) ? tweens.functions = {propcount:0} : tweens.functions; if(tg.active == undefined){ tg.active = true; activetweens.functions = {}; } var prop:String = "func" + (Math.round(Math.random()*100000)).toString(); tarr = (tg[prop] == undefined) ? tg[prop] = [] : tg[prop]; if(tarr.active == undefined){ tarr.active = true; activetweens.functions[prop] = true; } tg.propcount++; tarr.push({prop:prop, starttime:getTimer(), func:ao.func, delay:delay, queue:ao.queue}); } else { target = ao.target; var time:Number = (ao.time == undefined) ? 0 : ao.time*1000; var ease:Function = (ao.ease == undefined) ? none : ao.ease; var func:Function = ao.func; var startfunc:Function = ao.startfunc; var upfunc:Function = ao.upfunc; var round:Boolean = (ao.round == undefined) ? roundresults : ao.round; var cycles:Number = (ao.cycles == undefined) ? 1 : ao.cycles; var queuen:Array = ao.queue; for ( var p in ao ) if(p == 'target' || p == 'time' || p == 'ease' || p == 'delay' || p == 'func' || p == 'startfunc' || p == 'upfunc' || p == 'round' || p == 'queue' || p == 'cycles') delete ao[p]; if(tweens == undefined) tweens = {}; var tg:Object = (tweens[target] == undefined) ? tweens[target] = {propcount:0} : tweens[target]; if(tg.active == undefined){ tg.active = true; activetweens[target] = {}; } for ( var i in ao ){ var prop:String = i; var value = ao[i]; if(isNaN(value)) continue; tarr = (tg[prop] == undefined) ? tg[prop] = [] : tg[prop]; if(tarr.active == undefined) { tarr.active = true; activetweens[target][prop] = true; tg.propcount++; } var ftv:Number = tarr[tarr.length-1].startpos; ftv = (ftv == undefined) ? target[prop] : ftv; var newval:Number = (typeof(value) == 'string') ? ftv + Number(value) : value; var dif:Number = (ftv > newval) ? -1*Math.abs(ftv-newval) : Math.abs(ftv-newval); tarr.push({target:target, cycles:cycles, prop:prop, ease:ease, starttime:getTimer()+1, queue:queuen, startpos:target[prop], value:value, dif:dif, newval:newval, time:time, func:func, startfunc:startfunc, upfunc:upfunc, round:round, delay:delay}); }; } return tarr; } } static function getTweens(target:Object, active:Boolean):Array { var a:Array = []; for ( var i in tweens[target] ) { if(i != 'active' && i != 'propcount'){ if(active) if(tweens[target][i].active) a.push(i); else a.push(i); } } return a; }; }