Matrix tweens with BetweenAS3
a study for custom tween of betweenas3
// forked from beinteractive's 1. Simple tweens with BetweenAS3
// a study for custom tween of betweenas3
package
{
import flash.geom.Matrix;
import flash.display.*;
import flash.text.TextField;
import flash.events.MouseEvent;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.easing.*;
public class MatrixTweenTest extends Sprite
{
public function MatrixTweenTest()
{
(addChild(new TextField()) as TextField).text = 'Click to start';
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
BetweenAS3.registerTweenTarget(DisplayObject, MatrixTweenTarget.TARGET_PROPERTIES, MatrixTweenTarget);
}
private function mouseUpHandler(e:MouseEvent):void
{
while (numChildren > 0) {
removeChildAt(0);
}
var box1:Sprite = addNewBox(80,80);
var box2:Sprite = addNewBox(0,0);
box2.transform.matrix = new Matrix( -1.5, -0.2, -0.5, -1.6, 300, 300 );
box2.alpha = 0.5;
BetweenAS3.tween(box1,
// To
{
alpha:0.5,
a: -1.5,
b: -0.2,
c: -0.5,
d: -1.6,
tx: 300,
ty: 300
},
// From
null,
// Time
2.0,
// Easing
Back.easeOutWith(3)
).play();
}
private function addNewBox(x:Number, y:Number):Sprite
{
var box:Sprite = new Sprite();
box.graphics.beginFill(0);
box.graphics.drawRect(-40, -40, 80, 80);
box.graphics.endFill();
box.x = x;
box.y = y;
addChild(box);
return box;
}
}
}
import flash.display.DisplayObject;
import flash.geom.Matrix;
import org.libspark.betweenas3.targets.ITweenTarget;
import org.libspark.betweenas3.targets.single.AbstractSingleTweenTarget;
/**
* @author nutsu
*/
class MatrixTweenTarget extends AbstractSingleTweenTarget
{
public static const TARGET_PROPERTIES:Array = [
'a','b','c','d','tx','ty'
];
protected var _target:DisplayObject = null;
protected var _mtx:Matrix;
protected var _sa:Number;
protected var _da:Number;
protected var _sb:Number;
protected var _db:Number;
protected var _sc:Number;
protected var _dc:Number;
protected var _sd:Number;
protected var _dd:Number;
protected var _sx:Number;
protected var _dx:Number;
protected var _sy:Number;
protected var _dy:Number;
protected var _flags:uint = 0;
protected var _related_flags:uint = 0;
override public function get target():Object { return _target; }
override public function set target(value:Object):void {
_target = value as DisplayObject;
}
override public function setSourceValue(propertyName:String, value:Number, isRelative:Boolean = false):void
{
if (propertyName == 'a') {
_sa = value;
_flags |= 0x0001;
_related_flags |= isRelative ? 0x0001 : 0;
}
else if (propertyName == 'b') {
_sb = value;
_flags |= 0x0002;
_related_flags |= isRelative ? 0x0002 : 0;
}
else if (propertyName == 'c') {
_sc = value;
_flags |= 0x0004;
_related_flags |= isRelative ? 0x0004 : 0;
}
else if (propertyName == 'd') {
_sd = value;
_flags |= 0x0008;
_related_flags |= isRelative ? 0x0008 : 0;
}
else if (propertyName == 'tx') {
_sx = value;
_flags |= 0x0010;
_related_flags |= isRelative ? 0x0010 : 0;
}
else if (propertyName == 'ty') {
_sy = value;
_flags |= 0x0020;
_related_flags |= isRelative ? 0x0020 : 0;
}
}
override public function setDestinationValue(propertyName:String, value:Number, isRelative:Boolean = false):void
{
if (propertyName == 'a') {
_da = value;
_flags |= 0x0001;
_related_flags |= isRelative ? 0x0100 : 0;
}
else if (propertyName == 'b') {
_db = value;
_flags |= 0x0002;
_related_flags |= isRelative ? 0x0200 : 0;
}
else if (propertyName == 'c') {
_dc = value;
_flags |= 0x0004;
_related_flags |= isRelative ? 0x0400 : 0;
}
else if (propertyName == 'd') {
_dd = value;
_flags |= 0x0008;
_related_flags |= isRelative ? 0x0800 : 0;
}
else if (propertyName == 'tx') {
_dx = value;
_flags |= 0x0010;
_related_flags |= isRelative ? 0x1000 : 0;
}
else if (propertyName == 'ty') {
_dy = value;
_flags |= 0x0020;
_related_flags |= isRelative ? 0x2000 : 0;
}
}
protected function initialize():void
{
var t:Matrix = _target.transform.matrix;
var f:uint = _flags;
var r:uint = _related_flags;
if ((f & 0x0001) != 0) {
if (isNaN(_sa)) {
_sa = t.a;
}
else if ((r & 0x0001) != 0) {
_sa += t.a;
}
if (isNaN(_da)) {
_da = t.a;
}
else if ((r & 0x0100) != 0) {
_da += t.a;
}
}
if ((f & 0x0002) != 0) {
if (isNaN(_sb)) {
_sb = t.b;
}
else if ((r & 0x0002) != 0) {
_sb += t.b;
}
if (isNaN(_da)) {
_db = t.b;
}
else if ((r & 0x0200) != 0) {
_db += t.b;
}
}
if ((f & 0x0004) != 0) {
if (isNaN(_sc)) {
_sc = t.c;
}
else if ((r & 0x0004) != 0) {
_sc += t.c;
}
if (isNaN(_dc)) {
_dc = t.c;
}
else if ((r & 0x0400) != 0) {
_dc += t.c;
}
}
if ((f & 0x0008) != 0) {
if (isNaN(_sd)) {
_sd = t.d;
}
else if ((r & 0x0008) != 0) {
_sd += t.d;
}
if (isNaN(_dd)) {
_dd = t.d;
}
else if ((r & 0x0800) != 0) {
_dd += t.d;
}
}
if ((f & 0x0010) != 0) {
if (isNaN(_sx)) {
_sx = t.tx;
}
else if ((r & 0x0010) != 0) {
_sx += t.tx;
}
if (isNaN(_dx)) {
_dx = t.tx;
}
else if ((r & 0x1000) != 0) {
_dx += t.tx;
}
}
if ((f & 0x0020) != 0) {
if (isNaN(_sy)) {
_sy = t.ty;
}
else if ((r & 0x0020) != 0) {
_sy += t.ty;
}
if (isNaN(_dy)) {
_dy = t.ty;
}
else if ((r & 0x2000) != 0) {
_dy += t.ty;
}
}
_mtx = t;
}
override public function update(time:Number):void
{
var factor:Number = 0;
var t:DisplayObject = _target
var f:uint = _flags;
if ((f & 0x80000000) == 0) {
initialize();
_flags |= 0x80000000;
}
if (time > 0) {
if (time < _time) {
factor = _easing.calculate(time, 0.0, 1.0, _time);
}
else {
factor = 1.0;
}
}
var invert:Number = 1.0 - factor;
if ((f & 0x0001) != 0) {
_mtx.a = _sa * invert + _da * factor;
}
if ((f & 0x0002) != 0) {
_mtx.b = _sb * invert + _db * factor;
}
if ((f & 0x0004) != 0) {
_mtx.c = _sc * invert + _dc * factor;
}
if ((f & 0x0008) != 0) {
_mtx.d = _sd * invert + _dd * factor;
}
if ((f & 0x0010) != 0) {
_mtx.tx = _sx * invert + _dx * factor;
}
if ((f & 0x0020) != 0) {
_mtx.ty = _sy * invert + _dy * factor;
}
t.transform.matrix = _mtx;
}
public function setFrom(o:AbstractSingleTweenTarget):void
{
//super.setFrom(o);
var obj:MatrixTweenTarget = o as MatrixTweenTarget;
_target = obj._target;
_mtx = obj._mtx;
_sa = obj._sa;
_sb = obj._sb;
_sc = obj._sc;
_sd = obj._sd;
_sx = obj._sx;
_sy = obj._sy;
_da = obj._da;
_db = obj._db;
_dc = obj._dc;
_dd = obj._dd;
_dx = obj._dx;
_dy = obj._dy;
_flags = obj._flags;
_related_flags = obj._related_flags;
}
public function clone():ITweenTarget
{
var obj:MatrixTweenTarget = new MatrixTweenTarget();
obj.setFrom(this);
return obj;
}
}