topical media & game development

talk show tell print

lib-flex-animation-code-10-org-as3lib-kitchensync-action-KitchenSyncObjectParser.ax

lib-flex-animation-code-10-org-as3lib-kitchensync-action-KitchenSyncObjectParser.ax (swf ) [ flash ] flex


  package org.as3lib.kitchensync.action
  {
          import org.as3lib.kitchensync.KitchenSyncDefaults;
          import org.as3lib.kitchensync.action.tweentarget.*;
          
          public class @ax-lib-flex-animation-code-10-org-as3lib-kitchensync-action-KitchenSyncObjectParser implements ITweenObjectParser {
                  
                  public static const TARGET:String                         = "target";
                  public static const TARGETS:String                         = "targets";
                  public static const DURATION:String                        = "duration";
                  public static const DELAY:String                         = "delay";
                  public static const EASING_FUNCTION:String        = "easingFunction";
                  public static const EASING_MOD1:String                = "easingMod1";
                  public static const EASING_MOD2:String                = "easingMod2";
                  public static const PROPERTIES:String                = "properties";
                  public static const SYNC:String                                = "sync";
                  public static const SNAP_TO_WHOLE:String        = "snapToWholeNumbers"; 
                  public static const SNAP_TO_VALUE:String        = "snapToValueOnComplete";
                  
                  private static const PROP_DELIMITER:RegExp = /\s*,\s*/;
                  private static const PROP_VALUE_DELIMITER:RegExp = /\s*(=|:)\s*/;
                  private static const VALUE_RANGE_DELIMITER:RegExp = /\s*[~]\s*/;
                  private static const START_VALUE_MARKER:RegExp = /(_start|Start|_from|From)/;
                  private static const END_VALUE_MARKER:RegExp = /(_end|End|_to|To)/;
                  
                  public function get keywords():Array
                  {
                          return _keywords;
                  }
                  
                  protected var _keywords:Array = [
                          TARGET, TARGETS, PROPERTIES,
                          DURATION, DELAY,
                          EASING_FUNCTION, EASING_MOD1, EASING_MOD2,
                          SYNC, SNAP_TO_VALUE, SNAP_TO_WHOLE
                  ];
                  
                  public function parseObject(parameters:Object):ITween {
                          // set up initial tween.
                          var tween:KSTween = new KSTween();
                          
                          tween.duration = parseDuration(parameters);
                          tween.delay = parseDelay(parameters);
                          tween.easingFunction = parseEasingFunction(parameters);
                          tween.sync = parseSync(parameters);
                          
                          
                          var mod1:* = parseMod1(parameters);
                          var mod2:* = parseMod2(parameters);
  
                          if (mod1) { tween.easingMod1 = mod1; }
                          if (mod2) { tween.easingMod2 = mod2; }
                          
                          var targets:Array = parseTargets(parameters);
                          //trace("targets:",targets);
                          var properties:Array = [];
                          var explicitProperties:Array = parseProperties(parameters);
                          var stringProperties:Array = parsePropertiesString(parameters);
                          properties = properties.concat(explicitProperties, stringProperties);
                          trace("properties (" + properties.length + "):",properties);
                          
                          var i:int, j:int;
                          var target:Object;
                          var propertyData:PropertyData;
                          var tweenTarget:ITweenTarget;
                          
                          for (i = 0; i < targets.length; i ++) {
                                  target = targets[i];
                                  for (j = 0; j < properties.length; j++) {
                                          propertyData = properties[j] as PropertyData;
                                          if (propertyData != null) {
                                                  tweenTarget = new TargetProperty(
                                                                                  target, 
                                                                                  propertyData.propertyName,
                                                                                  propertyData.startValue,
                                                                                  propertyData.endValue
                                                                            );
                                                                                                                  
                                                  tween.addTweenTarget(tweenTarget);
                                          }
                                  }
                          } 
                          
                          return tween;
                  }
                  
                  private function parseTargets(parameters:Object):Array {
                          // extract raw data.
                          var targets:Array, target:Object;
                          
                          targets = getFirstDefinedValue(parameters, "targets") as Array;
                          // determine which value to use.
                          if (targets != null && targets.length > 0) {
                                  return targets;
                          } 
                          
                          target = getFirstDefinedValue(parameters, "target") as Object;
                          if (target != null) {
                                  return [target];
                          }
                          throw new SyntaxError("At least one target must be defined");
                  }
                  
                  private function parseSync(parameters:Object):Boolean {
                          var sync:Object = getFirstDefinedValue(parameters, "sync") as Boolean;
                          if (sync != null) {
                                  return sync as Boolean;
                          }
                          return KitchenSyncDefaults.sync;
                  }
                  
                  private function parseEasingFunction(parameters:Object):Function {
                          var easingFunction:Function = getFirstDefinedValue(parameters, "easingFunction", "easing", "ease") as Function;
                          if (easingFunction != null) {
                                  return easingFunction;
                          }
                          return null;
                  }
                  
                  private function parseDuration(parameters:Object):* {
                          var duration:* = getFirstDefinedValue(parameters, "duration");
                          if (isNaN(duration)) {
                                  if (duration == null) {
                                          // default to 1 second
                                          return 1000;
                                  }
                          } 
                          return duration;
                  }
  
                  private function parseDelay(parameters:Object):* {
                          var delay:* = getFirstDefinedValue(parameters, "delay", "offset");
                          return delay;
                  }
                  
                  
                  private function parseProperties(paramerters:Object):Array {
                          var resultsArray:Array = new Array();
                          var property:String;
                          var startValue:Number;
                          var endValue:Number;
                          
                          for (var key:String in paramerters) {
                                  if (keywords.indexOf(key) < 0) {
                                          var data:PropertyData = new PropertyData();
                                          // check for ~ notation 
                                          var string:String = paramerters[key].toString();                                
                                          if (string.search("~") >= 0) {
                                                  var values:Array = string.split("~");
                                                  data.propertyName = key;
                                                  data.startValue = values[0];
                                                  data.endValue = values[1];
                                          } else {
                                                  // check for _start / _end notation.
                                                  var startStringIndex:int = key.search(START_VALUE_MARKER);
                                                  var endStringIndex:int = key.search(END_VALUE_MARKER);
                                                  if (startStringIndex >= 0) {
                                                          data.propertyName = key.slice(0, startStringIndex);
                                                          data.startValue = paramerters[key] as Number; 
                                                          data.endValue = getFirstDefinedValue(paramerters,         data.propertyName + "_end", 
                                                                                                                                                                  data.propertyName + "End",
                                                                                                                                                                  data.propertyName + "_to",
                                                                                                                                                                  data.propertyName + "To") as Number;
                                                          if (isNaN(data.endValue)) {
                                                                  data.endValue = KSTween.VALUE_AT_START_OF_TWEEN;
                                                          }
                                                          
                                                          resultsArray.push(data);
                                                          continue;
                                                  } else {
                                                          // ignore it.
                                                          continue;
                                                  }
                                          } 
                                          // check results for keywords.
                                          switch (data.propertyName) {
                                                  case "scale":
                                                          resultsArray.push(new PropertyData("scaleX", data.startValue, data.endValue));
                                                          resultsArray.push(new PropertyData("scaleY", data.startValue, data.endValue));
                                                  break;
                                                  
                                                  default:
                                                          // push results onto array to later be converted into tween targets.
                                                          resultsArray.push(data);
                                          }
                                  }
                          }
                          return resultsArray;
                  }
                  
                  private function parsePropertiesString(parameters:Object):Array {
                          var property:PropertyData;
                          var resultsArray:Array = [];
                          
                          var allPropsString:String = getFirstDefinedValue(parameters, "properties", "property") as String;
                          if (allPropsString == null) { return null; }
                          
                          var properties:Array = allPropsString.split(PROP_DELIMITER);
                          var singleProperty:String;
                          var values:String;
                          /* 
                          for (var key:String in parameters) {
                                  if (keywords.indexOf(key) < 0) {
                                          // if key isn't a keyword
                                          var startStringIndex:int = key.search(START_VALUE_MARKER);
                                          if (startStringIndex >= 0) {
                                                  var propertyName:String = key.slice(0, startStringIndex);
                                                  var startValue:Number = parameters[key] as Number; 
                                                  var endValue:Number = getFirstDefinedValue(parameters, propertyName + "_end", propertyName + "End") as Number;
                                                  resultsArray.push(new PropertyData(propertyName, startValue, endValue));
                                          } else {
                                                  var propertyName:String = key;
                                                  var values:String = parameters[key].toString();
                                                  var startValue:Number = values.split(VALUE_RANGE_DELIMITER)[0];
                                                  var endValue:Number = values.split(VALUE_RANGE_DELIMITER)[1];
                                          }
                                  }
                          } */
                          
                          for each (singleProperty in properties) {
                                  property = new PropertyData();
                                  property.propertyName = singleProperty.split(PROP_VALUE_DELIMITER)[0];
                                  values = singleProperty.split(PROP_VALUE_DELIMITER)[2]; 
                                  if (values.search(VALUE_RANGE_DELIMITER) < 0) {
                                          property.startValue = KSTween.VALUE_AT_START_OF_TWEEN;
                                          property.endValue = Number(values);
                                  } else {
                                          property.startValue = Number(values.split(VALUE_RANGE_DELIMITER)[0]);
                                          property.endValue = Number(values.split(VALUE_RANGE_DELIMITER)[1]);
                                  }
                                  
                                  switch (property.propertyName) {
                                          case "scale":
                                                  resultsArray.push(new PropertyData("scaleX", property.startValue, property.endValue));
                                                  resultsArray.push(new PropertyData("scaleY", property.startValue, property.endValue));
                                          break;
                                          
                                          default:
                                                  resultsArray.push(property);
                                  }
                          }
                          return resultsArray;
                  }
                  
                  private static function parseMod1(parameters:Object):Number {
                          var mod1:Number = getFirstDefinedValue(parameters, "easingMod1", "mod1") as Number;
                           return mod1;
                  }
                  private static function parseMod2(parameters:Object):Number {
                          var mod2:Number = getFirstDefinedValue(parameters, "easingMod2", "mod2") as Number;
                           return mod2;
                  }
                  
                  
Returns the first defined variable within an object. Used when you need to access a value that may have multiple aliases. The values will be checked in order that they are entered.
parameter: object The object to check for values.
parameter: keys The remaining parameters will be strings of property names to check for valid values.
returns: the value of the first defined property or null if all were undefined.

  
                  private static function getFirstDefinedValue(object:Object, ... keys):* {
                          var key:String, value:*, i:int;
                          for (i = 0; i < keys.length; i++) {
                                  key = keys[i];
                                  value = object[key] as Object;
                                  if (value != null && value != undefined)  {
                                          return value;
                                  }
                          }
                          return null;
                  }
          }
  }
          
  internal class PropertyData {
          public var propertyName:String;
          public var startValue:Number;
          public var endValue:Number;
          
          public function PropertyData(propertyName:String = "", startValue:Number = NaN, endValue:Number = NaN) {
                  this.propertyName = propertyName;
                  this.startValue = startValue;
                  this.endValue = endValue;
          }
          
          public function toString():String { return propertyName + ":" + startValue + "~" + endValue }
  }


(C) Æliens 19/08/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.