Avg. Rating 2.7

Problem

Rotate UIComponent instance abound center or any other point.

Solution

Use component transform matrix or anchor rotation to some container point transformation.

Detailed explanation

Sample class available for download on http://classes.codeflex.ru/downloads/CodeFlexCenterRotator.zip

Here simple class with 3 static functions offered. First function (rotate) anchoring to UIComponent instance geometrical center point, 2 other functions logic based on components transformation matrix use.

 

package ru.codeflex.classes
{
	import mx.core.UIComponent;
	import flash.geom.Matrix;
	import flash.geom.Point;
	
	/**
	 * 
	 * @author olga@codeflex.ru
	 * 
	 */	
	public class CodeFlexCenterRotator
	{
		
		public function CodeFlexCenterRotator()
		{
		}
		/**
		 * 
		 * @param target UIComponent instance to rotate
		 * @param angle Number value of rotation 
		 * 
		 */		
		public static function rotate( target : UIComponent, angle : Number ) : void {

			var originX :Number;
			var originY :Number;
			var angleFrom : Number;
			var angleTo : Number  = angle;
			var centerX : Number;
			var centerY : Number;
			var originalOffsetX : Number
			var originalOffsetY : Number
			var newX : Number;
			var newY : Number;
			
			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;
			}
	
			target.rotation = angleFrom;
			
			radVal = Math.PI * angleFrom/180;
		
			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);
			

			var rotateValue:Number = Number(angle);		
			var radVal:Number = Math.PI * rotateValue / 180;
			
			
			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);  
			
			
			
		}
		
		/**
		 * 
		 * @param m - current target's transform matrix  
		 * @param x - rotation point x
		 * @param y - rotation point y
		 * @param angleDegrees - rotation degrees.
		 * 
		 * After method executes m will ne changed, update UIComponent transform matrix with new value
		 */			
		public static function rotateAroundInternalPoint(m:Matrix, x:Number, y:Number, angleDegrees:Number):void
		{		
			var p:Point = m.transformPoint(new Point(x, y));
			rotateAroundExternalPoint(m, p.x, p.y, angleDegrees);
		}
		
		/**
		 * 
		 * @param m - current target's transform matrix  
		 * @param x - rotation point x
		 * @param y - rotation point y
		 * @param angleDegrees - rotation degrees.
		 * 
		 * After method executes m will ne changed, update UIComponent transform matrix with new value
		 */
		public static function rotateAroundExternalPoint(m:Matrix, x:Number, y:Number, angleDegrees:Number):void
		{
			m.translate(-x, -y);
			m.rotate(angleDegrees * Math.PI /180);
			m.translate(x, y);
		}	
	}

	}
}
Report abuse

Related recipes