I was wanting a lightweight function to resize, rotate, and skew DisplayObjects based on a dynamic registration point so I made a function to apply my desired matrix settings.

One thing that bothers me is that I could not figure out how to skew along the X and Y axis at the same time. When I do set "c" and "b" Matrix properties, one of the skewed axis does not skew parallel like it should. And if I concatenate separate skew Matrices, the last concatenated skew Matrix transforms correctly but not the one before it. I'm trying to avoid using nested DisplayObjects to perform the separate X and Y skews, but that looks like an option I will have to use.


 
/*---------------------------------------------------------------------------
Sets the transform property of DisplayObject with a customized Matrix.
 
display			-An ActionScript DisplayObject.
tx					-Translation x.
ty					-Translation y.
reg				-Registation point from which all transform effects orient from.
ang				-Rotation in in degrees.
scalex				-X scale percentage.
scaley				-Y scale percentage.
skew				-Skew percentage of the DisplayObjects width or height.
axis				-String indicating which axis to skew on.
 
Note:	-The "skew" argument only works one axis at a time, If anyone knows
		 how to skew on both X and Y axis at the same time accurately please help me.
 
		-The "reg" Registration point get scaled by scalex and scaley.		 
 
----------------------------------------------------------------------------*/
function setDisplayMatrix(display:DisplayObject,
						  tx:Number=0,
						  ty:Number=0,
						  reg:Point=null,
						  ang:Number=0,
						  scalex:Number=1,
						  scaley:Number=1,
						  skew:Number=0,
						  axis:String="x"):void
{
	reg=reg||new Point();
	var curM:Matrix=new Matrix();
	var skewM:Matrix=new Matrix();
	var rotM:Matrix=new Matrix();
	var scaleM:Matrix=new Matrix();
	var rp:Point;
	var r:Number=ang*Math.PI/180;
	if(axis == "y"){
		skewM.c=Math.tan(skew);
	}else{
		skewM.b=Math.tan(skew);
	}
	scaleM.scale(scalex,scaley);
	rotM.rotate(r);
	curM.concat(scaleM);
	curM.concat(skewM);
	curM.concat(rotM);
	rp=curM.transformPoint(reg);
	curM.tx=-rp.x;
	curM.ty=-rp.y;
	curM.tx+=tx;
	curM.ty+=ty;
	display.transform.matrix=curM;
}
 

Here is a diagram I made to show what kind of skew I wanted to achieve instead of only skewing one axis at a time:
The type of skews I want to achieve.

Vote in HexoSearch
4 Responses to “Matrix transforms based on an arbitrary registration point”
  1. not sure if this is what you need, but try:

    skewAmount:Number=0;

    skewM.c=skewM.b=Math.tan(skewAmount);

    It performs skew on both axis in the same time

  2. simple, direct and clean. Thanks!

  3. Thanks Flanture, but I may be describing the kind of skew I want to do incorrectly. I would like to skew a separate value along the horizontal edge of the shape, and also skew a separate value along the vertical edge of the shape. I’ve updated this post with a diagram showing the kind of skew I’d like to do.

    To make the skewing run along the edges is what I wish to do. After skewing along the horizontal axis first, the vertical axis is different. Visa versa if I skewed along the vertical axis first.

  4. Matthew Clifford says:

    Hello Keith,

    This is an astonishingly good post and fantastic working example…

    Would you be willing to post a link to the source code for this, as it would be most appreciated?

    Kind regards,

    Matthew

Leave a Comment

Thanks for visiting www.keith-hair.net