The Flex provides a lots of functions about Matrix Transformation functions. Using these matrix functions, we can implements 2D transformation in a very easy way. For 2D transformation, the most common transformation is Translate, Scale, Rotate, and Skew. By default, all these transformations are according to the Top-Left point, (0, 0) point. For example, when we set a rotation as 45 in a canvas, the canvas will rotate 90 degrees around (0,0), as figure 1 shown. The Scale and Skew also use the same rule to transformation. But lots of times, we want to rotate a canvas, movieclip, or an image, around a certain point, for example, rotate it around center point, as figure 2 shown. In this post, I will show you how to make a rotation around a point.

Default Rotation ExampleRotate Around Center Example


We need to decide a rotation point first. In my example, I will use the center point as the rotation point. Here, we need to understand that the coordinate of the rotation point should be basing on the rotation object. That means if the rotation object width and height are 100×100, the point coordinate will be (50, 50), the center point. Then we follow the 4 steps:

  1. Get the new point basing on the current matrix;
  2. Translate the object to the new point;
  3. Rotate the object
  4. Translate the object back from the new point;

In this way, we can rotate the object around the point, regardless the object has already other matrix transforms. Below is the code example:

var aroundPoint:Point = resetCenterPoint(displayObj, displayObj.width/2, displayObj.height/2);
(displayObj as DisplayObject).addEventListener(MouseEvent.CLICK, clickHandler);

function clickHandler(event:MouseEvent):void
{
rotate(displayObj, 45, aroundPoint.x, aroundPoint.y);
}

function resetCenterPoint(obj:DisplayObject, orgX:Number, orgY:Number):Point
{
var m:Matrix = obj.transform.matrix;

var orgXY:Point = m.deltaTransformPoint(new Point(orgX, orgY));
orgXY.x += m.tx;
orgXY.y += m.ty;
return orgXY;
}

function rotate(obj:DisplayObject, angle:Number, aroundX:Number, aroundY:Number):void
{
var m:Matrix = obj.transform.matrix;

//var orgXY:Point = resetCenterPoint(obj, obj.width/2, obj.height/2);

var cm:Matrix = new Matrix(1, 0, 0, 1, -aroundX, -aroundY);
m.concat(cm);

m.rotate(Math.PI * angle / 180);

var rcm:Matrix = new Matrix(1, 0, 0, 1, aroundX, aroundY);
m.concat(rcm);

obj.transform.matrix = m;
}

Download Source Code

Previous PostNext Post

10 Comments

  1. In the rotate function you don’t need to create new matrices for the translations.

    Calling the translate function should be the same as creating an identity matrix, applying the translate, then concatenating this matrix with your object matrix.

    var m:Matrix = obj.transform.matrix;
    m.translate( -aroundX, -aroundY );
    m.rotate(Math.PI * angle / 180);
    m.translate( aroundX, aroundY );
    obj.transform.matrix = m;

    1. Yes, this way is only working when there is not any other transform. If you want to rotate a transformed object, one matrix will be hard to do it.

      For example, you scale the object, then rotate.

  2. Hi,

    Thanks a lot for the code….however, when I try the rotation by 1 degree….the square’s position is changed with every 360 rotation. I tried 1 degree because i want to have angle determined by mouse drag on the square which would vary from low to high values.

    Please let me know if this problem can be worked around.

    Thanks

Leave a Reply to Amit Tamse Cancel reply

Your email address will not be published. Required fields are marked *