niiyz
2/28/2015 - 10:33 PM

gistfile1.js

/*
This code takes a 2D transformation matrix described as a one-dimensional array 
(in column order, top to bottom and left to right) and decomposes it using the dojo
matrix library.  This input matrix should produce a 45-deg X skew:

  1 1 0
  0 1 0 
  0 0 1

The output of decompose() looks like this:

{
	angle1: -58.282525588538995,
	angle2: 31.71747441146101,
	dx: 0,
	dy: 0,
	sx: 1.6180339887498953,
	sy: 0.618033988749895
}

So two rotations and two scales presumably produce the skew, but there's no obvious way
to go from this to the 45-deg angle that could then be used in CSS3 skew transform, like
transform:skew(45deg);
*/

	dojo.require("dojox.gfx.decompose");

	function decompose(
		inMatrix)
	{
		var matrix = new dojox.gfx.matrix.Matrix2D({
			xx: inMatrix[0],
			yx: inMatrix[1],
			xy: inMatrix[3],
			yy: inMatrix[4],
			dx: inMatrix[6],
			dy: inMatrix[7]
		});

		var decomposed = dojox.gfx.decompose(matrix);

		decomposed.angle1 *= 180 / Math.PI;
		decomposed.angle2 *= 180 / Math.PI;

		return decomposed;
	}
	
	log(decompose([1, 0, 0, 1, 1, 0, 0, 0, 1]));


/*
Here's Aaron's ActionScript decomposition code, converted to JS so it can run in 
Fireworks.  You can do something like asDecompose(fw.selection[0].transform.matrix) to
decompose the transform of the current selection.
*/

	function Point(x, y)
	{
		return { x: x, y: y };
	}

	function matrixTransforms(matrix) {
		// calculate delta transform point
		var px = deltaTransformPoint(matrix, new Point(0, 1));
		var py = deltaTransformPoint(matrix, new Point(1, 0));

		// calculate skew
		var skewX = ((180 / Math.PI) * Math.atan2(px.y, px.x) - 90);
		var skewY = ((180 / Math.PI) * Math.atan2(py.y, py.x));

		return {
			translateX:matrix.tx,
			translateY:matrix.ty,
			scaleX:Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b),
			scaleY:Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d),
			skewX:skewX,
			skewY:skewY,
			rotation:skewX // rotation is the same as skew x
		}
	}

	function deltaTransformPoint(matrix, point)  {
		//return matrix.deltaTransformPoint(point);
		var dx = point.x * matrix.a + point.y * matrix.c + 0;
		var dy = point.x * matrix.b + point.y * matrix.d + 0;
		return new Point(dx, dy);
	}

	function asDecompose(
		inMatrix)
	{
		var matrix = {
			a: inMatrix[0],
			c: inMatrix[1],
			b: inMatrix[3],
			d: inMatrix[4],
			tx: inMatrix[6],
			ty: inMatrix[7]
		};
		
		return matrixTransforms(matrix);
	}