actionscript-video-com-mosesSupposes-fuse-FuseItem.ax [swf] flex
* The Fuse Kit [beta1.1z3] * Copyright (c) 2006 Moses Gunesch, MosesSupposes.com * * Distributed under MIT Open Source License, see Fuse-Kit-License.html (in fuse package directory) * Easing Equations (c) 2003 Robert Penner used by permission, see PennerEasing * Visit http://www.mosessupposes.com/Fuse * * @ignore * * Pass this class to {gray com.mosesSupposes.fuse.ZigoEngine#register} or {gray com.mosesSupposes.fuse.ZigoEngine#simpleSetup} to enable Fuse-style Object Syntax parsing capability with {gray com.mosesSupposes.fuse.ZigoEngine#doTween}. Note that registering Fuse is not required to use this feature. * @usage * <pre>ZigoEngine.doTween({ target:clip1, scale:200, ease:Strong.easeIn, time:"00:50", startAt:"01:50" });</pre> * <br><i>Most methods and properties are excluded here - see class file for further documentation.</i> * @author Moses Gunesch / MosesSupposes.com * @version 2.0
* @exclude * Unique identifier used by ZigoEngine.register
* When true, known tween properties may omit underscores (x will convert to _x, etc.)
* @exclude * @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem's current index in the engine's array stack. index is 0-based like an Array. Can be set externally at any time by parent Fuse if items are spliced or reordered.
* @exclude * An internal reference to the ZigoEngine class. Fuse + @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem may be used without ZigoEngine so an import statement is not used to avoid unecessary filesize when the engine is not needed.
* @exclude * Original action object or array passed by user
* @exclude * Unique ID of the @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem's parent Fuse instance.
* @exclude * Private internal play-state value, usually toggling from -1 to 1; 0 is a special flag used during the addTweens cycle.
* @exclude * Internal memory flag indicating start properties have been preset during current play cycle.
* @exclude * Internal flag indicating whether the @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem has triggered advance due to a trigger:true value in a profile.
* @exclude * Internal array queue that is progressively deleted upon tween completion to track @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem completion. (Public for access by Fuse.getActiveTargets)
* @exclude * Storage tank for @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem elements that are not handled by tweens: command, label, aEvents, and delay if no tweens found. (Public for access by Fuse.currentLabel, Fuse.skipTo)
* @exclude * Internal storage array of parsed action objects, meaning any object with tweenable elements or elements where tweening may or may not occur.
* @exclude * Verbose string listing the general contents of the @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem, viewable by calling traceItems on the parent Fuse instance.
* @exclude * An internal collection tank for variables used across multiple parseProfile calls as the @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem is being instantiated. Deleted when constructor is finished.
* @exclude * An internal collection of @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem instances generated when Fuse Object Syntax is used with <code>ZigoEngine.doTween</code>. These otherwise untracked instances are given an ID of -1 and are auto-deleted by the @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem class upon completion using <code>removeInstance</code>.
* This method needn't be called as method call is rerouted here automatically upon <code>ZigoEngine.doTween</code>. * @return comma-delimited string listing properties successfully added to the engine.
* @exclude * label property queried by Fuse * @return label string if @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem contains a label property
* @exclude * Fuse needs to retrieve original objects passed for Array methods that return them * @return true if trigger has been fired within currently playing item
* @exclude * Fuse needs to retrieve original objects passed for Array methods that return them * @return original action object as passed by user
* @exclude * Fuse calls this to get additional playing or paused targets to add to defaults when getActiveTargets is called on a Fuse. * @return a list of target objects or empty array
* @exclude
* @exclude * Called by parent Fuse to retrieve simple freestanding delays (note that in certain cases @files use ZigoEngine tweens to time complex delays, such as those that appear within an action group). Such non-tweened delays are centralized into the parent Fuse, which runs a setInterval timer and handles pause/resume behavior for that delay. *
parameter: scope current default scope set in parent Fuse instance * @return delay in seconds */ public function evalDelay(scope:Object):Number { var d:Object = _oElements.delay; if (d instanceof Function) { d = d.apply((_oElements.delayscope!=undefined) ? _oElements.delayscope : scope); } if (typeof d=='string') d = (parseClock(String(d))); if (_global.isNaN(Number(d))==true) return 0; return Number(d); } /** * @exclude * Called by parent Fuse to play the @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem, including triggering commands, firing callbacks not associated with tweens, and starting tweens. * @param targs - an array of default targets currently set in parent Fuse instance * @param scope - current default scope set in parent Fuse instance * @return returns successfully tweened props for doTween() */ public function startItem(targs:Array, scope:Object):String { _ZigoEngine = _global.com.mosesSupposes.fuse.ZigoEngine; var fuse:Object = _global.com.mosesSupposes.fuse.Fuse; var outputLevel:Number = (fuse!=undefined) ? fuse.OUTPUT_LEVEL : _ZigoEngine.OUTPUT_LEVEL; // Fuse command like 'pause' or 'stop'. v2.0: Only delay,scope,args are retained for items containing command. if (_oElements.command!=null) { var validCommands:String = '|start|stop|pause|resume|skipTo|setStartProps|'; var cs:Object = (_oElements.scope || scope); // profile scope used for eval only. command always sent to parent fuse var command:String = (_oElements.command instanceof Function) ? String(_oElements.command.apply(cs)) : String(_oElements.command); // user can pass a Delegate to scope this // IMPORTANT: args param is not used during eval, args are passed to Fuse, primarily for use with skipTo(index/label) var args:Array = (_oElements.args instanceof Function) ? _oElements.args.apply(cs) : _oElements.args; if (validCommands.indexOf('|'+command+'|')==-1 || (command=='skipTo' && args==undefined)) { if (outputLevel>0) FuseKitCommon.error('111', command); } else { _nPlaying = 1; if (!(args instanceof Array)) args = (args==null) ? [] : [args]; dispatchRequest(String(command), args); } return null; } // Changed order to deal with skipLevel. Now we tween first then fire callbacks and events. if (_aTweens.length>0) this.stop(); _ZigoEngine.addListener(this); // For monitoring targets that go missing. Only one corresponding remove, in stop(), which is called by complete(). _nPlaying = 2; // Special flag meaning doTweens is running, important for avoiding onTweenInterrupt/End conflicts. var propsAdded:String = null; if (_aProfiles.length>0) { if (_ZigoEngine==undefined) { FuseKitCommon.error('112'); } else { propsAdded = doTweens(targs, scope, false); } } // do not move. Callbacks can contain pause or other play commands, so this is checked afterward _nPlaying = 1; // Non-tween callbacks & events (skipped if skipLevel is 2 and all tweens failed) var fa:Array = _oElements.aEvents; for (var i:String in fa) { if (propsAdded==null && _aTweens.length>0 && (fa[i]).skipLevel==2) continue; fireEvents(fa[i],scope,outputLevel); } if (propsAdded==null && !(_aTweens.length>0) && _nPlaying==1) { if (outputLevel==3) FuseKitCommon.output('-'+(_sID())+' no tweens added - item done. [getTimer()='+getTimer()+']'); complete(); } return propsAdded; } /** * @exclude * Called by parent Fuse to stop the @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem's tweens. If currently playing, the internal method onStop is called which clears current tween list and associated listeners. */ public function stop():Void { // (for onTweenInterrupt) var doOnStop:Boolean = (_nPlaying>-1); _nPlaying = -1; // active stop: clear this item's tweens and remove listeners if (doOnStop==true) onStop(); _ZigoEngine.removeListener(this); } // -- private -- /** * @exclude */ private static function removeInstance(id:Number):Void { @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem(_aInstances[id]).destroy(); delete _aInstances[id]; } /** * @exclude * Clears active elements. (Fuse event reverse-subscribed by parent Fuse) */ private function onStop():Void { _bStartSet = false; for (var i:String in _aTweens) { var to:Object = _aTweens[i]; to.targ.removeListener(this); _ZigoEngine.removeTween(to.targ, to.props); delete _aTweens[i]; } delete _aTweens; _bTrigger = false; } /** * @exclude * An event dispatched by parent Fuse to all child @files to preset tween start-values. * @param o event object containing a .filter property which can specify exclusion from the call */ private function evtSetStart(o:Object):Void { // no starts to set or Fuse is about to play this item. if (_sImage.indexOf('StartProps:')==-1 || o.curIndex==_nItemID) { return; } if (o.all!=true) { var match:Boolean = false; for (var i:String in o.filter) { if (Number(o.filter[i])==_nItemID || String(o.filter[i])==_oElements.label) match = true; } if (match==false) { return; } } doTweens(o.targs, o.scope, true); // flag removed when parent Fuse stopped. _bStartSet = true; } /** * @exclude * Called by parent Fuse to pause or resume the @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem's tweens and tweened delays. During resume it is not assumed that targets and pauses are intact, each is checked and the internal tween array is trimmed if items have gone missing. * @param resume indicates whether it is a pause or resume call */ public function pause(resume:Boolean):Void { if (_nPlaying==-1) return; _nPlaying = ((resume==true) ? 1 : 0); for (var i:String in _aTweens) { var o:Object = _aTweens[i]; var t:Object = o.targ; var p:Object = o.props; if (resume==true) { // Is pause intact? Target/prop could have been manipulated since it was paused here. var missing:Array = []; var oldTL:Number = _aTweens.length; for (var j:String in p) { if (_ZigoEngine.isTweenPaused(t,p[j])==false) missing.push(p[j]); } if (missing.length>0) { onTweenEnd({__zigoID__:o.targZID, props:missing, isResume:true}); } if (_aTweens.length==oldTL) { // otherwise onTweenEnd removed the tween t.addListener(this); _ZigoEngine.unpauseTween(t, o.props); } } else { t.removeListener(this); _ZigoEngine.pauseTween(t, o.props); } } if (resume==true && !(_aTweens.length>0)) { // no tweens. complete(); } else if (resume==true) { _ZigoEngine.addListener(this); } else { _ZigoEngine.removeListener(this); } } /** * @exclude * Called by parent Fuse to clear @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem instance's memory and listeners during Fuse's destroy cycle. */ public function destroy():Void { var doRemove:Boolean = (_nPlaying>-1); _nPlaying = -1; for (var i:String in _aTweens) { var o:Object = _aTweens[i]; o.targ.removeListener(this); if (doRemove==true) _ZigoEngine.removeTween(o.targ, o.props); delete _aTweens[i]; } for (var j:String in this) { delete this[j]; } } /** * @exclude */ private function dispatchRequest(type:String, args:Array):Void {// avoids import of Fuse class since @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem can be used with ZigoEngine as an Object Syntax extension var f:Object = _global.com.mosesSupposes.fuse.Fuse.getInstance(_nFuseID); if (!(args instanceof Array) && args!=null) args = (new Array(args)); Function(f[type]).apply(f, args); } // 2. /** * @exclude * Concise string ID representing the parent Fuse's fixed ID and the @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem's current index in the Fuse, such as "Fuse#0>Item#0" */ private function _sID():String // like "Fuse#0>Item#0" { var str:String; if (_nFuseID==-1) { str = 'One-off tween '; } else { var fuse:Object = _global.com.mosesSupposes.fuse.Fuse.getInstance(_nFuseID); str = 'Fuse#'+String(_nFuseID); if (fuse.label!=undefined) str+=':"'+fuse.label+'"'; } str+='>Item#'+String(_nItemID); if (_oElements.label!=undefined) str+=':"'+_oElements.label+'"'; return str; } /** * @exclude * Constructor - Attempts to parse action(s) into_oElements
and_aProfiles
, building the verbose string ID_sImage
in the process. * @param id current index of @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem in parent Fuse instance * @param o action object or Array of action objects pushed into the Fuse for parsing * @param fuseID permanent unique ID of parent Fuse stored in _nFuseID */ public function @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem (id:Number, o:Object, fuseID:Number) { _ZigoEngine = _global.com.mosesSupposes.fuse.ZigoEngine; this._nItemID = id; this._nFuseID = fuseID; this._initObj = o; _aProfiles = []; _oElements = { aEvents:[] }; _oTemps = {}; if (!(o instanceof Array)) o = [o]; var fuse:Object = _global.com.mosesSupposes.fuse.Fuse; _oTemps.outputLevel = (fuse!=undefined) ? fuse.OUTPUT_LEVEL : _global.com.mosesSupposes.fuse.ZigoEngine.OUTPUT_LEVEL; // v2 Command actions can only contain delay, label, scope, args and may not be nested in groups. if (o.length==1) { var o0:Object = o[0]; var obj:Object = (o0.action!=undefined) ? o0.action : o0; if (obj.__buildMode!=true && obj.command!=undefined) { _oElements.command = obj.command; _oElements.scope = obj.scope; // v2.0: changed commandscope & commandargs to scope, args. _oElements.args = obj.args; _sImage = ' Elements:['+('command'+((typeof obj.command=='string') ? ':"'+obj.command+'", ' : ', ')); if (obj.label!=undefined && typeof obj.label=='string') { _sImage+=('label:"'+obj.label+'", '); _oElements.label = obj.label; // one label per Command Action } if (obj.delay!=undefined) { _sImage+='delay, '; _oElements.delay = obj.delay; // one delay per Command Action } if (obj.func!=undefined && _oTemps.outputLevel>0) FuseKitCommon.error('113'); return; } } // persistant vars for looping through actions _oTemps.sImgS = ''; _oTemps.sImgE = ''; _oTemps.sImgB = ''; _oTemps.afl = 0; _oTemps.ael = 0; _oTemps.twDelayFlag = false; _oTemps.nActions = o.length; _oTemps.fuseProps = FuseKitCommon._fuseprops(); _oTemps.cbProps = FuseKitCommon._cbprops(); _oTemps.sUP = FuseKitCommon._underscoreable(); _oTemps.sCT = FuseKitCommon._cts(); _oTemps.bTriggerFound = false; // Parse each profile. for (var i:String in o) { var item:Object = o[i]; if (item.label!=undefined && typeof item.label=='string') _oElements.label = item.label; // one string-only label per @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem var a:Object; var aap:Object; var bApplied:Boolean = Boolean(typeof item.action=='object' && !(item.action instanceof Array)); // reject arrays in action param! if (bApplied==true) { a = item.action; aap = { // applied-action profile, these props are mixed into the action during parseProfile. delay:item.delay, target:item.target, addTarget:item.addTarget, label:item.label, trigger:item.trigger }; } else { a = item; } var oPr:Object = parseProfile(a, aap); if (oPr!=undefined) { _aProfiles.unshift(oPr); } } // build string image (if a command was passed in, this happens up top.) _sImage = ''; var str:String = ''; if (_oElements.label!=undefined) str+=('label:"'+_oElements.label+'", '); if (_oTemps.afl>0) str+= ((_oTemps.afl>1) ? _oTemps.afl+' callbacks, ' : 'callback, '); if (_oElements.delay!=undefined || _oTemps.twDelayFlag==true) str+='delay, '; if (_oTemps.bTriggerFound==true) str+='trigger, '; if (_oTemps.ael>0) str+= ((_oTemps.ael>1) ? _oTemps.ael+' events, ' : 'event, '); if (str!='') _sImage+=' Elements:['+(str.slice(0,-2))+']'; if (_oTemps.sImgS!='') _sImage+= ' StartProps:['+(_oTemps.sImgS.slice(0,-2))+']'; // careful: "StartProps:" is checked in evtSetStart if (_oTemps.sImgE!='') _sImage+= ' Props:['+(_oTemps.sImgE.slice(0,-2))+']'; if (_oTemps.sImgB!='') _sImage+= ' Simple Syntax Props:['+(_oTemps.sImgB.slice(0,-1))+']'; delete _oTemps; } /** * @exclude * Used by constructor to parse each action object passed (multiple objects can be passed in an Array for simultaneous action groups). The parsing process is a fairly complex procudure that blocks tween start & end properties, tags 'auto-fill' end properties in which only a start value was passed, extracts freestanding items that do not require tweens, and generates proxy tweens used to handle delays within groups. * @param obj the action object to be parsed into a profile and pushed into _aProfiles * @param aap Stands for 'applied action profile' object. When an 'applied action' is encountered, this override profile mixes properties into the resulting profile. * @return parsed profile object */ private function parseProfile(obj:Object, aap:Object):Object { var i:String, j:String, k:String; // Build Mode (simple syntax) objects if (obj.__buildMode==true) { if (obj.command!=undefined) { if (obj.command=='delay') { // addCommand('delay',Number) _oElements.delay = obj.commandargs; } else { _oElements.command = obj.command; _oElements.args = obj.commandargs; } } if (obj.func!=undefined) { _oTemps.afl++; _oElements.aEvents.unshift({f:obj.func,s:obj.scope,a:obj.args}); } if (obj.tweenargs!=undefined) { _oTemps.sImgB += (obj.tweenargs[1].toString()+','); // (allowing duplicates in simple syntax props image to save code, since it could be comma-delim str) return obj; } return null; } var oPr:Object = { delay:(aap.delay!=undefined) ? aap.delay : obj.delay, ease:obj.ease, seconds:obj.seconds, event:obj.event, eventparams:obj.eventparams, skipLevel:(typeof obj.skipLevel=='number' && obj.skipLevel>=0 && obj.skipLevel<=2) ? obj.skipLevel : _ZigoEngine.SKIP_LEVEL, // correct early for use in @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem.doTweens oSP:{}, oEP:{}, oAFV:{} }; // trigger var trigger:Object = ((aap.trigger!=undefined) ? aap.trigger : obj.trigger); // can be true or number, not parsed until doTweens if (trigger!=undefined) { if (_oTemps.bTriggerFound==false) { // only one trigger is allowed per @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem oPr.trigger = trigger; _oTemps.bTriggerFound = true; } else if (_oTemps.outputLevel>0) { FuseKitCommon.error('126',(_sID()),trigger); } } // synonyms if (oPr.delay==undefined) oPr.delay = obj.startAt; if (oPr.ease==undefined) oPr.ease = obj.easing; // synonym (cannot use OR eval with string for some reason) if (oPr.seconds==undefined) oPr.seconds = ((obj.duration!=undefined) ? obj.duration : obj.time); // synonym (cannot use OR eval with string for some reason) // applied action target param overrides action target param if (aap.target!=undefined) oPr.target = ((aap.target instanceof Array) ? aap.target : [aap.target]); else if (obj.target!=undefined) oPr.target = ((obj.target instanceof Array) ? obj.target : [obj.target]); // applied action addTarget param adds to action addTarget param (don't change order) if (obj.addTarget!=undefined) oPr.addTarget = ((obj.addTarget instanceof Array) ? obj.addTarget : [obj.addTarget]); if (aap.addTarget!=undefined) { if (oPr.addTarget==undefined) oPr.addTarget = ((aap.addTarget instanceof Array) ? aap.addTarget : [aap.addTarget]); else oPr.addTarget = ((oPr.addTarget instanceof Array) ? (oPr.addTarget.concat(aap.addTarget)) : ((new Array(oPr.addTarget)).concat(aap.addTarget))); } var bTwFlag:Boolean = false; for (j in obj) { var v:Object = obj[j]; if ((_oTemps.cbProps).indexOf('|'+j+'|')>-1) {//'|cycles|easyfunc|func|scope|args|startfunc|startscope|startargs|updfunc|updscope|updargs|extra1|extra2|' if (j!='skipLevel') oPr[j] = v; continue; } if ((_oTemps.fuseProps).indexOf('|'+j+'|')>-1) {//'|command|label|delay|event|eventparams|target|addTarget|trigger|startAt|ease|easing|seconds|duration|time|' if (j=='command' && _oTemps.nActions>1 && _oTemps.outputLevel>0) FuseKitCommon.error('114',String(v)); continue; } if (typeof v=='object') { var copy:Object = (v instanceof Array) ? ([]) : {}; for (k in v) copy[k] = v[k]; v = copy; } var se:Object; var seCP:Object; if (j.indexOf('start')==0) { j = j.slice(6); se = oPr.oSP; } else { se = oPr.oEP; } if (ADD_UNDERSCORES==true && _oTemps.sUP.indexOf('|_'+j+'|')>-1) j='_'+j; if (_oTemps.sCT.indexOf('|'+j+'|')>-1) { var addPct:Boolean = (j=='_tintPercent' && se.colorProp.p=='_tint'); var addTint:Boolean = (j=='_tint' && se.colorProp.p=='_tintPercent'); if (se.colorProp==undefined || addPct==true || addTint==true) { // write only 1 color prop per profile, saves cleanup work during tween. if (addPct==true) se.colorProp = {p:'_tint', v:{ tint:se.colorProp.v, percent:v }}; else if (addTint==true) se.colorProp = {p:'_tint', v:{ tint:v, percent:se.colorProp.v }}; else se.colorProp = {p:j, v:v}; bTwFlag = true; } else if (_oTemps.outputLevel>0) { FuseKitCommon.error('115',(_sID()),j); } } else if (v!=null) { // (null values are only accepted for color props) if (se==oPr.oEP && (obj.controlX!=undefined || obj.controlY!=undefined) && (j.indexOf('control')==0 || j=='_x' || j=='_y')) { // group bezier end props if (se._bezier_==undefined) se._bezier_ = {}; if (j.indexOf('control')==0) se._bezier_[j] = v; //controlX, controlY else (se._bezier_[(j.charAt(1))] = v); // x, y } else { se[j] = v; } bTwFlag = true; } } // end parse props(j), still looping through actions(i) /* Special "Nontween delay" cases * (Note that normally delays are played by parent fuse except in these cases) * -start/update callbacks without any tween props * -delay within multi-item group */ if (bTwFlag==false && (oPr.trigger!=undefined || ((oPr.delay!=undefined || oPr.seconds!=undefined) && ( (oPr.startfunc!=undefined || oPr.updfunc!=undefined) || (oPr.func!=undefined && _oTemps.nActions>1) )))) { if (_ZigoEngine==undefined) { // ignore output level for crucial error message FuseKitCommon.error('116'); } else { if (oPr.func!=undefined) _oTemps.afl++; if (oPr.event!=undefined) _oTemps.ael++; oPr._doTimer = true; if (oPr.delay!=undefined) _oTemps.twDelayFlag = true; return oPr; } } if (bTwFlag==true) { // do a final round of cleanup on tween profile and build string image var bEC:Boolean = (oPr.oEP.colorProp!=undefined); for (var l:Number=0; l<2; l++) { var se:Object = (l==0) ? oPr.oSP : oPr.oEP; var str:String = (l==0) ? _oTemps.sImgS : _oTemps.sImgE; var sCP:String = se.colorProp.p; if (sCP!=undefined) { // combine color back in (colorProp was used to enforce single start/end color) se[sCP] = se.colorProp.v; delete se.colorProp; } if ((se._xscale!=undefined || se._scale!=undefined) && (se._width!=undefined || se._size!=undefined)) { var discard:String = (se._xscale!=undefined) ? '_xscale' : '_scale'; delete se[discard]; if (_oTemps.outputLevel>0) FuseKitCommon.error('115',(_sID()),discard); } if ((se._yscale!=undefined || se._scale!=undefined) && (se._height!=undefined || se._size!=undefined)) { var discard:String = (se._yscale!=undefined) ? '_yscale' : '_scale'; delete se[discard]; if (_oTemps.outputLevel>0) FuseKitCommon.error('115',(_sID()),discard); } for (j in se) { if (str.indexOf(j+', ')==-1) str+=(j+', '); if (se==oPr.oSP) { if (oPr.oEP[j]==undefined && !(j==sCP && bEC==true)) { // add 'autofill' lookup oPr.oAFV[j] = true; oPr.oEP[j] = []; } } } ((l==0) ? _oTemps.sImgS = str : _oTemps.sImgE = str); } return oPr; } // If no tweens were added or start/end profiles ended up empty, move usable props to _oElements if (oPr.delay!=undefined && _oTemps.nActions==1) { // single-item actions only, see first if() in this block for multi-item actions _oElements.delay = oPr.delay; _oElements.delayscope = oPr.scope; // (internal, not a valid user prop!) } if (oPr.event!=undefined) { _oTemps.ael++; _oElements.aEvents.unshift({e:oPr.event, s:oPr.scope, ep:oPr.eventparams, skipLevel:oPr.skipLevel}); } // actions containing startfunc/updfunc are handled w/nonTweenDelay. var oldL:Number = _oElements.aEvents.length; if (oPr.easyfunc!=undefined) _oElements.aEvents.push({cb:oPr.easyfunc, s:oPr.scope, skipLevel:oPr.skipLevel}); if (oPr.func!=undefined) _oElements.aEvents.push({f:oPr.func, s:oPr.scope, a:oPr.args, skipLevel:oPr.skipLevel}); _oTemps.afl+=(_oElements.aEvents.length-oldL); delete oPr; return undefined; } // 3. /** * @exclude * Internal method to preset start values and generate tween calls to be sent to the engine. This is a complex procedure mainly due to the 'runtime-evaluation' feature of the Kit - scope, target(s), and all start and end values delegated to a function are retrieved by executing such functions just as the item is encountered in the sequence. doTweens handles all of this, builds and sends the tween calls while storing a reference in the internal _aTweens array. It then does emergency cleanup in situations where no tweens successfully fired and boolean end-values, callbacks, or delays are orphaned. Presetting start values is handled with 0-second tween calls which is important for interrupting any current tweens, which are monitored by any running Fuses; Start values with missing end-values are 'auto-filled' during doTweens. * @param targs parent Fuse instance's current default targets * @param defaultScope parent Fuse instance's current default scope * @param setStart flag indicating that the doTweens call should only preset start values. * @return returns successfully tweened props for doTween() */ private function doTweens(targs:Array, defaultScope:Object, setStart:Boolean):String { if (_aTweens==null) { this._aTweens = []; } var fuse:Object = _global.com.mosesSupposes.fuse.Fuse; var outputLevel:Number = (fuse!=undefined) ? fuse.OUTPUT_LEVEL : _ZigoEngine.OUTPUT_LEVEL; var propsAdded:String = ''; var nTgErrors:Number = 0; var i:String, j:String, k:String; // Build-Mode @ax-actionscript-video-com-mosesSupposes-fuse-FuseItem (startprops option doesn't exist here)---------- if ((_aProfiles[0]).__buildMode==true) { for (var h:Number=0; h<_aProfiles.length; h++) { var twArgs:Array = (_aProfiles[h]).tweenargs; if ((twArgs[6]).cycles===0 || ((twArgs[6]).cycles.toUpperCase())=='LOOP') { delete (twArgs[6]).cycles; if (outputLevel>0) FuseKitCommon.error('117',(_sID())); } var sProps:String = (_ZigoEngine.doTween.apply(_ZigoEngine, twArgs)); var aProps:Array = ((sProps==null) ? [] : (sProps).split(',')); if (aProps.length>0) { _aTweens.push({targ:(twArgs[0]), props:aProps, targZID:(twArgs[0]).__zigoID__}); (twArgs[0]).addListener(this); for (j in aProps) if (propsAdded.indexOf(aProps[j]+',')==-1) propsAdded+=(aProps[j]+','); } if (outputLevel==3) FuseKitCommon.output('\n-'+(_sID())+' TWEEN (simple syntax)\n\ttargets:['+twArgs[0]+']\n\tprops sent:['+twArgs[1]+']'); } return ((propsAdded=='') ? null : propsAdded.slice(0,-1)); } // Normal setStart, tweens --------------------------------------------- var doSetStarts:Boolean = (_bStartSet!=true && (setStart==true || _sImage.indexOf('StartProps:')>-1)); // cycling through each action profile for (var h:Number=0; h<_aProfiles.length; h++) { var pr:Object = _aProfiles[h]; // Set scope for callbacks + runtime-eval funcs. // Each action may define a "scope" param which overrides Fuse default scope var scope:Object = defaultScope; // this local is used many times within this loop for runtime-eval if (pr.scope!=undefined) { // scope param can be a runtime func (or delegate) that uses Fuse default scope to eval. // (The evaled scope will cascade to updscope & startscope if they are funcs.) scope = (pr.scope instanceof Function) ? pr.scope.apply(scope) : pr.scope; } // build event object var event:Object; if (pr.event!=undefined) { var evt:String = ((pr.event instanceof Function) ? pr.event.apply(scope) : pr.event); var evtparams:Object = ((pr.eventparams instanceof Function) ? pr.eventparams.apply(scope) : pr.eventparams); if (evt!=undefined && evt.length>0) { event = {e:evt, ep:evtparams, s:scope}; } } // build callback object var skipLevel:Boolean = ((pr.skipLevel instanceof Function) ? pr.skipLevel.apply(scope) : pr.skipLevel); var oSimpleCB:Object = { skipLevel:skipLevel }; var oCB:Object = { skipLevel:skipLevel }; if (pr.cycles!=undefined) { var cycles:Object = ((pr.cycles instanceof Function) ? pr.cycles.apply(scope) : pr.cycles); if ((Number(cycles)==0 || (String(cycles).toUpperCase())=='LOOP') && fuse!=undefined) { delete pr.cycles; if (outputLevel>0) FuseKitCommon.error('117',(_sID())); // infinite cycles not allowed in fuses } else { oSimpleCB.cycles = oCB.cycles = cycles; } } var cbstr:String=''; if (pr.easyfunc!=undefined || pr.func!=undefined || pr.startfunc!=undefined || pr.updfunc!=undefined) { for (i in pr) { if (i.indexOf('func')>-1) { oCB[i] = pr[i]; } else if (i=='startscope' || i=='updscope' || i.indexOf('args')>-1) { oCB[i] = (pr[i] instanceof Function) ? Function(pr[i]).apply(scope) : pr[i]; } } if (scope!=undefined) { if (oCB.func!=undefined && oCB.scope==undefined) oCB.scope = scope; // auto-fill callback scopes where possible if (oCB.updfunc!=undefined && oCB.updscope==undefined) oCB.updscope = scope; if (oCB.startfunc!=undefined && oCB.startscope==undefined) oCB.startscope = scope; } } for (j in oCB) cbstr+=(j+':'+oCB[j]+'|'); // trigger: may be boolean, number, or runtime-eval function var triggerTrue:Boolean = (pr.trigger===true); var triggerTime:Number = undefined; if (triggerTrue==false && pr.trigger!=undefined) { triggerTime = ((pr.trigger instanceof Function) ? pr.trigger.apply(scope) : pr.trigger); if (typeof triggerTime=='string') { triggerTime = ((String(triggerTime).charAt(0)=='-') ? -(parseClock(String(triggerTime).slice(1))) : (parseClock(String(triggerTime)))); } if (_global.isNaN(triggerTime)==true) triggerTime = undefined; } // Targets // evaluated targets + addTargets var targets:Array = []; var aBase:Array = (pr.target==undefined) ? targs : pr.target; var aTemp:Array = []; var bTgError:Boolean = false; // (any runtime func (or delegate) may return one targ or an array of targs) for (i in aBase) { var v:Object = aBase[i]; aTemp = aTemp.concat((v instanceof Function) ? v.apply(scope) : v); } for (i in pr.addTarget) { var v:Object = pr.addTarget[i]; aTemp = aTemp.concat((v instanceof Function) ? v.apply(scope) : v); } for (i in aTemp) { var v:Object = aTemp[i]; if (v!=null) { var exists:Boolean = false; for (j in targets) { if (targets[j]==v) { exists = true; break; } } if (exists==false) targets.unshift(v); } else { bTgError = true; } } var noTargError:Boolean = (targets.length==0 && pr._doTimer!=true); var doTimer:Boolean = (pr._doTimer==true && targets.length==0); if (bTgError==true || noTargError==true) { nTgErrors++; if (noTargError==true) { continue; } } // -- 1. start props -- if (doSetStarts==true) { // generate one ZigoEngine.doTween() call per target. Props parsed for runtime-eval, bools, validation for (i in targets) { var targ:Object = targets[i]; var aSP:Array = []; var aSV:Array = []; if (setStart==true) { for (var q:String in pr.oEP) { // Use 3rd param createNew to pre-create any missing filters on setStartProps, so the filter doesn't suddenly appear just before that action starts. _global.com.mosesSupposes.fuse.FuseFMP.getFilterProp(targ,q,true); } } for (var p:String in pr.oSP) { var v:Object = pr.oSP[p]; if (v instanceof Function) v = v.apply(scope); if (v===true || v===false) { // set start booleans immediately. targ[p] = v; if (pr.oAFV[p]==true) { // prohibit autofill with booleans. for (k in pr.oEP[p]) if (pr.oEP[p][k].targ==targ) pr.oEP[p].splice(Number(k),1); pr.oEP[p].push({targ:targ,val:'IGNORE'}); } continue; } // autofill missing end values. Assume resets for known properties, otherwise take a snapshot of the current value to return to. if (pr.oAFV[p]==true && !(p=='_colorReset' && v==100) && !(p=='_tintPercent' && v==0)) {// if no endprop was passed for startprop, store current value (does not apply to color prop which resets, preset during constructor parse) var afv:Object; if (p=='_tint' || p=='_colorTransform') { afv = _ZigoEngine.getColorTransObj(); } else if (('|_alpha|_contrast|_invertColor|_tintPercent|_xscale|_yscale|_scale|').indexOf('|'+p+'|')>-1) { afv = 100; } else if (('|_brightness|_brightOffset|_colorReset|_rotation|').indexOf('|'+p+'|')>-1) { afv = 0; } else { // snapshot current val, retaining target (which is important in the case of relative endvals) var fmpVal:Number = _global.com.mosesSupposes.fuse.FuseFMP.getFilterProp(targ,p,true); if (fmpVal!=null) afv = fmpVal; else afv = (_global.isNaN(targ[p])==false) ? targ[p] : 0; } for (k in pr.oEP[p]) if (pr.oEP[p][k].targ==targ) pr.oEP[p].splice(Number(k),1); pr.oEP[p].push({targ:targ,val:afv}); } if (typeof v=='object') { var copy:Object = (v instanceof Array) ? ([]) : {}; for (k in v) copy[k] = ((v[k]) instanceof Function) ? Function(v[k]).apply(scope) : v[k]; v = copy; } aSP.push(p); aSV.push(v); }// end startprops loop(n) // set starts using egine, which monitors/broadcasts interrupts + parses complex properties. if (aSV.length>0) { if (outputLevel==3) FuseKitCommon.output('-'+(_sID())+' '+targ+' SET STARTS: '+['['+aSP+']', '['+aSV+']']); _ZigoEngine.doTween(targ, aSP, aSV, 0); } } // end set starts }// end if startprops if (setStart==true) { continue; } // -- 2. end props -- // Generate one ZigoEngine.doTween() call per target since envals can differ due to auto-fill feature. // the last round of evaluating seconds, delay, and booleans is saved for the pickup round that happens after this loop var seconds:Number; var delay:Number; var booleans:Object;// Group end-booleans per target to be set in onTweenEnd var tweenSuccess:Boolean = false; var targsOrProxy:Array = ((doTimer==false) ? targets : [0]);// force loop to occur once for targetless timer tweens for (i in targsOrProxy) { // Eval other per-profile params (putting this in the loop is less efficient but it allows runtime-eval-funcs to be run per target.) // Q: when a user builds an action and there are multiple targets, do they want getters to be fired per target, or per action? var ease:Object = pr.ease; if (ease instanceof Function) { // could be a runtime eval function! var ef:Function = (Function(ease)); if (typeof ef(1,1,1,1)!='number') ease = ef.apply(scope); // it's not a valid easing equation the engine can use. } seconds = (pr.seconds instanceof Function) ? pr.seconds.apply(scope) : pr.seconds; if (seconds!=undefined) { if (typeof seconds=='string') seconds = (parseClock(String(seconds))); if (_global.isNaN(seconds)==true) seconds = (_ZigoEngine.DURATION || 0); } delay = (pr.delay instanceof Function) ? pr.delay.apply(scope) : pr.delay; if (typeof delay=='string') delay = (parseClock(String(delay))); if (delay==null || _global.isNaN(delay)==true) delay = 0; if (doTimer==true) continue; // --------------------------------------------------------------- //parse var targ:Object = targsOrProxy[i]; var aEP:Array = []; var aEV:Array = []; var numBools:Number = 0; for (var p:String in pr.oEP) { var v:Object = pr.oEP[p]; if (v instanceof Function) { v = v.apply(scope); } if (v===true || v===false) { // end booleans will be attached to a tween & set in onTweenEnd. if (booleans==undefined) booleans = {}; booleans[p] = v; numBools++; continue; } if (typeof v=='object') { if ((v[0]).targ!=undefined) { // this is an autofilled property - match targets. for (k in v) { if ((v[k]).targ==targ) { v = (v[k]).val; break; } } } else { var copy:Object = (v instanceof Array) ? ([]) : {}; for (k in v) copy[k] = ((v[k]) instanceof Function) ? Function(v[k]).apply(scope) : v[k]; v = copy; } } if (v!='IGNORE') { aEP.push(p); aEV.push(v); } } // end endprops loop(n) // normal tweens. monitor only the props that are added to the engine's tweenlist. var aProps:Array = []; if (aEV.length>0) { // Only add callbacks/booleans/events in the case of single target - otherwise these things will be picked up with a fake tween later. var sProps:String = _ZigoEngine.doTween(targ, aEP, aEV, seconds, ease, delay, oCB); if (sProps!=null) aProps = (sProps.split(',')); if (aProps.length>0) { var to:Object = {targ:targ, props:aProps, bools:booleans, targZID:targ.__zigoID__}; if (tweenSuccess==false) { // Important: callback, event, trigger:true need to only be added once per profile. oCB = oSimpleCB; to.event = event; event = booleans = undefined; to.trigger = triggerTrue; // single-target profile with trigger:true } _aTweens.push(to); targ.addListener(this); tweenSuccess = true; } for (j in aProps) if (propsAdded.indexOf(aProps[j]+',')==-1) propsAdded+=(aProps[j]+','); // TRACE TWEENS (lets you know if one or more props didn't get added) if (outputLevel==3) { var epstr:String = aEP.toString(); if (aProps.length>aEP.length) epstr += ('\n\t[NO-CHANGE PROPS DISCARDED. KEPT:'+sProps+']'); var evstr:String = ''; for (j in aEV) evstr=(((typeof aEV[j]=='string')?'"'+aEV[j]+'"':aEV[j]) + ', '+evstr); FuseKitCommon.output('\n-'+(_sID())+' TWEEN:\n'+(['\t[getTimer():'+getTimer()+'] ','targ: '+targ, 'props: '+epstr, 'endVals: '+evstr, 'time: '+((seconds==undefined) ? _ZigoEngine.DURATION : seconds), 'easing: '+((ease==undefined) ? _ZigoEngine.EASING : ease), 'delay: '+((delay==undefined) ? 0 : delay), 'callbacks: '+((cbstr=='') ? '(none)':cbstr)]).join('\n\t')); } } } // end targets loop(i) if (seconds==undefined || _global.isNaN(seconds)==true) seconds = 0; var time:Number = delay+seconds; // time-based trigger: use a fake tween (trigger time must be less than tween duration+delay) if (triggerTime!=undefined) { // Special option to use a negative trigger time, which is counted back from the end of the tween if (triggerTime<0) { triggerTime += time; } if (triggerTime>0 && (time==0 || triggerTime