Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...
bastrix

skew problems

Recommended Posts

Hi all,

 

I'm working on a tool that gathers info from the xml files of a xfl flash project. I then need to reproduce some of the animations I find in that xml using tweenlite.

 

Within the xml files when I find something like this on a keyframe of an ordinary flash tween:

 

-<DOMFrame keyMode="22017" motionTweenSnap="true" tweenType="motion" duration="10" index="18"> -<elements> -<DOMSymbolInstance centerPoint3DY="-119.5" centerPoint3DX="70.65" libraryItemName="Symbol 12"> -<matrix> <Matrix ty="-124.75" tx="65.4" d="0.998733520507813" c="-0.050689697265625" b="0.050689697265625" a="0.998733520507813"/> </matrix> -<transformationPoint> <Point y="5.3" x="6"/> </transformationPoint> </DOMSymbolInstance> </elements> </DOMFrame>

 

I try gathering the matrix and other info and then doing this:

 

myTimeline.insert(TweenLite.to(mc, tweens[t]._durationFrame, {useFrames:true, ease:ClassicEase.ease, easeParams:[tweens[t]._acceleration], alpha:tweens[t+1]._alpha, transformMatrix:{a:_a, b:_b, c:_c, d:_d, tx:_tx, ty:_ty}}), 0);

 

Most of it works fine, but I've found that animations taht use skew within flash behave in unpredictable ways. It's like the skew from tweenlite is not the same as the flash one.

 

Any help will be appreciated. Thanks.

Link to comment
Share on other sites

Hmm...the transformMatrix simply applies those values to the DisplayObject's transform.matrix property, so I'm not sure what you're thinking is different. Any chance you could post a VERY simple example that only shows 2 tweens: 1 standard Flash one and the other that is a TweenLite that looks different?

Link to comment
Share on other sites

Hi Jack, thanks for replying, I also sent you a msg since I can not upload a fla file here I can send you an example if you need it. But basically I have very simple movieclip, I skew it using flash IDE, then grab the details I need to do EXACTLY the same with a transformMatrix, but it skews in a weird way. It seems like its fliping and the same time:

 

TweenLite.to(mc, 9, { useFrames:true, ease:ClassicEase.ease, easeParams:[0], transformMatrix:{a:0.466400146484375, b:-0.884552001953125, c:0.884552001953125, d:0.466400146484375, tx:-47.05, ty:-38.5}});

Link to comment
Share on other sites

BTW that ClassicEase is just simulating the default flash ease, but any ease you use gives the same result.

 

Thanks!

Link to comment
Share on other sites

Ok I managed to upload the example so you can see it:

 

[media=]http://dynamic.flash1.dev.socialpoint.es/static/temp/tweenliteSkew.swf[/media]

 

The line of code to skew:

 

TweenLite.to(mc, 9, { useFrames:true, ease:ClassicEase.ease, easeParams:[0], transformMatrix:{a:0.466400146484375, b:-0.884552001953125, c:0.884552001953125, d:0.466400146484375, tx:-47.05, ty:-38.5}});

 

Thanks

Link to comment
Share on other sites

Ah yes - this is expected behavior. Let me explain...

 

When you define each individual matrix value like that (a, b, c, d, tx, ty), TweenLite just tweens each value individually. If you read up on the matrix (Senocular does a fantastic job here: http://www.senocular...ransformmatrix/) you'll see why that's giving you the look/effect that you're seeing. It is totally accurate, but obviously not what you desired.

 

To get things to tween the way your "Flash" example does it, you need to define the rotation, scaleX, scaleY, x, and y instead. Doing so tells the TransformMatrixPlugin to tween each of those values and then recompose them into the associated matrix values. It has to do with how rotation gets applied inside the matrix numbers. If you only tween the scaleX, scaleY, x, and/or y, you'll get the same looking tween either way.

 

I have attached a sample FLA and swf that demonstrate the difference visually and in code. And here is the raw ActionScript code that's in the FLA (in case someone doesn't want to download the files):

 

 

import flash.events.Event;
import flash.geom.Matrix;
import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.plugins.*;
TweenPlugin.activate([TransformMatrixPlugin]);

//we'll start at a normal matrix (x:0, y:0, scaleX:1, scaleY:1, rotation:0)
var mOrig:Matrix = new Matrix();
//record the current scale/rotation/skew/position as our destination
var mDest:Matrix = mc1.transform.matrix;
//reset both matrices to the original (with no transforms)
mc1.transform.matrix = mc2.transform.matrix = mOrig;

//now record the CHANGE in each of the matrix values so that we can tween them manually in applyTransform() easier
var a:Number = mDest.a - mOrig.a;
var b:Number = mDest.b - mOrig.b;
var c:Number = mDest.c - mOrig.c;
var d:Number = mDest.d - mOrig.d;
var tx:Number = mDest.tx - mOrig.tx;
var ty:Number = mDest.ty - mOrig.ty;

var startTime:uint = getTimer();

addEventListener(Event.ENTER_FRAME, applyTransform);

//this function manually tweens each matrix property (of mc1) over the course of 5 seconds
function applyTransform(event:Event):void {
//figure out a value between 0 and 1 indicating the progress of the tween
var ratio:Number = (getTimer() - startTime) / 5000;
if (ratio < 1) {
	mc1.transform.matrix = new Matrix(mOrig.a + ratio * a, mOrig.b + ratio * b, mOrig.c + ratio * c, mOrig.d + ratio * d, mOrig.tx + ratio * tx, mOrig.ty + ratio * ty);
} else {
	mc1.transform.matrix = mDest;
	removeEventListener(Event.ENTER_FRAME, applyTransform);
}
}

//we'll use TweenMax to tween mc2 for comparison
TweenMax.to(mc2, 5, {transformMatrix:translateMatrix(mDest), ease:Linear.easeNone});

//this function accepts a matrix and transates it into an object that has the regular transform properties like scaleX, scaleY, rotation, x, y, and skewX
function translateMatrix(m:Matrix):Object {
var vars:Object = {x:m.tx, y:m.ty};
vars.scaleX = Math.sqrt(m.a * m.a + m.b * m.;
vars.scaleY = Math.sqrt(m.d * m.d + m.c * m.c);
vars.rotation = (m.a || m. ? Math.atan2(m.b, m.a) : 0;
vars.skewX = (m.c || m.d) ? Math.atan2(m.c, m.d) + vars.rotation : 0;
if (Math.abs(vars.skewX) > Math.PI / 2) {
	vars.scaleY *= -1;
	vars.skewX += (vars.skewX <= 0) ? Math.PI : -Math.PI;
}
//translate from radians to degrees and flip the skewX because of the way Flash interprets it.
vars.rotation *= 180 / Math.PI;
vars.skewX *= -180 / Math.PI;
return vars;
}

 

Just put two MovieClips or Sprites on the stage and name them mc1 and mc2 and apply the same transform to both (mess with the scale/skew/rotation/position). Then run the code and you'll see how things are affected when you manually tween each matrix property versus tweening the meaningful data like rotation, skew, etc. which affect multiple matrix values.

 

Make more sense now?

transformMatrix_demo.zip

  • Like 1
Link to comment
Share on other sites

Ah yes - this is expected behavior. Let me explain...

 

When you define each individual matrix value like that (a, b, c, d, tx, ty), TweenLite just tweens each value individually. If you read up on the matrix (Senocular does a fantastic job here: http://www.senocular...ransformmatrix/) you'll see why that's giving you the look/effect that you're seeing. It is totally accurate, but obviously not what you desired.

 

To get things to tween the way your "Flash" example does it, you need to define the rotation, scaleX, scaleY, x, and y instead. Doing so tells the TransformMatrixPlugin to tween each of those values and then recompose them into the associated matrix values. It has to do with how rotation gets applied inside the matrix numbers. If you only tween the scaleX, scaleY, x, and/or y, you'll get the same looking tween either way.

 

I have attached a sample FLA and swf that demonstrate the difference visually and in code. And here is the raw ActionScript code that's in the FLA (in case someone doesn't want to download the files):

 

 

import flash.events.Event;
import flash.geom.Matrix;
import com.greensock.*;
import com.greensock.easing.*;
import com.greensock.plugins.*;
TweenPlugin.activate([TransformMatrixPlugin]);

//we'll start at a normal matrix (x:0, y:0, scaleX:1, scaleY:1, rotation:0)
var mOrig:Matrix = new Matrix();
//record the current scale/rotation/skew/position as our destination
var mDest:Matrix = mc1.transform.matrix;
//reset both matrices to the original (with no transforms)
mc1.transform.matrix = mc2.transform.matrix = mOrig;

//now record the CHANGE in each of the matrix values so that we can tween them manually in applyTransform() easier
var a:Number = mDest.a - mOrig.a;
var b:Number = mDest.b - mOrig.b;
var c:Number = mDest.c - mOrig.c;
var d:Number = mDest.d - mOrig.d;
var tx:Number = mDest.tx - mOrig.tx;
var ty:Number = mDest.ty - mOrig.ty;

var startTime:uint = getTimer();

addEventListener(Event.ENTER_FRAME, applyTransform);

//this function manually tweens each matrix property (of mc1) over the course of 5 seconds
function applyTransform(event:Event):void {
//figure out a value between 0 and 1 indicating the progress of the tween
var ratio:Number = (getTimer() - startTime) / 5000;
if (ratio < 1) {
	mc1.transform.matrix = new Matrix(mOrig.a + ratio * a, mOrig.b + ratio * b, mOrig.c + ratio * c, mOrig.d + ratio * d, mOrig.tx + ratio * tx, mOrig.ty + ratio * ty);
} else {
	mc1.transform.matrix = mDest;
	removeEventListener(Event.ENTER_FRAME, applyTransform);
}
}

//we'll use TweenMax to tween mc2 for comparison
TweenMax.to(mc2, 5, {transformMatrix:translateMatrix(mDest), ease:Linear.easeNone});

//this function accepts a matrix and transates it into an object that has the regular transform properties like scaleX, scaleY, rotation, x, y, and skewX
function translateMatrix(m:Matrix):Object {
var vars:Object = {x:m.tx, y:m.ty};
vars.scaleX = Math.sqrt(m.a * m.a + m.b * m.;
vars.scaleY = Math.sqrt(m.d * m.d + m.c * m.c);
vars.rotation = (m.a || m. ? Math.atan2(m.b, m.a) : 0;
vars.skewX = (m.c || m.d) ? Math.atan2(m.c, m.d) + vars.rotation : 0;
if (Math.abs(vars.skewX) > Math.PI / 2) {
	vars.scaleY *= -1;
	vars.skewX += (vars.skewX <= 0) ? Math.PI : -Math.PI;
}
//translate from radians to degrees and flip the skewX because of the way Flash interprets it.
vars.rotation *= 180 / Math.PI;
vars.skewX *= -180 / Math.PI;
return vars;
}

 

Just put two MovieClips or Sprites on the stage and name them mc1 and mc2 and apply the same transform to both (mess with the scale/skew/rotation/position). Then run the code and you'll see how things are affected when you manually tween each matrix property versus tweening the meaningful data like rotation, skew, etc. which affect multiple matrix values.

 

Make more sense now?

 

Jaaaaysus! Thanks a million! I spent ages trying to figure out what I was doing wrong... This was extremely helpful. THANKS!

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×