uxebu/bonsai — pull request #106 by padolsey (2012-10-04 19:28:41+00:00)
Title: Animation Refactor

This pull request includes various changes to the animation APIs in bonsai.

The aim was to simplify and generalise the Animation APIs.

#### Animation class destroyed

The Animation class now only exists as a convenience factory for `KeyframeAnimation`.

`new Animation` now returns a single-phase `KeyframeAnimation` instance. So, animations are really just keyframe animations now.

#### Strategies removed

Previously we supported strategies such as `prop`, `attr` or custom strategies supplying `get` and `set` methods (these were used by the Animation to apply animated values to subjects). The support for strategies has now been **removed**.

`KeyframeAnimation` now supports a single way of setting and getting properties from subjects: the `attr` method. This is our main use-case (animating DisplayObject) and if you need to you can still create any arbitrary animation as long as you provide the `attr` method. See [this example](https://gist.github.com/3835790).

#### New `PropertyTween` class

This takes care of tweening a single property like `x` or `fillColor` or `width`. The `PropertyTween` applies the *optional* passed translator to the values. A translator is used to split a property value into its component parts (e.g. `fillColor` -> `r,g,b,a`) and then back to its true type on each `at()` call (after actual tweening).

PropertyTween example:

```js
var p = new PropertyTween(0, 50);
p.at(0); // => 0
p.at(0.5); // => 25
p.at(0.8); // => 40
p.at(1); // => 50
```

With a translator:

```js
var colorTranslator = {
toNumeric: function(c) {
return [c.r(), c.g(), c.b(), c.a()];
},
toUnique: function(n) {
return new color.RGBAColor(n[0], n[1], n[2], n[3]);
}
};
var tween = new PropertyTween(color('red'), color('blue'), colorTranslator);

tween.at(0); // RGBAColor instance
tween.at(0).rgba(); // => "rgba(255,0,0,1)" (red)
tween.at(0.5).rgba(); // => "rgba(128,0,128,1)" (purple)
tween.at(1).rgba(); // => "rgba(0,0,255,1)" (blue)
```

#### New `PropertiesTween` class

This takes care of tweening multiple properties. To do this it instantiates a
`PropertyTween` instance for each individual property.

The `PropertiesTween#at` method will return a whole object containing all values
at the passed progress. E.g.

```js
var p = new PropertiesTween({x: 0}, {x: 1000});

p.at(0).x; // => 0
p.at(0.1).x; // => 100
p.at(0.5).x; // => 500
```

It also handles all of the default translators we have. Currently we have
translators for these properties:

* fillColor
* strokeColor
* fillGradient
* strokeGradient
* matrix
* filters
* segments [used for morphing]
* cornerRadius [array of radiuses for Rect]

So, if I pass any of those properties, translation will be done automatically.
E.g.

```js
var p = new PropertiesTween(
{ matrix: new Matrix(1,0,0,1,0,0) },
{ matrix: new Matrix(2,0,0,1,200,200) }
);

p.at(0.5).matrix; // => new Matrix(1.5,0,0,1,100,100)
```

#### Translators are more efficient

Translators have a simple contract. They must provide:

* A `toNumeric` method: *Is passed a raw start or end value and returns an array of numbers that can be tweened.*
* A `toUnique` method: *Is passed an array of numbers and returns a value that can be returned by `PropertyTween#at()`. This is usually the custom value like a color or matrix instance which will be composed from the tweened numbers in the array.*

Previously translators had to build, maintain and destroy named properties in custom `values` objects ... Now it's MUCH simpler; they just need to provide the above methods, and they're more performant as they're just dealing with arrays. Compare the [old](https://github.com/uxebu/bonsai/blob/master/src/runner/animation/matrix_translations.js) with the [new](https://github.com/uxebu/bonsai/blob/animation-generic/src/runner/animation/translators/matrix.js)!

#### Notes:

* It might be a good idea to expose `PropertiesTween` and `PropertyTween` classes. I imagine they could be useful as stand-alone functionality. Not sure though.
* All example movies work. All tests work. New tests have been added for new endpoints/classes.