简体   繁体   中英

Flex/ActionScript - rotate Sprite around its center

I have created a Sprite in Actionscript and rendered it to a Flex Canvas. Suppose:

var fooShape:Sprite = new FooSpriteSubclass();

fooCanvas.rawChildren.addChild(myshape);

//Sprite shape renders on screen

fooShape.rotation = fooNumber;

This will rotate my shape, but seems to rotate it around the upper-left point of its parent container(the canvas).

How can I force the Sprite to rotate about is own center point? I could obviously write code to calculate the rotation, and then have it re-render, but I think there must be a built-in way to do this, and certainly do not want to 'reinvent the wheel' if possible.

I am using FlexBuilder, and therefore do not have access to the full Flash API.

Thank you much!

The following steps are required to rotate objects based on a reference point (using Matrix object and getBounds):

  1. Matrix translation (moving to the reference point)
  2. Matrix rotation
  3. Matrix translation (back to original position)


For example to rotate an object 90 degrees around its center:

// Get the matrix of the object  
var matrix:Matrix = myObject.transform.matrix; 

// Get the rect of the object (to know the dimension) 
var rect:Rectangle = myObject.getBounds(parentOfMyObject); 

// Translating the desired reference point (in this case, center)
matrix.translate(- (rect.left + (rect.width/2)), - (rect.top + (rect.height/2))); 

// Rotation (note: the parameter is in radian) 
matrix.rotate((90/180)*Math.PI); 

// Translating the object back to the original position.
matrix.translate(rect.left + (rect.width/2), rect.top + (rect.height/2)); 



Key methods used:

Didn't have much luck with the other examples. This one worked for me. I used it on a UIComponent.

http://www.selikoff.net/2010/03/17/solution-to-flex-image-rotation-and-flipping-around-center/

private static function rotateImage(image:Image, degrees:Number):void {
// Calculate rotation and offsets
var radians:Number = degrees * (Math.PI / 180.0);
var offsetWidth:Number = image.contentWidth/2.0;
var offsetHeight:Number =  image.contentHeight/2.0;

// Perform rotation
var matrix:Matrix = new Matrix();
matrix.translate(-offsetWidth, -offsetHeight);
matrix.rotate(radians);
matrix.translate(+offsetWidth, +offsetHeight);
matrix.concat(image.transform.matrix);
image.transform.matrix = matrix;

}

Actually I had to add this code to make above solutions work for me.

private var _rotateCount = 0;
var _origginalMatrix:Matrix=new Matrix();
.........
if (_rotateCount++ >= 360 / angleDegrees)
{
    myObject.transform.matrix = _origginalMatrix;
    _rotateCount = 0;
            return;
}

var matrix:Matrix = myObject.transform.matrix;
.... 

Without that after some long time rotated object slowly moves somewhere right top.

If you want to rotate around the center, merely center the asset inside your sprite by setting the internal assets x and y to half of the width and height of the asset. This swill center your content and allow it to rotate around a center point.

An example of runtime loaded assets is as follows:

var loader:Loader = new Loader():
var request:URLRequest = new URLRequest(path/to/asset.ext);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, _onLoaderComplete);
loader.load(request);

private function _onLoaderComplete(e:Event):void
{
    var mc:MovieClip = e.target.content as MovieClip;
    mc.x = -mc.width * 0.5;
    mc.y = -mc.height * 0.5;
    mc.rotation = 90;
    addChild(mc);
}

An alternative solution is to put your object inside another View, move it so that your image's center is at the container's top-left corner, and then rotate the container.

import spark.components.*;

var myContainer:View = new View();
var myImage:Image = new Image();

myContainer.addElement(myImage);
myImage.x = myImage.width / -2;
myImage.y = myImage.height / -2;

addElement(myContainer);

myContainer.rotation = whateverAngle;

One issue might be that the width of the image isn't know at the moment it is created, so you might want to find a way around that. (Hardcode it, or see if myImage.preliminaryWidth works)

/**
* Rotates the object based on its center
* Parameters: @obj => the object to rotate
* @ rotation => angle to rotate
* */
public function RotateAroundCenter(obj:Object, rotation:Number):void
{

var bound:Rectangle = new Rectangle();
// get the bounded rectangle of objects
bound = obj.getRect(this);

// calculate mid poits
var midx1:Number = bound.x + bound.width/2;
var midy1:Number = bound.y + bound.height/2;

// assign the rotation
obj.rotation = rotation;

// assign the previous mid point as (x,y)
obj.x = midx1;
obj.y = midy1;

// get the new bounded rectangle of objects
bound = obj.getRect(this);

// calculate new mid points
var midx2:Number = bound.x + bound.width/2;
var midy2:Number = bound.y + bound.height/2;

// calculate differnece between the current mid and (x,y) and subtract
 //it to position the object in the previous bound.
var diff:Number = midx2 - obj.x;
obj.x -= diff;
diff = midy2 - obj.y;
obj.y -= diff;
}

//////////////////

Usage:

you can use the above function as described below,

var img:Canvas = new Canvas()
RotateAroundCenter(img, rotation);

This will help you

REf: http://subashflash.blogspot.in/2010/08/rotation-of-object-based-on-center.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM