Most effects manipulate the effect target in the x and
y dimensions to create two-dimensional effects. In the two-dimensional
coordinate system, the x, y coordinates of 0, 0 corresponds to the
upper-left corner of the component’s coordinate system. For example,
if the Application container takes up your full computer screen,
those coordinates correspond to the upper-left corner of the computer screen.
Increasing values of x moves to the right of the compute screen,
and increasing values of y move down the screen.
The 3D effects add support for the z-axis. The z = 0 coordinate
corresponds to the plane of the computer screen. Increasing values
of z moves an object into the screen, making the object look farther
away from the viewer. Decreasing values of z move the object toward
the viewer.
The spark 3D effects are transform effects designed to take advantage
of the support for three-dimensional graphics in Flash Player. Flex
includes the following 3D effects:
Moves
the effect target in the x, y, and z coordinate system. Moving the
target to increasing values in the z direction makes it appear to
move back away from the viewer, so the target shrinks. Moving the
target to decreasing values in the z direction makes it appear to
move toward the viewer, so the target grows.
Rotates
the effect target around the x, y, or z-axis. For example, rotating
the target around the y-axis rotates the object vertically through
the x and z planes, similar to a door opening and closing on vertical
hinges. Rotating the target around the z-axis makes the object rotate
through the x and y planes, which is the same as a two-dimensional
rotation.
Scales
the effect target in the x, y, and z directions by setting the appropriate scale
properties on the target. A scale of 2.0 means the object has been magnified
by a factor of 2. A scale of 0.5 means the object has been reduced by
a factor of 2. A scale value of 0.0 is not allowed.
The executing SWF file for the previous example is shown below:
In this example, the Move3D effect moves the target by increasing
the value of the x and z coordinates by 100. It then reverses, and
moves the component back to its original x and z coordinates. To
the user, the image moves to the left and shrinks, then moves back
to the right and grows to its original size.
The following example uses the Rotate3D effect to rotate the
image around the y-axis:
The executing SWF file for the previous example is shown below:
Setting the transform center of a 3D effect
By default, the transform center of the target of a 3D
transform effect is the upper-left corner of the target component.
This point corresponds to coordinates (0, 0, 0) in the target component’s
coordinate system. You can set the transform center to a different
location. For an introduction to setting the transform center for
two-dimensional effects, see Applying transform effects.
If you run the example in the previous section, you notice that
the target object rotates around its left edge. That is because
the effects, by default, operates around the default transform center
of the target object.
Often, you want to rotate the target component around its center
point instead of around the default transform center. One option
is to set the transform center to the center point of the component
by setting the autoCenterTransform property to true.
The following example modifies the example from the previous section
to rotate the image around its center point:
The executing SWF file for the previous example is shown below:
Alternatively, you can set the transormX, transformY,
and transformZ properties on the effect target
to define the transform center. In the following example, you set
the transform center of the image to the right edge, corresponding
to the transormX property having a value of 100:
The executing SWF file for the previous example is shown below:
Component layout and 3D effects
Effects can modify the layout of the parent container of the
effect target. For example, suppose the effect target is in a container
that uses vertical layout. You then use the two-dimensional Rotate
effect to rotate the target through 360°. As the effect plays, the
parent container modifies the layout of its other children to accommodate
the rotating child. Therefore, container children can change position
during the effect.
Flex has the concept of layering of the children of a container.
Children are drawn on the screen in the order in which they are
defined in the container. If children overlap, the child defined
later in the container appears on top because it is drawn last.
Flex provides a set of built-in layout classes, such as the VerticalLayout
class, to control child layout in a container. These layout classes
assume that all children are in the z = 0 plane. That means a container
always lays out children in the two-dimensional x, y plane.
However, a 3D effect can modify the effect target in the x, y,
and z dimensions. If your 3D effect uses the z dimension, the built-in
layout classes do not consider it during layout. If you then allow
the parent container to update its layout by taking only the x and
y dimensions into consideration, your application might not appear
correctly. Therefore, you typically disable the parent container
from performing layout while the 3D effect plays.
All effects support the disableLayout property.
When set to true, this property disables layout
in the parent container of the effect target for the duration of
the effect. The default value is false. For effects
though, you typically do not want to disable layout of the parent
container entirely.
All transform effects define the applyChangesPostLayout property
which, by default, is set to true for the 3D effects.
This setting lets the 3D effect modify the target component, but
the parent container ignores the changes and does not update its
layout while the effect plays. Changes to other container children still
cause a layout update.
Note: For the 2D transform effects Move, Rotate, and Scale, the
affectLayout property is true by default.
You can think of the 3D effects as not playing until after the
container for the effect target has completed its layout. Because
the effect plays post layout, the parent container does not modify
its layout for changes to the target component caused by the effect.
In the following example, the application contains three images
in an HGroup container. The Rotate3D effect then plays on the middle
image to rotate it around the y-axis. Because the applyChangesPostLayout property
is true by default, no layout occurs as the image
rotates, and the target image overlaps the image on its left:
The executing SWF file for the previous example is shown below:
For example, set the transformX property to
100 on the effect target in the previous example to rotate the middle
image so that it overlaps the image on the right. The image on the
right appears on top of the middle image because it was drawn last.
You can override the default of disabling layout on the effect
target by setting the applyChangesPostLayout property
of the effect to false. In the following example,
you rotate the image around the z-axis, with the applyChangesPostLayout property
set to false. A 3D rotation around the z-axis is
essentially a 2D rotation in the x and y plane. Because the applyChangesPostLayout property
is false, the parent container updates the layout
of the other two images as the effect plays:
The executing SWF file for the previous example is shown below:
Setting the postLayoutTransformOffsets property on a component
You can directly modify the position, rotation, and scale
of a component post layout without using a 3D effect. Instead, use
the postLayoutTransformOffsets property, of type
mx.geom:TransformOffsets, of the UIComponent class. By setting the postLayoutTransformOffsets property
directly, you modify the target without causing the parent container
to update its layout.
In the following example, you use the postLayoutTransformOffsets property
to modify the position and scale of a component. As you modify it, notice
that the parent container does not update its layout:
<?xml version="1.0"?>
<!-- behaviors\Spark3DOffset.mxml -->
<s:Application
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:s="library://ns.adobe.com/flex/spark">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.geom.TransformOffsets;
// Define an instance of TransformOffsets.
private var myXForm:TransformOffsets = new TransformOffsets();
// Initialize the postLayoutTransformOffsets property of the target.
private function initOffsets():void {
targetImg.postLayoutTransformOffsets = myXForm;
}
// Move the target 20 pixels to the left and
// increase its x and y scale by 0.1.
private function nudgeImageLeft():void {
targetImg.postLayoutTransformOffsets.x =
targetImg.postLayoutTransformOffsets.x - 20;
targetImg.postLayoutTransformOffsets.scaleX =
targetImg.postLayoutTransformOffsets.scaleX + 0.1;
targetImg.postLayoutTransformOffsets.scaleY =
targetImg.postLayoutTransformOffsets.scaleY + 0.1;
}
// Move the target 20 pixels to the right and
// decrease its x and y scale by 0.1.
private function nudgeImageRight():void {
targetImg.postLayoutTransformOffsets.x =
targetImg.postLayoutTransformOffsets.x + 20;
targetImg.postLayoutTransformOffsets.scaleX =
targetImg.postLayoutTransformOffsets.scaleX - 0.1;
targetImg.postLayoutTransformOffsets.scaleY =
targetImg.postLayoutTransformOffsets.scaleY - 0.1;
}
// Reset the transform.
private function resetImage():void {
targetImg.postLayoutTransformOffsets.x = 0;
targetImg.postLayoutTransformOffsets.scaleX = 1.0;
targetImg.postLayoutTransformOffsets.scaleY = 1.0;
}
]]>
</fx:Script>
<s:Panel title="Offset Example"
width="75%" height="75%" >
<s:HGroup
horizontalCenter="0"
verticalCenter="0">
<s:Image
source="@Embed(source='assets/Nokia_6630.png')"/>
<s:Image id="targetImg"
source="@Embed(source='assets/Nokia_6630.png')"
creationComplete="initOffsets();"/>
<s:Image
source="@Embed(source='assets/Nokia_6630.png')"/>
</s:HGroup>
<s:HGroup left="5" bottom="5">
<s:Button id="nudgeLeftButton"
label="Nudge Left"
click="nudgeImageLeft();"/>
<s:Button id="nudgeRightButton"
label="Nudge Right"
click="nudgeImageRight();"/>
<s:Button id="resetButton"
label="Reset"
click="resetImage();"/>
</s:HGroup>
</s:Panel>
</s:Application>
The executing SWF file for the previous example is shown below:
Notice in this example that as you nudge the image to the left,
it overlaps the image to its left. As you nudge the image to the
right, it moves behind the image on the right. This overlap is because
the image on the right is defined later in the container, and is
therefore drawn last on the screen.
Setting the center of the projection
The 3D effects work by mapping a three-dimensional image
onto a two-dimensional representation for display on a computer
screen. The projection point defines the center of the field
of view, and controls how the target is projected from three dimensions
onto the screen.
By default, when you apply a 3D effect, the effect automatically
sets the projection point to the center of the target. You can set
the autoCenterProjection property of the effect
to false to disable this default. You then use
the projectionX and projectionY properties
to explicitly set the projection point. These properties specify
the offset of the projection point from the (0, 0) coordinate of
the target.