import mx.utils.Delegate;
import mx.events.EventDispatcher;
import com.mosesSupposes.fuse.FuseItem;
import com.mosesSupposes.fuse.FuseKitCommon;
/**
*
* Fuse Kit 2
* 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
*
* Event & animation sequencer that extends Array.
*
* @usage
* To enable animation sequencing, pass Fuse to {@link com.mosesSupposes.fuse.ZigoEngine#register} or {@link com.mosesSupposes.fuse.ZigoEngine#simpleSetup}.
*
* Events dispatched:
*
onStartonStoponPauseonResumeonAdvanceonCompletevar f:Fuse = new Fuse();
* f.addEventListener("onComplete", myListenerObj);
* trace(Fuse.VERSION); // if the version is incorrect, clear your ASO cache.*/ public static var VERSION:String = FuseKitCommon.VERSION; /** * Class default: Controls how much feedback Fuse outputs, helpful for debugging. * @usage
// once only * Fuse.OUTPUT_LEVEL = 3;*
// once only * Fuse.AUTOCLEAR = true; * * // later this can be overridden in any instance * var f:Fuse = new Fuse(); * f.autoClear = false;* When a Fuse is set to auto-remove itself it is best practice to not set a variable reference to that Fuse, which may cause memory buffering, or to delete the variable when the Fuse is complete.
// once only * Fuse.AUTOSTOP = false;* If this default is set false, Fuses will skip past any externally interrupted tweens and continue to play through. * When Fuses are used in interactive devices like rollover states, it is best to leave this setting true to avoid conflicts between Fuse instances controlling the same behavior.
var drawContentPage:Fuse = new Fuse(); * drawContentPage.label = "drawContentPage";* @description The Fuse label is used in output messages, and can be used to reference a Fuse instance in {@link #getInstance}, {@link #fastForward} and Simple Syntax methods {@link #open} and {@link #openGroup}. * @see #id * @see #getInstance * @see #open * @see #openGroup */ public var label:String; /** * Instance default: Fuse instance is automatically destroyed after playing once. * @usage *
var f:Fuse = new Fuse(); * f.autoClear = true;* In this example, the fuse instance f will delete itself after it plays through once, at which time you should also delete the variable
f to prevent memory buffering issues.
* @see #AUTOCLEAR
*/
public var autoClear:Boolean;
/**
* Instance default: Fuse instance stops when any of its running tweens are interrupted, or is destroyed if {@link #autoClear} is turned on.
* @usage This instance-level setting overrides the default setting Fuse.{@link #AUTOSTOP}. If false an interrupted Fuse will recover and continue to play through.
* var f:Fuse = new Fuse(); * f.autoStop = false; //override the default setting for this Fuse instance* @see #AUTOSTOP * @see #autoClear * @see #AUTOCLEAR */ public var autoStop:Boolean; /** * Instance default: scope for all functions run from a Fuse if left unspecified within the action. * @usage *
var f:Fuse = new Fuse();
* f.scope = this;
* f.push({target:menu,
* start_alpha:0,
* x:getMenuX,
* y:getMenuY,
* startfunc:"setupMenu",
* updfunc:"onMenuFadeUpdate",
* func:"onMenuShown"
* });
* f.push({ scope:contentArea,
* func:"drawContent"
* });
* In this example, all the functions in the first action, including the runtime-evaluation calls to supposed getMenuX and getMenuY methods will be
* auto-scoped to the Fuse's default scope (this). In the second action, drawContent is specifically scoped to the contentArea object, overriding the default.
* It's most useful to set a default scope when there will be many function calls within the sequence, to save you from specifically scoping each action.
* @see #Fuse
*/
public var scope:Object;
/**
* Instance default: duration value in seconds for any action that does not specify one.
* @usage This setting supercedes the default {@link com.mosesSupposes.fuse.ZigoEngine#DURATION} only for the
* Fuse instance it is set on, and is overrided by any action containing its own seconds,
* duration, or time parameter.
* var f:Fuse = new Fuse();
* f.duration = 2;
* f.push({ x:'100' }); // adopts new default
* f.push({ y:'100', time:.5 }); // overrides default
* @see #ease
* @see com.mosesSupposes.fuse.ZigoEngine#DURATION
*/
public var duration:Number;
/**
* Instance default: easing value for any action that does not specify one.
* @usage This setting supercedes the default {@link com.mosesSupposes.fuse.ZigoEngine#EASING} only for the
* Fuse instance it is set on, and is overrided by any action containing its own ease or
* easing parameter.
* var f:Fuse = new Fuse();
* f.easing = "easeInOutCubic";
* f.push({ x:'100' }); // adopts new default
* f.push({ y:'100', ease:'easeInExpo' }); // overrides default
* @see #duration
* @see com.mosesSupposes.fuse.ZigoEngine#EASING
*/
public var easing:Object;
/**
* Internal id based on instance count.
*/
private var _nID:Number;
/**
* Internal sequence play-index.
*/
private var _nIndex:Number;
/**
* Internal, can be -1 ("stopped"), 1 ("playing"), or 0 ("paused").
*/
private var _nState:Number = -1;
/**
* Internal list of instance's default animation targets, set using public setter target or addTarget method.
*/
private var _aDefaultTargs:Array;
/**
* Internal setInterval id for delays run by Fuse. (Delays in groups or with tweens are handled by FuseItem.)
*/
private var _nDelay:Number = -1;
/**
* Internal storage used for tracking a delay's current time during pause().
*/
private var _nTimeCache:Number = -1;
/**
* Stores a Delegate function used to trap nested Fuse's onComplete event (stored for later removal during destroy()).
*/
private var _oDel1:Object;
/**
* Static list of all Fuse instances created, publicly accessible via getInstance() and getInstances() and used by remote methods like open().
*/
private static var _aInstances:Array = null;
/**
* Internal storage of Build Mode (Simple Syntax) params curID:Number (often queried to find out if Build Mode is active), prevID:Number, curGroup:Array.
*/
private static var _oBuildMode:Object = null;
/**
* Written in during EventDispatcher.initialize().
*/
private var dispatchEvent:Function;
/**
* Fuse extends Array to enable sequence-building & management using familiar methods like push().
* @param fuseAction One or more generic "action" objects or arrays in Fuse Object Syntax constituting a sequence.
* @usage
* * // setup - once per FLA only * import com.mosesSupposes.fuse.*; * ZigoEngine.register( Fuse, PennerEasing ); * * // build a short intro sequence to apply to box1_mc. * var f:Fuse = new Fuse(); * f.label = "swoopyIntro"; * f.target = box1_mc; * * f.push({ delay: .25 }); * * // labels can be used in some methods but are mostly a convenience. * f.push({ label: "appear", * start_scale: 500, * start_alpha: 0, * time: 1.75, * ease: "easeOutBack", * trigger: .5 // advances this action early * }); * * * // the array brackets in this action form a group of parallel tweens * f.push([ * { label: "swoop", * x: "80", * controlY: "50", // adds a bezier curve * time: 1.5, * ease: "easeInOutBack" * }, * * // these tweens bounce back, by using 2 cycles * { brightOffset: 50, * rotation: 10, * ease: "easeInOutQuad", * cycles: 2, * time: .5, * delay: .25 * } * ]); * * // a simple callback. You could also subscribe to the "onComplete" event. * f.push({ func:"trace", args:"done!" }); * * f.traceItems(); * f.start(true); // passing true presets start props - remove it to see a change. ** Starts the Fuse and outputs: *
-Fuse "swoopyIntro" traceItems: * ---------- * -Fuse "swoopyIntro">Item #0: Elements:[delay] * -Fuse "swoopyIntro">Item #1 "appear": Elements:[trigger] StartProps:[_alpha, _scale] Props:[_scale, _alpha] * -Fuse "swoopyIntro">Item #2 "swoop": Props:[_brightOffset, _rotation, _bezier_] * -Fuse "swoopyIntro">Item #3: Elements:[callback] * ---------- * done! ** Once a Fuse Array contains at least one action it is controllable with the play methods {@link #start}, * {@link #stop}, * {@link #pause}, * {@link #resume}, * {@link #skipTo}, * and {@link #fastForward}. Fuses dispatch the events listed at the * top of this page during their play cycle. Start properties can be preset for all or a specific subset of actions, using the {@link #setStartProps} method * or during any {@link #start} call. (If
true were not passed
* during start in the example above, the target would be visible during the short delay in the first action.) Note
* that end values are omitted in the "appear" action, making use of Fuse's smart parsing to keep
* actions concise. Actions can be further condensed with the use of instance defaults {@link #duration},
* {@link #easing}, {@link #target}, and {@link #scope}.label, target/addTarget,
* event/eventparams, trigger, command and
* a few extra time-notation options. Standard ZigoEngine tweening parameters, including user-defined variables, make up
* the bulk of what you'll see listed in any action. You can expect Object Syntax's features to be logical, intuitive and useful.
* ** Object Syntax DetailGetting started with Object Syntax
*Fuse Object Syntax is detailed thoroughly below. To start experimenting with it, simply paste the code block above into * a new FLA (AS2.0, 30 FPS), create a symbol on stage and name it
*box1_mc, then test the movie to see the clip * swoop in.The
*triggerfound in the"appear"action allows the animation to overlap with the next * action, like motion tweens in a layered timeline, by advancing early. As your first test, remove or comment out thetriggerto * see the difference in how the Fuse plays. Leave it out as you move on, to eliminate potential property-collision the trigger * can create (which Fuse handles gracefully, but may create visual confusion for learners).
*
* If you have Flash 8 or higher, addFuseFMPto the register call at top, then try addingstart_Blur_blur:50to * the"appear"action. Next,pusha few new actions into the sequence just before the final * trace action, and use them to try features listed below — the best way to familiarize yourself with Object Syntax is * through hands-on testing.
*
* Hints: If you're using the Fuse Kit Extension, sidebar of Flash's Actions panel contains a comprehensive list of Fuse * methods, properties, Object Syntax parameters and more, all of which will write themselves into your code on double-click. * When writing Object Syntax, pay close attention to brackets and commas. Fuse has its own set of error messages that can resemble * compiler errors (esp. in Flash 6-8) so be sure to read any errors carefully.Object Syntax Mechanics (advanced topic)
*Fuse actions are pre-parsed as much as possible as they're added to the Fuse. But Fuse's action interpreter is highly * active at runtime as each item begins playing.
*
*
* Internally, standalone program events, delays, callbacks, and boolean property-setters are split * off from animation when possible, or at other times blocked with tweens when tight synchronization is called for. All internal * tween calls Fuse makes to the engine are monitored carefully for potential failures (which can be caused by no-duration tweens, * boolean-setter-only actions andskipLevelsettings) to keep the sequence from stalling. Any elements left dangling * are picked up in the case of such a failure. Tween interruptions are also handled carefully to determine whether a Fuse containing * an advance-trigger might be overwriting one of its own tweens during advance, or if auto-stop functionality should otherwise * be honored due to an external interruption.
*
* These complex internal mechanics support Fuse's robust runtime parsing capabilities. Its ability to suss out missing * end-values when only start-values are provided includes returning any 'open' property (such as x or y) to its current position * just before that tween executes. To help you avoid hard-coding sequences, any start or end value can be set to a function * (or Delegate) returning that value, and it will be queried as the action executes, allowing you to keep things on-the-spot. * Because Fuse can tie directly into your program via callbacks and events, it's also possible to generate, alter, or conditionally * skip through Fuse sequences on the fly, or use a Fuse to control other Fuses.
*
*Working with asynchronous events (advanced topic)
*One common question from advanced programmers is whether Fuse can be set up to work with asynchronous program events, such * as a sequential loader that waits for an onLoad handler before advancing. The answer is that Fuse does not automate such behavior * but that it is easily achieved manually. (It turns out such automation is impractical in the real world. Consider a simple * loader class like
*MovieClipLoader. Using it requires instantiation, writing and wiring custom event handlers * that tie back into your program's code — Simply too much to do in-sequence.)
*
* It is easy to do nonetheless, by adding an inline{command:"pause"}action which makes the Fuse wait * for your asynchronous event to fire. Set up the dispatching object and any custom event handlers outside the Fuse. Sometimes * that routine can be encapsulated in a method triggered by the Fuse. Whatever kicks off the delay, aloadClipcall * for instance, could also be fired from the Fuse sequence if convenient.
*
* Once things are set up and your Fuse has self-paused, the final step is to set up a way to resume * the sequence when your event fires. If you're already writing a custom handler for this event you can simplyresume()the * Fuse in that method's code. (Tip: UseFuse.getInstance()to contact your Fuse from any scope.) You can * also very easily wire any event directly to a Fuse's resume method.
*
* For example:myMCL.addListener({onLoadInit:Delegate.create(f,f.resume)});. The fact that MovieClipLoader usesaddListenerinstead * ofaddEventListener(while another class might use yet another event model) is further evidence that this sort * of automation is best left to you, and is little of Fuse's business.
*
*
{ target:clip1, x:10, seconds:2, ease:Strong.easeInOut }[ { x:10, seconds:2, ease:Strong.easeInOut }, { start_alpha:0, seconds:.5 } ]myFuse2{ scope:myFuse2, func:"start" }.
* See a more complex example of this below under the command parameter.action property.var intro:Object = { ... } has been defined, you can then include it in later Fuse actions
* like this:{ target:clip1, action:intro }delay, target, addTarget, label, trigger.target overrides, addTarget concatenates targets with any that are defined in the action. See
* below for info on other properties.start_ to any property and it will be set prior to tweening.{start_alpha:0}
* which will tween to 100 automatically.{ start_x:-100, start_y:-100 }.x:100rotation:"-90" yields a counter-clockwise rotation.start_visible:true0x000000), String ("#000000"), or null (reset)tint:"#FF3300"seconds:2, startAt:"01:75" - timecode for a 1.75-second delay{ x:function(){ return _root._xmouse; } }scope property.
* If scope is already being used for callbacks, you can use a Delegate to individually scope runtime-evaluation functions.{ myArray:[10,20], myMatrix:{a:0, b:1, tx:100}, GradientBevel_colors:[0xFF0000, 0x333333, 0x00FFFF] }{ myColors: [ 0x000000, 0xFFFFFF ], scope:this, updfunc:'redrawGradient' }label An action's string id, used for skipTo and fastForward. Groups are considered single actions by Fuse. (To label a
* group include a label within any of its sub-actions.) As a convenience, labels also appear in output messages.target Animation target or Array of targets. Overrides the instance's default {@link #target} list.addTarget Concatenates one or an Array of targets with the default {@link #target} list.ease or easing Accepts same formats as {@link com.mosesSupposes.fuse.ZigoEngine#doTween}'s easing parameter.seconds, time or duration See time formatting above.delay or startAt See time formatting above.event String declaring a custom event that should be dispatched by the engine.eventparams An object whose properties will be copied to the event object dispatched with the custom event. (Requires that the event property is defined)func Function, string name of function, or Easyfunc string like "myClip.doSomething(true);" ({@link com.mosesSupposes.fuse.Shortcuts} must be registered to use the easyfunc feature.)scope Object - overrides instance default {@link #scope}. Note that in Fuse actions this property is special in that it will be applied to all callbacks or runtime-evaluation functions if not otherwise defined.args One argument or an array of arguments to pass to the func callback.startfunc Callback fired after any delay and as tween is starting. Supports various formats - see func above.startscope If not defined, the scope property or instance default {@link #scope} will be used.startargs One argument or an array of arguments to pass to the startfunc callback.updfunc Callback fired on engine pulse as the tweens in the action are updated. Accepts various formats - see func above.updscope If not defined, the scope property or instance default {@link #scope} will be used.updargs One argument or an array of arguments to pass to the updfunc callback.extra1 Optional fifth parameter sent to easing method. Elastic easing amplitude or Back easing overshoot.extra2 Optional sixth parameter sent to easing method. Elastic easing period._bezier_ (Not necessary, see controlX, controlY below.) Generic object with some or all of the properties {x:,y:,controlX:,controlY:}. Relative (string) values are okay. Note that only one control param is necessary to generate a curved motion path.controlX, controlY Including one or both of these parameters in a Fuse action along with x and/or y generates a bezier curve similar to using the _bezier_ property but without the need for a nested object.cycles An integer 2 or higher, tweens back and forth between start and end positions. Infinite cycles (0 or "LOOP" in {@link com.mosesSupposes.fuse.ZigoEngine#doTween}) are not allowed in Fuses.roundResults Overrides the class setting {@link com.mosesSupposes.fuse.ZigoEngine#ROUND_RESULTS} for an individual action.skipLevel 0,1, or 2. An advanced behavior setting for cases where tweens fail. See {@link com.mosesSupposes.fuse.ZigoEngine#SKIP_LEVEL} for details. In Fuse, this parameter also applies to the custom event parameter, although standard Fuse events like onComplete are not skipped.trigger May be set as seconds (see time formatting above) or set to true if in a group to indicate advance after the item trigger is grouped with.[ { start_alpha:0, seconds:.5, trigger:true}, { x:'100', seconds:3 } ]{ width:500, delay:1, seconds:2, trigger:1.5 }onComplete Fuse event is not fired until any trailing tweens from triggered actions finish.command String "start","stop","pause","resume","skipTo", or "setStartProps".{command:"start"} causes the Fuse to loop.command property may ONLY contain the additional properties: scope, args, label, delay.args are sent to the Fuse command, and scope is only used for runtime-evaluation of other params set to function (see "Runtime-evaluation" above).{ command:"skipTo", args:3 }, { command:"start", args:true }easyfunc Removed from kit. func, startfunc, updfunc parameters now accept easyfunc strings (see func above).var fuseA:Fuse = new Fuse();
* var fuseB:Fuse = new Fuse();
* var fuseC:Fuse = new Fuse();
* // .. build Fuses here then..
* // final action in fuseC will resume the master Fuse,
* fuseC.push({ scope:fuseA, func:"resume" });
* // .. somewhere in fuseA, begin the others & pause:
* fuseA.push([{scope:fuseB, func:"start"},
* {scope:fuseC, func:"start"} ]);
* fuseA.push({ command:"pause" }); // keep command in a separate action
* // .. continue pushing actions into fuseA here.
* // .. fuseA will resume when fuseC hits its final "resume" action.
* FuseItem.ADD_UNDERSCORES to false, your Fuse actions may
* optionally omit underscores for the known properties below, listed here without. For descriptions of
* ZigoEngine properties (shown in bold), look up their underscored counterparts in
* {@link com.mosesSupposes.fuse.ZigoEngine#doTween}.
* alphabrightOffsetbrightnesscolorResetcolorTransformcontrastfadeframeheightinvertColorrotationscalesizetinttintPercentvisiblewidthxxscaleyyscale
* myFuse.removeEventListener('onComplete',this);
* myFuse.destroy();
* delete myFuse;
*
* @see #autoClear
* @see #AUTOCLEAR
* @see #getInstance
*/
public function destroy():Void
{
if (Fuse.OUTPUT_LEVEL>1) FuseKitCommon.output(getHandle()+' destroy.');
this.stop(true);
splice(0,length);
_aDefaultTargs = null;
scope = null;
// required for stripping listeners. 0,7 is not a mistake - do not change
_global.ASSetPropFlags(this,null,0,7);
var id:Number = _nID;
for (var i:String in this) delete this[i];
removeInstanceAt(id, true);
delete id;
delete this;
}
/**
* Instance-management: Gets a Fuse instance by its id or label
* @description This simple method returns one known Fuse instance. For more complex options use {@link #getInstances}.
* @param idOrLabel Fuse's numerical {@link #id} or {@link #label} identifying a unique Fuse instance.
* @return a Fuse instance if found or null if not
* @see #getInstances
*/
public static function getInstance(idOrLabel:Object):Fuse
{
if (typeof idOrLabel=='number') return _aInstances[idOrLabel];
if (typeof idOrLabel=='string') {
for (var i:String in _aInstances) if (Fuse(_aInstances[i]).label==idOrLabel) return _aInstances[i];
}
return null;
}
/**
* Instance-management: Get an array of some or all Fuse instances in active memory, with filtering options.
* @description
* // get currently playing Fuses that handle the target my_mc
* var myMcFuses:Array = Fuse.getInstances("playing",my_mc);
*
* // get all the Fuses in active memory
* var fuses:Array = Fuse.getInstances();
* @param stateFilter nothing/null/{@link com.mosesSupposes.fuse.FuseKitCommon#ALL} for all Fuse instances in active memory, or a play state "playing", "stopped" or "paused"
* @param targets optional - a single target, an Array of targets, or a list of targets starting with the second param.
* @return an array containing one or more Fuse instances matching search criteria
* @see #getInstance
*/
public static function getInstances(stateFilter:String, targets:Object):Array
{
var all:Boolean = (stateFilter==null || (stateFilter.toUpperCase())=='ALL');
if (!(targets instanceof Array)) targets = arguments.slice(1);
var a:Array = [];
for (var i:String in _aInstances) {
var instance:Fuse = _aInstances[i];
if (_aInstances[i]==null) continue;
// if specified state does not match
if (all==false && instance.state!=stateFilter) continue;
// yes: state matches and no targets to filter by
var found:Boolean = (targets.length==0);
if (found==false) {
// AS2 bug, break does not work twice!
if (found==true) continue;
var instTargs:Array = instance.getActiveTargets(true);
for (var j:String in targets) {
for (var k:String in instTargs) {
// yes: a target passed in was found in the instance
if (instTargs[k]==targets[j]) {
found = true;
break;
}
}
}
}
if (found==true) a.unshift(instance);
}
return a;
}
/**
* Instance default: an auto-assigned numerical reference
* @return Internal id based on instance count.
* @see #label
* @see #getInstance
*/
public function get id():Number { return _nID; }
/**
* Retrieves a Fuse instance's current play-state string.
* @return "stopped", "playing", or "paused"
* @see #currentIndex
*/
public function get state():String
{
switch(_nState) {
case -1 : return 'stopped';
case 0 : return 'paused';
case 1 : return 'playing';
default : return undefined;
}
}
/**
* Retrieves the current play-index of a Fuse instance.
* @return A number starting at 0 for the first action
* @see #state
* @see #currentLabel
*/
public function get currentIndex():Number { return this._nIndex; }
/**
* Retrieves the currently playing action's label, if defined.
* @description { label:"introFade", start_alpha:0, start_brightOffset:100, time:1.5, ease:"easeInExpo" }
* @return A string set in the action object using the label property.
* @see #Fuse
* @see #label
* @see #state
* @see #currentIndex
*/
public function get currentLabel():String { return (this[_nIndex]).label; }
/**
* see set target
* @ignore
*/
public function get target():Object { return (_aDefaultTargs.length==1) ? _aDefaultTargs[0] : _aDefaultTargs; }
/**
* Instance default: Sets one or more animation targets that will be used for any actions that don't specify their own.
* @description Overwrites prior existing targets.
* var f:Fuse = new Fuse(); * f.target = [clip1, clip2];* @param one target or an array of targets * @return a single animation target if one is set or an Array of targets if more than one is set. * @see #addTarget * @see #removeTarget * @see #getActiveTargets */ public function set target(t:Object):Void { delete _aDefaultTargs; if (t!=null) { addTarget(t); } } /** * Adds to current default target list. * @description
myFuse.addTarget(clip5);* @param accepts one or more targets, or an array of targets * @see #target * @see #removeTarget * @see #getActiveTargets */ public function addTarget(t:Object):Void { if (_aDefaultTargs==null) this._aDefaultTargs = []; if (arguments[0] instanceof Array) arguments = arguments[0]; for (var i:String in arguments) { var found:Boolean = false; for (var j:String in _aDefaultTargs) { if (arguments[i]==_aDefaultTargs[j]) { found = true; break; } } if (found==false) _aDefaultTargs.push(arguments[i]); } } /** * Removes targets from the current default target list. * @description
myFuse.removeTarget(clip5);* @param accepts one or more targets, or an array of targets * @see #target * @see #addTarget * @see #getActiveTargets */ public function removeTarget(t:Object):Void { if (_aDefaultTargs==null || _aDefaultTargs.length==0) return; if (arguments[0] instanceof Array) arguments = arguments[0]; for (var i:String in arguments) { for (var j:String in _aDefaultTargs) { if (arguments[i]==_aDefaultTargs[j]) _aDefaultTargs.splice(Number(j),1); } } } /** * Gets both the default target list and any targets in the action currently being played. * @param includeDefaults If true is passed, list includes the Fuse instance's default target list plus active action targets. * @return Array of targets currently being handled by the playing or paused action, plus the Fuse instance's default target list if true was passed.
myFuse.push({ x:"100" }); // add an action to the beginning of the sequence
* @param fuseAction One or more generic "action" objects or arrays in Fuse Object Syntax starting at this argument
* @return New length of Fuse instance
* @see #push
* @see #pushTween
* @see #pop
* @see #shift
* @see #splice
* @see #slice
* @see #reverse
* @see #clone
*/
public function unshift(fuseAction:Object):Number
{
this.splice.apply(this, ((new Array(0, 0)).concat(arguments)));
return length;
}
/**
* Removes the first element from a Fuse and returns that action object.
* @return original object passed by user
* @see #push
* @see #pushTween
* @see #pop
* @see #unshift
* @see #splice
* @see #slice
* @see #reverse
* @see #clone
*/
public function shift():Object
{
var o:Object = FuseItem(this[0]).getInitObj();
this.splice(0, 1);
return o;
}
/**
* Used to insert or remove items. Works almost exactly like Array.splice. Removed actions are destroyed permanently, with the exception of nested Fuses.
* @usage myFuse.splice(0, 2); // remove two items from the beginning of the sequencemyFuse.splice(-2, 0, { x:"100" }); // insert an action two steps from the end of the sequence
* @param startIndex index in Fuse to begin removing objects
* @param deleteCount number of objects to delete from startIndex
* @param fuseAction One or more generic "action" objects or arrays in Fuse Object Syntax starting at this argument
* @see #push
* @see #pushTween
* @see #pop
* @see #unshift
* @see #shift
* @see #slice
* @see #reverse
* @see #clone
*/
public function splice(startIndex:Number, deleteCount:Number, fuseAction:Object):Void
{
this.stop(true);
var si:Number = Number(arguments.shift());
if (si<0) si = length+si;
deleteCount = Number(arguments.shift());
var newItems:Array = new Array();
for (var i:Number=0; istart_x in all or specific items.
* @description In this example a sequence is set up and all start props are set, although the Fuse may not be used until later.
* var f:Fuse = new Fuse();
* f.target = clip1;
* f.push({ start_alpha:0 }); // fade up
* f.push({ x:'100', start_scale:150}); // scale down and slide
* f.setStartProps();
* If you want to set start props as the Fuse is started, you can pass setStartProps parameters to {@link #start}.
* @param nothing/null/{@link com.mosesSupposes.fuse.FuseKitCommon#ALL} to set all start props in the Fuse.
* To specify some actions while excluding others, pass an array of item indices/labels or a series of indices/labels as separate parameters.
* @see #start
* @see #closeAndStart
*/
public function setStartProps(trueOrItemIDs:Object):Void
{
var all:Boolean = (arguments.length==0 || trueOrItemIDs===true || trueOrItemIDs==FuseKitCommon.ALL);
dispatchEvent({target:this,
type:'evtSetStart',
all:all,
filter:(trueOrItemIDs instanceof Array) ? trueOrItemIDs : arguments,
curIndex:((_nState==1) ? _nIndex : -1),
targs:_aDefaultTargs,
scope:scope});
}
/**
* Play-control: Begins sequence play at index 0, with option to set start props prior to play.
* @description In this example all start props are set during start by passing true.
* var f:Fuse = new Fuse();
* f.target = clip1;
* f.push({ start_alpha:0 }); // fade up
* f.push({ x:'100', start_scale:150}); // scale down and slide
* f.start(true);
* @param setStart A {@link #setStartProps} call is generated from all arguments before the Fuse begins playing.
* @see #stop
* @see #pause
* @see #resume
* @see #skipTo
* @see #fastForward
*/
public function start(setStart:Object):Void
{
close();
this.stop(true);
this._nState = 1;
if (length==0) {
advance(false,true,false); // fires onComplete, state must be playing
}
if (setStart!=null && setStart!=false){
setStartProps.apply(this,arguments);
}
dispatchEvent({target:this, type:'onStart'});
if (OUTPUT_LEVEL>1) FuseKitCommon.output(getHandle()+' start.');
playCurrentItem();
}
/**
* Play-control: Stops a playing or paused Fuse instance and resets the play-index to 0.
* @see #start
* @see #pause
* @see #resume
* @see #skipTo
* @see #fastForward
*/
public function stop():Void
{
if(_nState!=-1) {
for (var i:Number=0; ivar f:Fuse = new Fuse();
* f.target = clip1;
* f.push({ start_alpha:0 });
* f.push({ x:'100', label:"slideRight"});
* //later...
* f.skipTo("slideRight"); // same as f.skipTo(1);
* @param indexOrLabel numerical item index or label string. Pass a negative index to count back from end, like -1 for last item.
* @see #start
* @see #stop
* @see #pause
* @see #resume
* @see #fastForward
*/
public function skipTo(indexOrLabel:Object):Void
{
close();
var index:Number = normalizeIndex(indexOrLabel);
if (index==null) {
if (OUTPUT_LEVEL>0) FuseKitCommon.error('102','skipTo',String(indexOrLabel));
return;
}
// hidden second arg passed by FuseItem
if (index==_nIndex && arguments[1]===true) {
if (OUTPUT_LEVEL>0) FuseKitCommon.error('103',String(indexOrLabel),_nIndex);
}
if ((this[_nIndex]) instanceof Fuse) {
Fuse(this[_nIndex]).removeEventListener('onComplete', _oDel1);
}
// (Item will be replayed if skipTo called on current item)
this.stop(true);
_nIndex = index;
var s:Number = _nState;
this._nState = 1;
// skipTo is being used to start the Fuse
if (s==-1) dispatchEvent({target:this, type:'onStart'});
playCurrentItem();
if (OUTPUT_LEVEL>1) FuseKitCommon.output('skipTo:'+index);
}
/**
* Play-control: Pauses a playing Fuse instance and its running tweens. Waits for {@link #resume} call to proceed.
* @see #start
* @see #stop
* @see #resume
* @see #skipTo
* @see #fastForward
*/
public function pause():Void
{
if(_nState==1){
for (var i:Number=0; i<=_nIndex; i++) {
if ((this[i]).state==='playing' || (this[i])._nPlaying>0) {
(this[i]).pause(); // do not cast
}
}
if (_nTimeCache!=-1) {
// remaining time in delay
_nTimeCache -= getTimer();
clearInterval(_nDelay);
}
this._nState = 0;
if (OUTPUT_LEVEL>1) FuseKitCommon.output(getHandle()+' pause.');
dispatchEvent({target:this, type:'onPause'});
}
}
/**
* Resumes a paused Fuse instance and its animations. Attempts to correct for animations that have been disrupted during pause.
* @see #start
* @see #stop
* @see #pause
* @see #skipTo
* @see #fastForward
*/
public function resume():Void
{
if (_nState!=0) return; // Behavior change from 1.0: only accept resume calls if paused!
close();
this._nState = 1;
if (OUTPUT_LEVEL>1) FuseKitCommon.output(getHandle()+' resume.');
dispatchEvent({target:this, type:'onResume'});
if (_nTimeCache!=-1) {
playCurrentItem(false, true);
}
// resume
for (var i:Number=0; i<=_nIndex; i++) {
if ((this[i]) instanceof Fuse && (this[i]).state=='paused') {
Fuse(this[i]).resume();
}
else if ((this[i])._nPlaying==0) {
FuseItem(this[i]).pause(true);
}
}
}
/**
* Fast-forwards animations in some or all remaining actions.
* @description Behavior:
* // fast-forward all animations and end fuse:
* myFuse.fastForward();
*
* // fast-forward from current index and resume play at index 8
* myFuse.fastForward(8);
*
* // fast-forward then resume at a labeled action like { x:"100", label:"slider" }
* myFuse.fastForward("slider");
*
* // fast-forward but play final action
* myFuse.fastForward(-1);
*
* The following example demonstrates fast-forwarding to an index within a nested Fuse instance, and also shows
* how a nested Fuse's label property can be used to fast-forward to. Note that the fast-forward commands could
* alternatively be written using positive or negative integers as in the examplese above.
* var nestedFuse1:Fuse = new Fuse(
* { rotation:180, label:"spin" },
* { tint:0x33FF00, tintPercent:50, label:"tint" }
* );
* nestedFuse1.label = "NF1";
* nestedFuse1.target = clip1_mc;
*
* var mainFuse:Fuse = new Fuse(
* { x:"100", label:"slideRight" },
* nestedFuse1,
* { x:"-100", label:"slideLeft" }
* );
* mainFuse.target = clip1_mc;
* mainFuse.start();
*
* // fast-forward to the "tint" action by using two fastForward calls.
* mainFuse.fastForward("NF1"); // first jump to the nested Fuse using its label
* nestedFuse1.fastForward("tint"); // then jump to the tint action using its label
*
* @param resumeAtIndexOrLabel Numerical item index or label string to fast-forward up to and resume playing at.startItem() in currently active item.
* @param postDelay true is sent when a delay has completed.
* @param delay force a delay to play, such as during resume
*/
private function playCurrentItem(postDelay:Boolean, resumeDelay:Boolean):Void
{
clearInterval(_nDelay);
if (postDelay!=true || resumeDelay==true) {
var d:Number = 0;
if (resumeDelay!=true) { // updated v2.1.2, plus pause & resume methods: improved standalone delay + callback, including trailing tweens overlapping
d = (FuseItem(this[_nIndex]).evalDelay(scope) || 0) * 1000;
}
if (d>0 || resumeDelay==true) {
if (resumeDelay==true) {
d = _nTimeCache;
this._nTimeCache += getTimer();
} else {
var multiplier:Number = Math.abs(_global.com.mosesSupposes.fuse.ZigoEngine.TIME_MULTIPLIER);
if (_global.isNaN(multiplier)==true) multiplier = 1;
d *= multiplier;
this._nTimeCache = (getTimer() + d);//used during pause.
}
this._nDelay = setInterval(this, 'playCurrentItem', d, true);
return;
}
}
_nTimeCache = _nDelay = -1;
if ((this[_nIndex]) instanceof Fuse) {
if (_oDel1==null) _oDel1 = Delegate.create(this,advance);
Fuse(this[_nIndex]).addEventListener('onComplete', _oDel1);
Fuse(this[_nIndex]).start(_aDefaultTargs, scope);
}
else {
var propsTweened:String = (FuseItem(this[_nIndex]).startItem(_aDefaultTargs, scope, duration, easing));
if (Fuse.OUTPUT_LEVEL>1) FuseKitCommon.output(getHandle()+' props tweened: '+propsTweened);
}
}
/**
* Nested instances receive this event
* @param event object
*/
private function evtSetStart(o:Object):Void
{
setStartProps.apply(this, o.filter);
}
/**
* Simple Syntax:Generate a new Fuse and begin intercepting tween calls until {@link com.mosesSupposes.fuse.Fuse#close} is called.
* @description Simple Syntax is an alternative way to construct Fuse sequences.
* Its primary uses are 1. Clear method-call sequencing and 2. An easy way for non-advanced coders to set up sequences.
* @usage
*
* // Example 1: Can be used to enforce a clear, strict order of timed events
* Fuse.open();
* Fuse.addCommand (mainMenu, "draw", menuXML);
* Fuse.addCommand ("delay", .5);
* Fuse.addCommand (contentPage, "loadContent", firstItem);
* Fuse.addCommand (screenDisplay, "exposeLayout");
* Fuse.addCommand ("delay", 2);
* Fuse.addCommand (this, "onResize");
* Fuse.addCommand (Logger, "output", "Setup sequence complete.", 0);
* Fuse.close();
*
* // Example 2: Simple Syntax with shortcut tweens
* Fuse.open();
* box_mc.slideTo(150,150, 1);
* Fuse.openGroup();
* box_mc.scaleTo(250, 1);
* box_mc.brightnessTo(-50, 2);
* Fuse.closeGroup();
* box_mc.colorTo(0x6633FF, 1);
* Fuse.closeAndStart();
*
* var f:Fuse = Fuse.open(); // store a reference to the Fuse
* // later...
* Fuse.open(f); // reopen existing
* // or...
* Fuse.open(0); // open Fuse with id 0
* // or...
* Fuse.open("introSequence"); // open Fuse with the label "introSequence"
* Fuse.openGroup(); can be called in place of Fuse.open();.Fuse.openGroup(); is called while a previous group was open, the preceding group is closed automatically.
* // use in place of Fuse.open() to begin a new Fuse.
* Fuse.openGroup();
* clip1.tween("_x","100");
* clip2.tween("_scale",200);
* Fuse.openGroup(); // you can skip closeGroup if opening another group.
* clip1.tween("_x","-100");
* clip2.tween("_scale",100);
* Fuse.closeAndStart(); // you can skip closeGroup here too.
*
* @param fuseOrID:Fuse (Optional) an existing Fuse or Fuse's id or label in which to open the new group.
* @return The currently open fuse instance or a new Fuse if openGroup was called prior to open().
* @see #open
* @see #closeGroup
* @see #close
* @see #closeAndStart
* @see #startRecent
* @see #addCommand
* @see #id
* @see #label
*/
public static function openGroup(fuseOrID:Object):Fuse
{
// allow openGroup() to open a new sequence.
if (!(_oBuildMode!=null && _oBuildMode.curID>-1)) open(fuseOrID);
else if (_oBuildMode.curGroup!=null) closeGroup();
_oBuildMode.curGroup = new Array();
return getInstance(_oBuildMode.curID);
}
/**
* Simple Syntax: Closes an action group started by {@link #openGroup}.
* @description May be omitted if followed by Fuse.close or Fuse.closeAndStart.Fuse.openGroup() is called while a previous group was open, the preceding group is closed automatically and the closeGroup command can be skipped.
* Fuse.open();
* clip1.tween("_x","100");
* Fuse.openGroup();
* clip1.tween("_x","-100");
* clip2.tween("_scale",200);
* Fuse.closeGroup();
* clip1.scaleTo(0);
* clip2.scaleTo(0);
* Fuse.closeAndStart();
* @see #open
* @see #openGroup
* @see #close
* @see #closeAndStart
* @see #startRecent
* @see #addCommand
*/
public static function closeGroup():Void
{
if (_oBuildMode.curGroup==null || !(_oBuildMode!=null && _oBuildMode.curID>-1)) return;
getInstance(_oBuildMode.curID).push(_oBuildMode.curGroup);
_oBuildMode.curGroup = null;
}
/**
* Simple Syntax: Completes the Fuse generated by {@link com.mosesSupposes.fuse.Fuse#open}.
* @description It is important that you complete each Fuse created using Fuse.open() using either Fuse.close() or Fuse.closeAndStart(). You cannot call start on a Fuse instance while Fuse is open.
* var runSetup:Fuse = Fuse.open();
* Fuse.addCommand(this, "callbackOne");
* Fuse.addCommand("delay", .25);
* Fuse.addCommand(this, "callbackTwo");
* Fuse.addCommand("delay", .25);
* Fuse.addCommand(this, "callbackThree");
* Fuse.close();
*
* // later in program...
* runSetup.start(); // reference the Fuse created
*
* @see #open
* @see #openGroup
* @see #closeGroup
* @see #closeAndStart
* @see #startRecent
* @see #addCommand
*/
public static function close():Void
{
if (!(_oBuildMode!=null && _oBuildMode.curID>-1)) return;
if (_oBuildMode.curGroup!=null) closeGroup();
_oBuildMode.curID = -1;
}
/**
* Simple Syntax: Close the open Fuse instance and start it playing.
* @description var runSetup:Fuse = Fuse.open(); * clip1.fadeOut(); * clip2.fadeOut(); * clip3.fadeOut(); * Fuse.closeAndStart();* @param setStart A {@link #setStartProps} call is generated from all arguments before the Fuse begins playing. * @see #open * @see #openGroup * @see #closeGroup * @see #close * @see #startRecent * @see #addCommand */ public static function closeAndStart(setStart:Object):Void { if (!(_oBuildMode!=null && _oBuildMode.curID>-1)) return; var f:Fuse = getInstance(_oBuildMode.curID); close(); f.start.apply(f, arguments); } /** * Simple Syntax: Restarts the Fuse most recently created using Fuse.{@link #open}(). * @param setStart A {@link #setStartProps} call is generated from all arguments before the Fuse begins playing. * @see #open * @see #openGroup * @see #closeGroup * @see #close * @see #closeAndStart * @see #addCommand */ public static function startRecent(setStart:Object):Void { var f:Fuse = getInstance(_oBuildMode.prevID); if (f!=null) f.start.apply(f, arguments); else FuseKitCommon.error('108'); } /** * Multi-purpose method for all non-animation Simple Syntax features. * @usage
var f:Fuse = new Fuse();
*
* // callback: scope, func, args
* Fuse.addCommand(this, "setItemData", 0, "Submit", true);
*
* // delay
* Fuse.addCommand("delay", .5);
*
* // inline Fuse play-command:
* // this final action will cause the Fuse to loop
* Fuse.addCommand("start");
*
* // advance-trigger (should appear within group)
* Fuse.addCommand("trigger", .5);
*
* @description Some addCommand calls are allowed inside groups ('delay','trigger', function-calls),
* but most are not. For instance if you want to have a Fuse pause itself, place the command
* Fuse.addCommand('pause'); outside any Fuse.openGroup(); blocks.
*
The 'trigger' feature should appear within groups and adds powerful flexibility for animators:
*
Just as delays can stagger the start times of grouped tweens, triggers allow the ends of grouped animations
* to overlap with the following action by advancing the action early. For example if an action contains two tweens,
* the longest of which is 2 seconds plus a 1-second delay, including Fuse.addCommand("trigger", 2.5);
* in the group would advance the Fuse to the next action half a second before the running tweens complete.
* This adds timeline-like flexibility and helps you keep your sequences less rigid.
*
* @param commandOrScope Accepts: 'delay','trigger','start','stop','pause','resume','skipTo','setStartProps' or in the case of a function-call a scope such as this.
* @param indexOrFunc Varies based on first argument: 'delay', 'trigger' : Number of seconds. 'skipTo': Destination index (starting at 0 for the first action).
* For function-call, a string of the function name such as 'trace'.
* @param argument Function-call: Any number of arguments can follow and will be passed during the call.
* @see #open
* @see #openGroup
* @see #closeGroup
* @see #close
* @see #closeAndStart
* @see #startRecent
*/
public static function addCommand(commandOrScope:Object, indexOrFunc:Object, argument:Object):Void
{
if (!(_oBuildMode!=null && _oBuildMode.curID>-1)) return;
var inGroup:Boolean = (_oBuildMode.curGroup!=null);
var into:Array = (inGroup==true) ? _oBuildMode.curGroup : getInstance(_oBuildMode.curID); // allow some addCommands within groups
if (typeof commandOrScope=='string') { // assume it's a command
var hasArg:Boolean = (indexOrFunc!=undefined);
var valid:Boolean = FuseKitCommon._validateFuseCommand(String(commandOrScope), inGroup, hasArg, OUTPUT_LEVEL, true);
if (valid==true) {
into.push({__buildMode:true, command:commandOrScope, commandargs:indexOrFunc});
}
}
else {
// assume it's a function-call
into.push({__buildMode:true, scope:commandOrScope, func:indexOrFunc, args:arguments.slice(2)});
}
}
// -- internal --
/**
* @exclude
* Internal use only. This is the method ZigoEngine uses to route tween calls into an open Fuse instance after Fuse.open().
* @return true if Fuse is in build-mode
*/
public static function addBuildItem(args:Array):Boolean
{
if (!(_oBuildMode!=null && _oBuildMode.curID>-1)) return false;
var into:Array = (_oBuildMode.curGroup!=null) ? _oBuildMode.curGroup : getInstance(_oBuildMode.curID);
if (args.length==1 && typeof args[0]=='object') {
// Object syntax can be mixed with simple syntax by using Fuse.open(); with commands like my_mc.tween({x:'100'});
into.push(args[0]);
}
else {
into.push({__buildMode:true, tweenargs:args});
}
return true;
}
/**
* @param indexOrLabel numerical item index or label string. Pass a negative index to count back from end, like -1 for last item.
* @return index, or null indicating failure.
*/
private function normalizeIndex(indexOrLabel:Object):Number
{
var index:Number;
if (typeof indexOrLabel=='string') {
index = -1;
for (var i:Number=0; i