1////////////////////////////////////////////////////////////////////////////////
2//
3//  ADOBE SYSTEMS INCORPORATED
4//  Copyright 2009 Adobe Systems Incorporated
5//  All Rights Reserved.
6//
7//  NOTICE: Adobe permits you to use, modify, and distribute this file
8//  in accordance with the terms of the license agreement accompanying it.
9//
10////////////////////////////////////////////////////////////////////////////////
11
12package spark.effects
13{
14import mx.core.mx_internal;
15import mx.effects.IEffectInstance;
16
17import spark.effects.animation.MotionPath;
18import spark.effects.supportClasses.AnimateTransformInstance;
19
20use namespace mx_internal;
21
22//--------------------------------------
23//  Excluded APIs
24//--------------------------------------
25
26[Exclude(name="motionPaths", kind="property")]
27
28/**
29 *  The Rotate3D class rotate a target object
30 *  in three dimensions around the x, y, or z axes.
31 *  The rotation occurs around the transform center of the target.
32 *
33 *  <p>Like all AnimateTransform-based effects, this effect only works on subclasses
34 *  of UIComponent and GraphicElement, as these effects depend on specific
35 *  transform functions in those classes.
36 *  Also, transform effects running in parallel on the same target run as a single
37 *  effect instance
38 *  Therefore, the transform effects share the transform center
39 *  set by any of the contributing effects.</p>
40 *
41 *  @mxml
42 *
43 *  <p>The <code>&lt;s:Rotate3D&gt;</code> tag
44 *  inherits all of the tag attributes of its superclass,
45 *  and adds the following tag attributes:</p>
46 *
47 *  <pre>
48 *  &lt;s:Rotate3D
49 *    <b>Properties</b>
50 *    id="ID"
51 *    angleXFrom="no default"
52 *    angleXTo="no default"
53 *    angleYFrom="no default"
54 *    angleYTo="no default"
55 *    angleZFrom="no default"
56 *    angleZTo="no default"
57 *  /&gt;
58 *  </pre>
59 *
60 *  @includeExample examples/Rotate3DEffectExample.mxml
61 *
62 *  @langversion 3.0
63 *  @playerversion Flash 10
64 *  @playerversion AIR 1.5
65 *  @productversion Flex 4
66 */
67public class Rotate3D extends AnimateTransform3D
68{
69    include "../core/Version.as";
70
71    //--------------------------------------------------------------------------
72    //
73    //  Class constants
74    //
75    //--------------------------------------------------------------------------
76
77    /**
78     *  @private
79     */
80    private static var AFFECTED_PROPERTIES:Array =
81        ["rotationX", "rotationY", "rotationZ",
82         "postLayoutRotationX","postLayoutRotationY","postLayoutRotationZ",
83         "width", "height"];
84
85    private static var RELEVANT_STYLES:Array = [];
86
87    //--------------------------------------------------------------------------
88    //
89    //  Constructor
90    //
91    //--------------------------------------------------------------------------
92
93    /**
94     *  Constructor.
95     *
96     *  @param target The Object to animate with this effect.
97     *
98     *  @langversion 3.0
99     *  @playerversion Flash 10
100     *  @playerversion AIR 1.5
101     *  @productversion Flex 4
102     */
103    public function Rotate3D(target:Object=null)
104    {
105        super(target);
106        applyLocalProjection = true;
107        instanceClass = AnimateTransformInstance;
108        applyChangesPostLayout = true;
109        transformEffectSubclass = true;
110    }
111
112    //--------------------------------------------------------------------------
113    //
114    //  Properties
115    //
116    //--------------------------------------------------------------------------
117
118    //----------------------------------
119    //  angleXFrom
120    //----------------------------------
121
122    [Inspectable(category="General")]
123
124    /**
125     *  The starting angle of rotation of the target object around
126     *  the x axis, expressed in degrees.
127     *  Valid values range from 0 to 360.
128     *
129     *  @langversion 3.0
130     *  @playerversion Flash 10
131     *  @playerversion AIR 1.5
132     *  @productversion Flex 4
133     */
134    public var angleXFrom:Number;
135
136    //----------------------------------
137    //  angleXTo
138    //----------------------------------
139
140    [Inspectable(category="General")]
141
142    /**
143     *  The ending angle of rotation of the target object around
144     *  the x axis, expressed in degrees.
145     *  Values can be either positive or negative.
146     *
147     *  <p>If the value of <code>angleTo</code> is less
148     *  than the value of <code>angleFrom</code>,
149     *  the target rotates in a counterclockwise direction.
150     *  Otherwise, it rotates in clockwise direction.
151     *  If you want the target to rotate multiple times,
152     *  set this value to a large positive or small negative number.</p>
153     *
154     *  @langversion 3.0
155     *  @playerversion Flash 10
156     *  @playerversion AIR 1.5
157     *  @productversion Flex 4
158     */
159    public var angleXTo:Number;
160
161    //----------------------------------
162    //  angleYFrom
163    //----------------------------------
164
165    [Inspectable(category="General")]
166
167    /**
168     *  The starting angle of rotation of the target object around
169     *  the y axis, expressed in degrees.
170     *  Valid values range from 0 to 360.
171     *
172     *  @langversion 3.0
173     *  @playerversion Flash 10
174     *  @playerversion AIR 1.5
175     *  @productversion Flex 4
176     */
177    public var angleYFrom:Number;
178
179    //----------------------------------
180    //  angleYTo
181    //----------------------------------
182
183    [Inspectable(category="General")]
184
185    /**
186     *  The ending angle of rotation of the target object around
187     *  the y axis, expressed in degrees.
188     *  Values can be either positive or negative.
189     *
190     *  <p>If the value of <code>angleTo</code> is less
191     *  than the value of <code>angleFrom</code>,
192     *  the target rotates in a counterclockwise direction.
193     *  Otherwise, it rotates in clockwise direction.
194     *  If you want the target to rotate multiple times,
195     *  set this value to a large positive or small negative number.</p>
196     *
197     *  @langversion 3.0
198     *  @playerversion Flash 10
199     *  @playerversion AIR 1.5
200     *  @productversion Flex 4
201     */
202    public var angleYTo:Number;
203
204    //----------------------------------
205    //  angleZFrom
206    //----------------------------------
207
208    [Inspectable(category="General")]
209
210    /**
211     *  The starting angle of rotation of the target object around
212     *  the z axis, expressed in degrees.
213     *  Valid values range from 0 to 360.
214     *
215     *  @langversion 3.0
216     *  @playerversion Flash 10
217     *  @playerversion AIR 1.5
218     *  @productversion Flex 4
219     */
220    public var angleZFrom:Number;
221
222    //----------------------------------
223    //  angleZTo
224    //----------------------------------
225
226    [Inspectable(category="General")]
227
228    /**
229     *  The ending angle of rotation of the target object around
230     *  the z axis, expressed in degrees.
231     *  Values can be either positive or negative.
232     *
233     *  <p>If the value of <code>angleTo</code> is less
234     *  than the value of <code>angleFrom</code>,
235     *  the target rotates in a counterclockwise direction.
236     *  Otherwise, it rotates in clockwise direction.
237     *  If you want the target to rotate multiple times,
238     *  set this value to a large positive or small negative number.</p>
239     *
240     *  @langversion 3.0
241     *  @playerversion Flash 10
242     *  @playerversion AIR 1.5
243     *  @productversion Flex 4
244     */
245    public var angleZTo:Number;
246
247    //--------------------------------------------------------------------------
248    //
249    //  Overridden methods
250    //
251    //--------------------------------------------------------------------------
252
253    /**
254     *  @private
255     */
256    override public function get relevantStyles():Array /* of String */
257    {
258        return RELEVANT_STYLES;
259    }
260
261    /**
262     *  @private
263     */
264    override public function getAffectedProperties():Array /* of String */
265    {
266        return AFFECTED_PROPERTIES;
267    }
268
269    // TODO (chaase): Should try to remove this override. At a minimum, we could
270    // put the motionPaths creation at the start of initInstance(). Ideally, we'd
271    // remove that logic entirely, but there's a need to create motionPaths fresh
272    // for every call to create/initInstance() or else multi-instance effects
273    // will inherit the one motionPaths object created elsewhere.
274    /**
275     * @private
276     */
277    override public function createInstance(target:Object = null):IEffectInstance
278    {
279        motionPaths = new Vector.<MotionPath>();
280        return super.createInstance(target);
281    }
282
283    /**
284     * @private
285     */
286    override protected function initInstance(instance:IEffectInstance):void
287    {
288        var xProp:String = applyChangesPostLayout ? "postLayoutRotationX" : "rotationX";
289        var yProp:String = applyChangesPostLayout ? "postLayoutRotationY" : "rotationY";
290        var zProp:String = applyChangesPostLayout ? "postLayoutRotationZ" : "rotationZ";
291
292        addMotionPath(xProp, angleXFrom, angleXTo);
293        addMotionPath(yProp, angleYFrom, angleYTo);
294        addMotionPath(zProp, angleZFrom, angleZTo);
295
296        super.initInstance(instance);
297    }
298}
299}
300