//////////////////////////////////////////////////////////////////////////////// // // Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // //////////////////////////////////////////////////////////////////////////////// package mx.effects.effectClasses { import mx.core.mx_internal; import mx.effects.EffectManager; // Let (phi) be angle between r=(Ox,Oy - Cx,Cy) and -X Axis. // (theta) be clockwise further angle of rotation. // // Xtheta = Cx - rCos(theta + phi); // Ytheta = Cy - rSin(theta + phi); // // Xtheta = Cx - rCos(theta)Cos(phi) + rSin(theta)Sin(phi); // Ytheta = Cy - rSin(theta)Cos(phi) - rCos(theta)Sin(phi); // // Now Cos(phi) = w/2r; Sin(phi) = h/2r; // // Xtheta = Cx - rCos(theta)Cos(phi) + rSin(theta)Sin(phi); // Ytheta = Cy - rSin(theta)Cos(phi) - rCos(theta)Sin(phi); // // Xtheta = Cx - rCos(theta)w/2r + rSin(theta)h/2r; // Ytheta = Cy - rSin(theta)w/2r - rCos(theta)h/2r; // // Xtheta = Cx - wCos(theta)/2 + hSin(theta)/2; // Ytheta = Cy - wSin(theta)/2 - hCos(theta)/2; // /** * The RotateInstance class implements the instance class * for the Rotate effect. * Flex creates an instance of this class when it plays a Rotate effect; * you do not create one yourself. * *

Every effect class that is a subclass of the TweenEffect class * supports the following events:

* * * *

The event object passed to the event listener for these events is of type TweenEvent. * The TweenEvent class defines the property value, which contains * the tween value calculated by the effect. * For the Rotate effect, * the TweenEvent.value property contains a Number between the values of * the Rotate.angleFrom and * Rotate.angleTo properties.

* * @see mx.effects.Rotate * @see mx.events.TweenEvent * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public class RotateInstance extends TweenEffectInstance { include "../../core/Version.as"; //-------------------------------------------------------------------------- // // Constructor // //-------------------------------------------------------------------------- /** * Constructor. * * @param target The Object to animate with this effect. * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public function RotateInstance(target:Object) { super(target); } //-------------------------------------------------------------------------- // // Variables // //-------------------------------------------------------------------------- /** * @private * The x coordinate of the absolute point of rotation. */ private var centerX:Number; /** * @private * The y coordinate of absolute point of rotation. */ private var centerY:Number; /** * @private */ private var newX:Number; /** * @private */ private var newY:Number; /** * @private */ private var originalOffsetX:Number; /** * @private */ private var originalOffsetY:Number; //-------------------------------------------------------------------------- // // Properties // //-------------------------------------------------------------------------- //---------------------------------- // angleFrom //---------------------------------- [Inspectable(category="General", defaultValue="0")] /** * The starting angle of rotation of the target object, * expressed in degrees. * Valid values range from 0 to 360. * * @default 0 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var angleFrom:Number = 0; //---------------------------------- // angleTo //---------------------------------- [Inspectable(category="General", defaultValue="360")] /** * The ending angle of rotation of the target object, * expressed in degrees. * Values can be either positive or negative. * *

If the value of angleTo is less * than the value of angleFrom, * then the target rotates in a counterclockwise direction. * Otherwise, it rotates in clockwise direction. * If you want the target to rotate multiple times, * set this value to a large positive or small negative number.

* * @default 360 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var angleTo:Number = 360; //---------------------------------- // originY //---------------------------------- /** * The x-position of the center point of rotation. * The target rotates around this point. * The valid values are between 0 and the width of the target. * * @default 0 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var originX:Number; //---------------------------------- // originY //---------------------------------- /** * The y-position of the center point of rotation. * The target rotates around this point. * The valid values are between 0 and the height of the target. * * @default 0 * * @langversion 3.0 * @playerversion Flash 9 * @playerversion AIR 1.1 * @productversion Flex 3 */ public var originY:Number; //-------------------------------------------------------------------------- // // Overridden methods // //-------------------------------------------------------------------------- /** * @private */ override public function play():void { super.play(); var radVal:Number = Math.PI * target.rotation / 180; // Default to the center if (isNaN(originX)) originX = target.width / 2; if (isNaN(originY)) originY = target.height / 2; // Find the about point centerX = target.x + originX * Math.cos(radVal) - originY * Math.sin(radVal); centerY = target.y + originX * Math.sin(radVal) + originY * Math.cos(radVal); if (isNaN(angleFrom)) angleFrom = target.rotation; if (isNaN(angleTo)) { angleTo = (target.rotation == 0) ? ((angleFrom > 180) ? 360 : 0) : target.rotation; } tween = createTween(this, angleFrom, angleTo, duration); target.rotation = angleFrom; radVal = Math.PI * angleFrom/180; EffectManager.suspendEventHandling(); originalOffsetX = originX * Math.cos(radVal) - originY * Math.sin(radVal); originalOffsetY = originX * Math.sin(radVal) + originY * Math.cos(radVal); newX = Number((centerX - originalOffsetX).toFixed(1)); // use a precision of 1 newY = Number((centerY - originalOffsetY).toFixed(1)); // use a precision of 1 target.move(newX, newY); EffectManager.resumeEventHandling(); } /** * @private */ override public function onTweenUpdate(value:Object):void { // If somebody else has changed our position if (Math.abs(newX - target.x) > 0.1) { centerX = target.x + originalOffsetX; } if (Math.abs(newY - target.y) > 0.1) { centerY = target.y + originalOffsetY; } var rotateValue:Number = Number(value); var radVal:Number = Math.PI * rotateValue / 180; EffectManager.suspendEventHandling(); target.rotation = rotateValue; newX = centerX - originX * Math.cos(radVal) + originY * Math.sin(radVal); newY = centerY - originX * Math.sin(radVal) - originY * Math.cos(radVal); newX = Number(newX.toFixed(1)); // use a precision of 1 newY = Number(newY.toFixed(1)); // use a precision of 1 target.move(newX, newY); EffectManager.resumeEventHandling(); } } }