1 | /*
|
2 | Unmatrix 2d
|
3 | - a crude implementation of the slightly bugged pseudo code in http://www.w3.org/TR/css3-2d-transforms/#matrix-decomposition
|
4 | */"use strict"
|
5 |
|
6 | // returns the length of the passed vector
|
7 |
|
8 | var length = function(a){
|
9 | return Math.sqrt(a[0] * a[0] + a[1] * a[1])
|
10 | }
|
11 |
|
12 | // normalizes the length of the passed point to 1
|
13 |
|
14 | var normalize = function(a){
|
15 | var l = length(a)
|
16 | return l ? [a[0] / l, a[1] / l] : [0, 0]
|
17 | }
|
18 |
|
19 | // returns the dot product of the passed points
|
20 |
|
21 | var dot = function(a, b){
|
22 | return a[0] * b[0] + a[1] * b[1]
|
23 | }
|
24 |
|
25 | // returns the principal value of the arc tangent of
|
26 | // y/x, using the signs of both arguments to determine
|
27 | // the quadrant of the return value
|
28 |
|
29 | var atan2 = Math.atan2
|
30 |
|
31 | var combine = function(a, b, ascl, bscl){
|
32 | return [
|
33 | (ascl * a[0]) + (bscl * b[0]),
|
34 | (ascl * a[1]) + (bscl * b[1])
|
35 | ]
|
36 | }
|
37 |
|
38 | module.exports = function(a, b, c, d, tx, ty){
|
39 |
|
40 | // Make sure the matrix is invertible
|
41 |
|
42 | if ((a * d - b * c) === 0) return false
|
43 |
|
44 | // Take care of translation
|
45 |
|
46 | var translate = [tx, ty]
|
47 |
|
48 | // Put the components into a 2x2 matrix
|
49 |
|
50 | var m = [[a, b], [c, d]]
|
51 |
|
52 | // Compute X scale factor and normalize first row.
|
53 |
|
54 | var scale = [length(m[0])]
|
55 | m[0] = normalize(m[0])
|
56 |
|
57 | // Compute shear factor and make 2nd row orthogonal to 1st.
|
58 |
|
59 | var skew = dot(m[0], m[1])
|
60 | m[1] = combine(m[1], m[0], 1, -skew)
|
61 |
|
62 | // Now, compute Y scale and normalize 2nd row.
|
63 |
|
64 | scale[1] = length(m[1])
|
65 | // m[1] = normalize(m[1]) //
|
66 | skew /= scale[1]
|
67 |
|
68 | // Now, get the rotation out
|
69 |
|
70 | var rotate = atan2(m[0][1], m[0][0])
|
71 |
|
72 | return [translate, rotate, skew, scale]
|
73 |
|
74 | }
|