Scale MovieClip From Center With Top-Left Registration

A lot of times I’ve found myself needing the ability to scale a movieclip from the center that has a registration point in the top left.  I searched around looking for a solution, but all of the answers I received told me just to move the registration point, or to put the movieclip inside of another empty movieclip.

Both of these suggestions, while they do work well, leave me wanting a better solution.  A lot of times, you don’t have control over the position of the registration point (especially if it’s been externally loaded), and nesting movieclips makes you’re code messy and adds another layer of management to the display stack.  Also, if you have any sort of grid class you’ve already developed (as I had) that aligned display objects based on a top-left registration point, neither of these solutions were viable.

There are other solutions that involve the matrix class and changing the registration with code, but this seems like an awful lot of work for what ends up being a very simple effect.  Below is the result of a little time spent tinkering around one day and figuring out how to do this with a minimal amount of code and some (very) simple math:

var scaleAmount:Number = .1;

var button:Sprite = new Sprite();
button.graphics.beginFill(0x000000);
button.graphics.drawRect(0, 0, 100, 100);
button.graphics.endFill();

button.addEventListener(MouseEvent.ROLL_OVER, _onOver);
button.addEventListener(MouseEvent.ROLL_OUT, _onOut);
this.addChild(button);

function _onOver(event:MouseEvent):void
{
	var prevWidth:Number = event.target.width;
	var prevHeight:Number = event.target.height;

	event.target.scaleX = event.target.scaleY += scaleAmount;

	var diffX:Number = event.target.width - prevWidth;
	var diffY:Number = event.target.height - prevHeight;

	event.target.x -= diffX / 2;
	event.target.y -= diffY / 2;
}

function _onOut(event:MouseEvent):void
{
	var prevWidth:Number = event.target.width;
	var prevHeight:Number = event.target.height;

	var event.target.scaleX = event.target.scaleY -= scaleAmount;

	var diffX:Number = prevWidth - event.target.width;
	var diffY:Number = prevHeight - event.target.height;

	event.target.x += diffX / 2;
	event.target.y += diffY / 2;
}

The above code is fairly self explanatory.  There’s some very simple math here, where we store the width and height before we change the scale of the button.  Once we make the change, we offset the x & y based on the difference between the previouswidth and height, and the new width and height.  This gives the illusion that the button is actually scaling from the center, even though the registration point is still top left.

This by no means in the only solution, but it’s the quickest and easiest one I’ve found so far.  If anyone has any other solutions or can improve on the code above, feel free to leave a comment.

Also, note that this solution is only viable for a display object that has a registration point in the top left.

About Josh
Father of 3, programmer, husky owner, and a lover of geeky things. Find me on twitter @joshbjosh.

No Comments, Be The First!

Your email address will not be published.