In Flash 10 display objects can be transformed in the 3D space. That’s very nice, but due to the implementation the appearence of an objects can become a little bit different (blurry) after transforming it in 3D (changing its z, rotationX/Y/Z property, etc.), even if the object is reverted exactly in the same position as it was before the 3D transformation. Actually when an object is transformed in 3D space Flash takes a bitmap snapshot of its content and this bitmap is what transformed and displayed in real. In order to raise the bitmap’s quality a smoothing is applied to it, and this smoothing causes the difference and the blur. It is noticable especially on textfields.
Here is a demonstration:
import caurina.transitions.*; var box1: TextBox = new TextBox(); // TextBox is a symbol in the library box1.x = 30; box1.y = 35; addChild(box1); var box2: TextBox = new TextBox(); box2.x = 270; box2.y = 35; addChild(box2); box1.addEventListener(MouseEvent.CLICK, click); function click(e: MouseEvent): void { Tweener.addTween(box1, {z: 200, time: 1}); Tweener.addTween(box1, {z: 0, time: 1, delay: 1}); }
When you click the left text box it will move back and forth to its original position, but after the animation (after using 3D transformation) the text becomes blurry (compare to the text on the right).
When a DisplayObject is started to be transformed in 3D, then its transform.matrix3D property is used instead of transform.matrix, which is used for 2D transformations. If we could switch back to using transform.matrix, the smoothing and its effect would be disappear. After starting to transform an object in 3D it will not switch back automatically to 2D/transform.matrix at any time, so we have to do it manually. When transform.matrix3D is in use, the value of transform.matrix is null, and vice versa if transform.matrix is in use, the value of transform.matrix3D is null. If we nullify any of these properties manually, Flash automatically switches to using the other one (with a default identity matrix). The same effect if we assign a value (a Matrix or Matrix3D reference) to the currently unused property. So the only thing what we need to do is saving the original transform.matrix value before starting 3D transformations and restoring it when we want to switch back to 2D. The example below extends the previous one. It saves the Matrix stored in transform.matrix before starting the 3D animation, and assigns it again when the animation is complete.
import caurina.transitions.*; var box1: TextBox = new TextBox(); // TextBox is a symbol in the library box1.x = 20; box1.y = 35; addChild(box1); var box2: TextBox = new TextBox(); box2.x = 230; box2.y = 35; addChild(box2); box1.addEventListener(MouseEvent.CLICK, click); var oldMatrix: Matrix; function click(e: MouseEvent): void { // if no tween in progress if (!Tweener.isTweening(box1)) { oldMatrix = box1.transform.matrix; Tweener.addTween(box1, {z: 200, time: 1}); Tweener.addTween(box1, {z: 0, time: 1, delay: 1, onComplete: tweenComplete}); } } function tweenComplete(): void { box1.transform.matrix = oldMatrix; }
We could omit the saving of the old matrix, of course, since assigning null to transform.matrix3D also switches back to 2D, but in this case a new identity matrix will be stored in transform.matrix, so we have to take care of transforming our object to the desired position.
October 7th, 2009 at 22:00
Hello, I was pleased to discover your
http://www.tengerstudio.com/public/mouse/
because I’m trying desperately to do the same .. in AS2.
How did you manage to do that ? With mouse events ? Position ?
When the mouse is outside the animation, the mouse position is not related to the animation ..
I didn’t find your email adress, so I write here .. I hope you are not angry .. and that you will answer me ..
Kind regards from france,
Barockeuse
October 7th, 2009 at 22:58
Hi, Barockeuse! There is no magic. A simple invisible button covers the whole stage and its onRollOut event will fire when the mouse leaves it – even when the mouse leaves the stage at all. Since this invisible button catches all mouse events and these cannot pass through to other buttons below that, other buttons should be managed by yourself (onMouseMove + checking the mouse position, etc.).