سؤال

I am trying to perform some 3D rotation on pictures, but it harder than it look. The fact is that when you rotate a picture on the axis X and/or Y, it look stretched (but it's normal). But when you make a rotation from the axis Z, the picture rotate around the Z axis of the screen instead of it own axis. So it look like a stretched picture which turn around an axis instead of a plate picture, viewed from a side and which turn around it center.

Since I know it's a little confusing, here is the function I am using. You can try it with a circular picture for a better "effect". Just imagine you want a rotating circle, no mater the orientation. You will see that the picture rotate around the axis of the screen insteat of it's own axis.

public function rotate(target:IVisualElement, x:Number = 0, y:Number = 0, z:Number = 0, duration:Number = 1000):void
{
    var rotation:Rotate3D = new Rotate3D();
    rotation.autoCenterTransform = true;
    rotation.angleXTo = x;
    rotation.angleYTo = y;
    rotation.angleZTo = z;
    rotation.duration = duration;
    rotation.target = target;

    rotation.play();
}

Is there a easy simple way to perform theses rotations without having to redevelop the wheel ?

هل كانت مفيدة؟

المحلول

Finally I managed to have something which work perfectly and without external library. The trick was so simple that I don't understand why I don't tried it before.

Instead of applying X, Y and Z transformations on the same element, I apply the X and Y rotations on a container and the Z axis on the picture inside the container.

Like this, the Z rotation doesn't disturb the other axis anymore.

Here is the working test code:

<fx:Script>
    <![CDATA[
        private function init():void
        {
            moveZ();
            var timer:Timer = new Timer(5000);
            timer.addEventListener(TimerEvent.TIMER, repeat);
            timer.start();
        }

        private function repeat(e:TimerEvent):void
        {
            moveZ();
        }

        private function moveX():void
        {
            rotX += 20;
            fx.angleXTo = rotX;
            fx.angleYTo = rotY;
            fx.angleZTo = 0;
            fx.duration = 1000;
            fx.play(new Array(container));
        }
        private function moveY():void
        {
            rotY += 20;
            fx.angleXTo = rotX;
            fx.angleYTo = rotY;
            fx.angleZTo = 0;
            fx.duration = 1000;
            fx.play(new Array(container));
        }
        private function moveZ():void
        {
            rotZ += 360;
            fx.angleXTo = 0;
            fx.angleYTo = 0;
            fx.angleZTo = rotZ;
            fx.duration = 5000;
            fx.play(new Array(image));
        }
    ]]>
</fx:Script>

<fx:Declarations>
    <fx:Number id="rotX">0</fx:Number>
    <fx:Number id="rotY">0</fx:Number>
    <fx:Number id="rotZ">0</fx:Number>
    <s:Rotate3D id="fx" autoCenterProjection="true" autoCenterTransform="true"/>
</fx:Declarations>
<s:VGroup id="vGroup" left="10" top="10">
    <s:Button label="X" buttonDown="moveX()"/>
    <s:Button label="Y" buttonDown="moveY()"/>
</s:VGroup>
<s:BorderContainer id="container" width="200" height="200" horizontalCenter="0"
                   verticalCenter="0">
    <s:BitmapImage id="image" width="200" height="200" horizontalCenter="0" smooth="true"
                   source="@Embed('assets/circle.png')" verticalCenter="0"/>
</s:BorderContainer>

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top