📄 interpolator.as
字号:
package flare.animate.interpolate
{
import flare.util.Property;
import flash.utils.getDefinitionByName;
import flash.utils.getQualifiedClassName;
/**
* Base class for value interpolators. This class also provides factory
* methods for creating concrete interpolator instances -- see the
* <code>create</code> method for details about interpolator creation.
*/
public class Interpolator
{
/** The target object whose property is being interpolated. */
protected var _target:Object;
/** The property to interpolate. */
protected var _prop:Property;
/**
* Base constructor for Interpolator instances.
* @param target the object whose property is being interpolated
* @param property the property to interpolate
* @param value the target value of the interpolation
*/
public function Interpolator(target:Object, property:String,
start:Object, end:Object)
{
reset(target, property, start, end);
}
/**
* Re-initializes an exising interpolator instance.
* @param target the object whose property is being interpolated
* @param property the property to interpolate
* @param value the target value of the interpolation
*/
public function reset(target:Object, property:String,
start:Object, end:Object):void
{
_target = target;
_prop = Property.$(property);
init(start, end);
}
/**
* Performs initialization of an interpolator, typically by
* initializing the start and ending values. Subclasses should
* override this method for custom initialization.
* @param value the target value of the interpolation
*/
protected function init(start:Object, end:Object) : void
{
// for subclasses to override
}
/**
* Calculate and set an interpolated property value. Subclasses should
* override this method to implement custom interpolation routines.
* @param f the interpolation fraction (typically between 0 and 1)
*/
public function interpolate(f:Number) : void
{
throw new Error("This is an abstract method");
}
// -- Interpolator Factory --------------------------------------------
private static var _maxPoolSize:int = 10000;
private static var _pools:Object = [];
private static var _lookup:Object = buildLookupTable();
private static var _rules:Array = buildRules();
private static function buildLookupTable() : Object
{
// add variables to ensure classes are included by compiler
var ni:NumberInterpolator;
var di:DateInterpolator;
var pi:PointInterpolator;
var ri:RectangleInterpolator;
var mi:MatrixInterpolator;
var ai:ArrayInterpolator;
var ci:ColorInterpolator;
var oi:ObjectInterpolator;
// build the value->interpolator lookup table
var lut:Object = new Object();
lut["Number"] = "flare.animate.interpolate::NumberInterpolator";
lut["int"] = "flare.animate.interpolate::NumberInterpolator";
lut["Date"] = "flare.animate.interpolate::DateInterpolator";
lut["Array"] = "flare.animate.interpolate::ArrayInterpolator";
lut["flash.geom::Point"] = "flare.animate.interpolate::PointInterpolator";
lut["flash.geom::Rectangle"] = "flare.animate.interpolate::RectangleInterpolator";
lut["flash.geom::Matrix"] = "flare.animate.interpolate::MatrixInterpolator";
return lut;
}
private static function buildRules() : Array
{
var rules:Array = new Array();
rules.push(isColor);
return rules;
}
private static function isColor(target:Object, property:String, s:Object, e:Object)
: String
{
return property.indexOf("Color")>=0 || property.indexOf("color")>=0
? "flare.animate.interpolate::ColorInterpolator"
: null;
}
/**
* Extends the interpolator factory with a new interpolator type.
* @param valueType the fully qualified class name for the object type
* to interpolate
* @param interpType the fully qualified class name for the
* interpolator class type
*/
public static function addInterpolatorType(valueType:String, interpType:String) : void
{
_lookup[valueType] = interpType;
}
/**
* Clears the lookup table of interpolator types, removing all
* type to interpolator mappings.
*/
public static function clearInterpolatorTypes():void
{
_lookup = new Object();
}
/**
* Adds a rule to the interpolator factory. The input function should
* take 4 arguments -- a target object, property name string, a
* starting value, and a target value -- and either return a fully
* qualified class name for the type of interpolator to use, or null if
* this rule does not apply.
* @param f the rule function for supplying custom interpolator types
* based on contextual conditions
*/
public static function addInterpolatorRule(f:Function):void
{
_rules.push(f);
}
/**
* Clears all interpolator rule functions from the interpolator
* factory.
*/
public static function clearInterpolatorRules():void
{
_rules = new Array();
}
/**
* Returns a new interpolator instance for the given target object,
* property name, and interpolation target value. This factory method
* follows these steps to provide an interpolator instance:
* <ol>
* <li>The list of installed interpolator rules is consulted, and if a
* rule returns a non-null class name string, an interpolator of
* that type will be returned.</li>
* <li>If all rules return null values, then the class type of the
* interpolation value is used to look up the appropriate
* interpolator type for that value. If a matching interpolator
* type is found, an interpolator is initialized and returned.
* </li>
* <li>If no matching type is found, a default ObjectInterpolator
* instance is initialized and returned.</li>
* </ol>
*
* <p>By default, the interpolator factory contains two rules. The
* first rule returns the class name of ColorInterpolator for any
* property names containing the string "color" or "Color". The second
* rule returns the class name of ObjectInterpolator for the property
* name "shape".</p>
*
* <p>The default value type to interpolator type mappings are:
* <ul>
* <li><code>Number -> NumberInterpolator</code></li>
* <li><code>int -> NumberInterpolator</code></li>
* <li><code>Date -> DateInterpolator</code></li>
* <li><code>Array -> ArrayInterpolator</code></li>
* <li><code>flash.geom.Point -> PointInterpolator</code></li>
* <li><code>flash.geom.Rectangle -> RectangleInterpolator</code></li>
* </ul>
* </p>
*
* <p>The interpolator factory can be extended either by adding new
* interpolation rule functions or by adding new mappings from
* interpolation value types to custom interpolator classes.</p>
*/
public static function create(target:Object, property:String,
start:Object, end:Object): Interpolator
{
// first, check the rules list for an interpolator
var name:String = null;
for (var i:uint=0; name==null && i<_rules.length; ++i) {
name = _rules[i](target, property, start, end);
}
// if no matching rule, use the type lookup table
if (name == null) {
name = _lookup[getQualifiedClassName(end)];
}
// if that fails, use ObjectInterpolator as default
if (name == null) {
name = "flare.animate.interpolate::ObjectInterpolator";
}
// now create the interpolator, recycling from the pool if possible
var pool:Array = _pools[name] as Array;
if (pool == null || pool.length == 0) {
// nothing in the pool, create a new instance
var Ref:Class = getDefinitionByName(name) as Class;
return new Ref(target, property, start, end) as Interpolator;
} else {
// reuse an interpolator from the object pool
var interp:Interpolator = pool.pop() as Interpolator;
interp.reset(target, property, start, end);
return interp;
}
}
/**
* Reclaims an interpolator for later recycling. The reclaimed
* interpolator should not be in active use by any other classes.
* @param interp the Interpolator to reclaim
*/
public static function reclaim(interp:Interpolator):void
{
var type:String = getQualifiedClassName(interp);
var pool:Array = _pools[type] as Array;
if (pool == null) {
_pools[type] = [interp];
} else if (pool.length < _maxPoolSize) {
pool.push(interp);
}
}
} // end of class Interpolator
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -