Actionscript 3.0: Rotate Around Center Point

Problem:

You need to rotate a movieclip/sprite around it’s center point, but its registration point is at (0,0) and you can’t and/or don’t feel like putting this object in the center of a container movieclip and rotating that.

Solution:

Use the transform matrix and show it who’s boss.

If you want to get this done simply and quickly, you can use this rotateAroundCenter function:

 private function rotateAroundCenter (ob:*, angleDegrees:Number, ptRotationPoint:Point) {
      var m:Matrix=ob.transform.matrix;
      m.tx -= ptRotationPoint.x;
      m.ty -= ptRotationPoint.y;
      m.rotate (angleDegrees*(Math.PI/180));
      m.tx += ptRotationPoint.x;
      m.ty += ptRotationPoint.y;
      ob.transform.matrix=m;
 }

Now to make this work, you could call it like this:

//this will create a point object at the center of the display object
ptRotationPoint = new Point(mcPhoto.x + mcPhoto.width/2, mcPhoto.y+mcPhoto.height/2);
//call the function and pass in the object to be rotated, the amount in degrees, and the point object we created
rotateAroundCenter(mcPhoto, 90, ptRotationPoint);

There you go, that should work. If you want to take it further, Jack Doyle at Greensock.com (author of TweenLite) wrote an amazing class called TransformMatrixProxy which will allow you to easily do all types of transformations (including rotation and skewing) based on the registration point you specify. Oh, and you can tween these properties as well… hell yeah…

I haven’t tried it out myself yet, but the demo works great and I’m sure it’s a really great tool. Go check it out. A screen shot of the TransformMatrixProxy demo at greensock.com

11 Comments

  1. Thanx dude! The function works fine.

    Comment by Raj — July 22, 2008 @ 9:20 am

  2. Thanks a lot for posting this!

    Comment by niceBoat — September 9, 2008 @ 7:31 pm

  3. Ok it works, but why the hell didn’t they put centering properties in actionscript ? Isn’t this pure stupidity, given that it is still missing in CS4 ?

    Comment by Xav — November 19, 2008 @ 5:51 pm

  4. Well, keep in mind that it is also possible to center the contents of a movieclip so that the registration point sits in the middle. Then the normal “rotate” property would rotate around center. Yes, I’m surprised there isn’t a built in function that would do that for you. There’s probably a reason for it. This is a quick fix, although it is a very powerful because knowing how to use the Matrix class will enable you to do all kinds of image transformations. I imagine in the future the type of functionality that the “TransformMatrixProxy” offers might be built right in.

    Comment by rbosinger — November 19, 2008 @ 6:11 pm

  5. for me this does not work. It is rotating but not around the center. It looks like it works only first 2 or 3 rounds and then my Spite starts to decline. If anyone could help me, I add simple code:

    package
    {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.*;

    /**
    * …
    * @author tomas.teicher
    */
    public class Main extends Sprite
    {
    public var rect:Sprite;
    public var bod:Point;

    public function Main():void
    {
    if (stage) init();
    else addEventListener(Event.ADDED_TO_STAGE, init);
    }

    private function init(e:Event = null):void
    {
    removeEventListener(Event.ADDED_TO_STAGE, init);
    // entry point
    rect = new Sprite();
    rect.graphics.beginFill(0x00ff00);
    rect.graphics.drawRect(0, 0, 100, 100);
    rect.graphics.endFill();
    addChild(rect);

    bod = new Point(rect.x + rect.width/2, rect.y+rect.height/2);
    addEventListener(Event.ENTER_FRAME, this.enterFrameHandler);

    }

    private function rotateAroundCenter (ob:*, angleDegrees:Number, ptRotationPoint:Point):void {
    var m:Matrix=ob.transform.matrix;
    m.tx -= ptRotationPoint.x;
    m.ty -= ptRotationPoint.y;
    m.rotate (angleDegrees*(Math.PI/180));
    m.tx += ptRotationPoint.x;
    m.ty += ptRotationPoint.y;
    ob.transform.matrix=m;
    }

    function enterFrameHandler(event:Event):void {
    rotateAroundCenter (rect, 1, bod);
    }
    }

    }

    Comment by tomas.teicher — April 4, 2010 @ 5:56 am

  6. полет фантазии надо срочно остановить, а то улетит незнамо куда и не поймаешь :) )

    Comment by 3piotik — May 5, 2010 @ 9:31 am

  7. I have tried this and cannot get it to work on a rectangle. Seems all the transform matrix examples of rotation use a square or worse, a circle. These examples only seem to work ONCE on a rectangle. Subsequent calls to rotate the rectangel have it spriralling off the stage.

    Comment by James — June 5, 2010 @ 4:15 pm

  8. Hi,

    This approach has one disadvantage – the rotation is always relative to the previous rotation and after a large number of iterations rounding error is accumulated. A possible solution can be found here:

    http://itforum.webrichservices.com/viewtopic.php?f=127&t=14

    Thank you for your original posing anyway, it helped me to understand a bit better how Flash works…

    Comment by Daniel Apostolov — August 6, 2010 @ 12:53 pm

  9. Have a look at this page.

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

    Comment by Subash — August 20, 2010 @ 2:16 pm

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

    excellent code! THANK YOU!!!

    Comment by Girit — May 26, 2011 @ 9:02 am

  11. That ‘s great!! I did and got it work fine. The last problem I have to solve that we have to back it to rotation zero before rotate it any new rotation.

    Comment by Pham Hong Phuc — June 19, 2011 @ 3:08 am

Sorry, the comment form is closed at this time.