W3C home > Mailing lists > Public > public-css-commits@w3.org > February 2012

csswg/css3-transforms Overview.html,1.21,1.22 Transforms.src.html,1.24,1.25 ChangeLog,1.11,1.12

From: Dirk Schulze via cvs-syncmail <cvsmail@w3.org>
Date: Fri, 10 Feb 2012 23:41:05 +0000
To: public-css-commits@w3.org
Message-Id: <E1Rw05R-0004aN-4K@lionel-hutz.w3.org>
Update of /sources/public/csswg/css3-transforms
In directory hutz:/tmp/cvs-serv17609

Modified Files:
	Overview.html Transforms.src.html ChangeLog 
Log Message:
2012-02-10 dschulze@adobe.com
    Backported 3D decomposing code from FX Transforms.
    Backported "Transitions and animations between transform values" from CSS 3D Transforms.
    Added 'skew' to the list of transformation functions for transitions and animations.
    Replaced bogus link to C file by an internal link to decomposing code.

Index: Overview.html
===================================================================
RCS file: /sources/public/csswg/css3-transforms/Overview.html,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- Overview.html	10 Feb 2012 05:38:04 -0000	1.21
+++ Overview.html	10 Feb 2012 23:41:02 -0000	1.22
@@ -1553,21 +1553,21 @@
     &lsquo;<code class=property>to</code>&rsquo; transforms are both single
     functions of the same type:
     <ul>
-     <li> For translate, translateX, translateY, scale, scaleX, scaleY,
-      rotate, skew, skewX and skewY functions:
+     <li> For translate, translate3d, translateX, translateY, translateZ,
+      scale, scale3d, scaleX, scaleY, scaleZ, rotate, rotateX, rotateY,
+      rotateZ, skew, skewX and skewY functions:
       <ul>
        <li> the individual components of the function are interpolated
         numerically.
       </ul>
 
-     <li> For matrix:
+     <li> For perspective, matrix, matrix3d and rotate3d:
       <ul>
-       <li> the matrix is decomposed using <a
-        href="http://tog.acm.org/GraphicsGems/gemsii/unmatrix.c">the method
-        described by unmatrix</a> into separate translation, scale, rotation
-        and skew matrices, then each decomposed matrix is interpolated
-        numerically, and finally combined in order to produce a resulting 3x2
-        matrix.
+       <li> the values are first converted to a 4x4 matrix, then decomposed
+        using <a href="#unmatrix">the method described by unmatrix</a> into
+        separate translation, scale, rotation, skew and perspective matrices,
+        then each decomposed matrix is interpolated numerically, and finally
+        combined in order to produce a resulting 4x4 matrix.
       </ul>
     </ul>
 
@@ -1594,9 +1594,12 @@
        rotate(50deg)" then the animation will execute as if the &lsquo;<code
        class=property>from</code>&rsquo; value is "scale(1) rotate(0)".</p>
 
-      <p> The identity functions are translate(0), translateX(0),
-       translateY(0), scale(1), scaleX(1), scaleY(1), rotate(0), skewX(0),
-       skewY(0) and matrix(1, 0, 0, 1, 0, 0).</p>
+      <p> The identity functions are translate(0), translate3d(0, 0, 0),
+       translateX(0), translateY(0), translateZ(0), scale(1), scale3d(1, 1,
+       1), scaleX(1), scaleY(1), scaleZ(1), rotate(0), rotate3d(1, 1, 1, 0),
+       rotateX(0), rotateY(0), rotateZ(0), skew(0), skewX(0), skewY(0),
+       matrix(1, 0, 0, 1, 0, 0) and matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
+       0, 0, 0, 0, 1).</p>
     </ul>
 
    <li> If both the &lsquo;<code class=property>from</code>&rsquo; and
@@ -1606,14 +1609,14 @@
     <ul>
      <li> Each transform function is animated with its corresponding
       destination function in isolation using the rules described above. The
-      individual values are then applied as a list to produce the resulting
+      individual values are then applied as a list to produce resulting
       transform value.
     </ul>
 
    <li> Otherwise:
     <ul>
      <li> The transform function lists are each converted into the equivalent
-      matrix value and animation proceeds using the rule for a single
+      matrix3d value and animation proceeds using the rule for a single
       function above.
     </ul>
   </ul>
@@ -1627,66 +1630,147 @@
    decomposition for animation</h2>
 
   <p> When interpolating between 2 matrices, each is decomposed into the
-   corresponding translation, rotation, scale and skew values. Not all
-   matrices can be accurately described by these values. Those that can't are
-   decomposed into the most accurate representation possible, using the
-   technique below. This technique is taken from The "unmatrix" method in
-   "Graphics Gems II, edited by Jim Arvo", simplified for the 2D case.
+   corresponding translation, rotation, scale, skew and perspective values.
+   Not all matrices can be accurately described by these values. Those that
+   can't are decomposed into the most accurate representation possible, using
+   the technique below. This technique is taken from the "unmatrix" method in
+   "Graphics Gems II, edited by Jim Arvo". The pseudocode below works on a
+   4x4 homogeneous matrix. A 3x2 2D matrix is therefore first converted to
+   4x4 homogeneous form.
 
   <h3 id=unmatrix><span class=secno>15.1. </span>Unmatrix</h3>
 
   <pre>
-          Input:  a, b, c, d ; 2x2 matrix (rotate, scale, shear) components
-                  tx, ty     ; translation components
-          Output: translate  ; a 2 component vector
-                  rotate     ; an angle
-                  scale      ; a 2 component vector
-                  skew       ; skew factor
+          Input:  matrix      ; a 4x4 matrix
+          Output: translation ; a 3 component vector
+                  rotation    ; Euler angles, represented as a 3 component vector
+                  scale       ; a 3 component vector
+                  skew        ; skew factors XY,XZ,YZ represented as a 3 component vector
+                  perspective ; a 4 component vector
           Returns false if the matrix cannot be decomposed, true if it can
 
-          Supporting functions (point is a 2 component vector):
-            float  length(point)                returns the length of the passed vector
+          Supporting functions (point is a 3 component vector, matrix is a 4x4 matrix):
+            double  determinant(matrix)         returns the 4x4 determinant of the matrix
+            matrix inverse(matrix)              returns the inverse of the passed matrix
+            matrix transpose(matrix)            returns the transpose of the passed matrix
+            point  multVecMatrix(point, matrix) multiplies the passed point by the passed matrix 
+                                                and returns the transformed point
+            double  length(point)               returns the length of the passed vector
             point  normalize(point)             normalizes the length of the passed point to 1
-            float  dot(point, point)            returns the dot product of the passed points
-            float  atan2(float y, float x)      returns the principal value of the arc tangent of 
+            double  dot(point, point)           returns the dot product of the passed points
+            double  cos(double)                 returns the cosine of the passed angle in radians
+            double  asin(double)                returns the arcsine in radians of the passed value
+            double  atan2(double y, double x)   returns the principal value of the arc tangent of 
                                                 y/x, using the signs of both arguments to determine 
                                                 the quadrant of the return value
 
           Decomposition also makes use of the following function:
-            point combine(point a, point b, float ascl, float bscl)
+            point combine(point a, point b, double ascl, double bscl)
                 result[0] = (ascl * a[0]) + (bscl * b[0])
                 result[1] = (ascl * a[1]) + (bscl * b[1])
+                result[2] = (ascl * a[2]) + (bscl * b[2])
                 return result
 
-          // Make sure the matrix is invertible
-          if ((a * d - b * c) == 0)
-            return false
+          // Normalize the matrix.
+          if (matrix[3][3] == 0)
+              return false
 
-          // Take care of translation
-          translate[0] = tx
+          for (i = 0; i < 4; i++)
+              for (j = 0; j < 4; j++)
+                  matrix[i][j] /= matrix[3][3]
+
+          // perspectiveMatrix is used to solve for perspective, but it also provides
+          // an easy way to test for singularity of the upper 3x3 component.
+          perspectiveMatrix = matrix
+
+          for (i = 0; i < 3; i++)
+              perspectiveMatrix[i][3] = 0
+
+          perspectiveMatrix[3][3] = 1
+
+          if (determinant(perspectiveMatrix) == 0)
+              return false
+
+          // First, isolate perspective.
+          if (matrix[0][3] != 0 || matrix[1][3] != 0 || matrix[2][3] != 0)
+              // rightHandSide is the right hand side of the equation.
+              rightHandSide[0] = matrix[0][3];
+              rightHandSide[1] = matrix[1][3];
+              rightHandSide[2] = matrix[2][3];
+              rightHandSide[3] = matrix[3][3];
+
+              // Solve the equation by inverting perspectiveMatrix and multiplying
+              // rightHandSide by the inverse.
+              inversePerspectiveMatrix = inverse(perspectiveMatrix)
+              transposedInversePerspectiveMatrix = transposeMatrix4(inversePerspectiveMatrix)
+              perspective = multVecMatrix(rightHandSide, transposedInversePerspectiveMatrix)
+
+               // Clear the perspective partition
+              matrix[0][3] = matrix[1][3] = matrix[2][3] = 0
+              matrix[3][3] = 1
+          else
+              // No perspective.
+              perspective[0] = perspective[1] = perspective[2] = 0
+              perspective[3] = 1
+
+          // Next take care of translation
+          translate[0] = matrix[3][0]
+          matrix[3][0] = 0
           translate[1] = matrix[3][1]
+          matrix[3][1] = 0
+          translate[2] = matrix[3][2]
+          matrix[3][2] = 0
 
-          // Put the components into a 2x2 matrix 'mat'
-          mat[0][0] = a
-          mat[0][1] = b
-          mat[1][0] = c
-          mat[1][1] = d
+          // Now get scale and shear. 'row' is a 3 element array of 3 component vectors
+          for (i = 0; i < 3; i++)
+              row[i][0] = matrix[i][0]
+              row[i][1] = matrix[i][1]
+              row[i][2] = matrix[i][2]
 
           // Compute X scale factor and normalize first row.
           scale[0] = length(row[0])
           row[0] = normalize(row[0])
 
-          // Compute shear factor and make 2nd row orthogonal to 1st.
-          skew = dot(row[0], row[1])
-          row[1] = combine(row[1], row[0], 1.0, -skew)
+          // Compute XY shear factor and make 2nd row orthogonal to 1st.
+          skew[0] = dot(row[0], row[1])
+          row[1] = combine(row[1], row[0], 1.0, -skew[0])
 
           // Now, compute Y scale and normalize 2nd row.
           scale[1] = length(row[1])
           row[1] = normalize(row[1])
-          skew /= scale[1];
+          skew[0] /= scale[1];
 
-          // Now, get the rotation out
-          rotate = atan2(mat[0][1], mat[0][0])
+          // Compute XZ and YZ shears, orthogonalize 3rd row
+          skew[1] = dot(row[0], row[2])
+          row[2] = combine(row[2], row[0], 1.0, -skew[1])
+          skew[2] = dot(row[1], row[2])
+          row[2] = combine(row[2], row[1], 1.0, -skew[2])
+
+          // Next, get Z scale and normalize 3rd row.
+          scale[2] = length(row[2])
+          row[2] = normalize(row[2])
+          skew[1] /= scale[2]
+          skew[2] /= scale[2]
+
+          // At this point, the matrix (in rows) is orthonormal.
+          // Check for a coordinate system flip.  If the determinant
+          // is -1, then negate the matrix and the scaling factors.
+          pdum3 = cross(row[1], row[2])
+          if (dot(row[0], pdum3) < 0)
+              for (i = 0; i < 3; i++) {
+                  scale[0] *= -1;
+                  row[i][0] *= -1
+                  row[i][1] *= -1
+                  row[i][2] *= -1
+
+          // Now, get the rotations ou
+          rotate[1] = asin(-row[0][2]);
+          if (cos(rotate[1]) != 0)
+             rotate[0] = atan2(row[1][2], row[2][2]);
+             rotate[2] = atan2(row[0][1], row[0][0]);
+          else
+             rotate[0] = atan2(-row[2][0], row[1][1]);
+             rotate[2] = 0;
 
           return true;</pre>
 
@@ -1705,21 +1789,20 @@
   <p><em>This section is not normative.</em>
 
   <p> After interpolation the resulting values are used to position the
-   element. One way to use these values is to recompose them into a 3x2
+   element. One way to use these values is to recompose them into a 4x4
    matrix. This can be done using the Transformation Functions of the <a
-   href="#effects"><em>transform</em></a> property. The following JavaScript
-   example produces a string for this purpose. The values passed in are the
-   output of the Unmatrix function above:
+   href="#effects"><em>transform</em></a> property. This can be done by the
+   following pseudo code. The values passed in are the output of the Unmatrix
+   function above:
 
   <pre>
-        function compose(translate, rotate, scale, skew, elementID)
-        {
-            var s = " translate(" + translate[0] + ", " + translate[1] + ")";
-            s += " rotate(" + rotate + ")";
-            s += " skewX(" + skew + ")";
-            s += " scale(" + scale[0] + ", " + scale[1] + ")";
-            document.getElementById(elementID).style.transform = s;
-        }</pre>
+          matrix3d(1,0,0,0, 0,1,0,0, 0,0,1,0, perspective[0], perspective[1], perspective[2], perspective[3])
+          translate3d(translation[0], translation[1], translation[2])
+          rotateX(rotation[0]) rotateY(rotation[1]) rotateZ(rotation[2])
+          matrix3d(1,0,0,0, 0,1,0,0, 0,skew[2],1,0, 0,0,0,1)
+          matrix3d(1,0,0,0, 0,1,0,0, skew[1],0,1,0, 0,0,0,1)
+          matrix3d(1,0,0,0, skew[0],1,0,0, 0,0,1,0, 0,0,0,1)
+          scale3d(scale[0], scale[1], scale[2])</pre>
 
   <h2 id=dom-interfaces><span class=secno>16. </span> DOM Interfaces</h2>
 

Index: Transforms.src.html
===================================================================
RCS file: /sources/public/csswg/css3-transforms/Transforms.src.html,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- Transforms.src.html	10 Feb 2012 05:38:04 -0000	1.24
+++ Transforms.src.html	10 Feb 2012 23:41:02 -0000	1.25
@@ -1405,8 +1405,9 @@
                   of the same type:
                   <ul>
                     <li>
-                      For translate, translateX, translateY, scale,
-                      scaleX, scaleY, rotate, skew, skewX and skewY functions:
+                      For translate, translate3d, translateX, translateY, translateZ, scale,
+                      scale3d, scaleX, scaleY, scaleZ, rotate, rotateX, rotateY, rotateZ, skew, skewX
+                      and skewY functions:
                         <ul>
                           <li>
                             the individual components of the function are
@@ -1415,16 +1416,16 @@
                         </ul>
                     </li>
                     <li>
-                      For matrix:
+                      For perspective, matrix, matrix3d and rotate3d:
                         <ul>
                           <li>
-                            the matrix is
+                            the values are first converted to a 4x4 matrix, then
                             decomposed using <a
-                            href="http://tog.acm.org/GraphicsGems/gemsii/unmatrix.c">the
+                            href="#unmatrix">the
                             method described by unmatrix</a> into separate translation,
-                            scale, rotation and skew matrices, then each
+                            scale, rotation, skew and perspective matrices, then each
                             decomposed matrix is interpolated numerically, and finally
-                            combined in order to produce a resulting 3x2 matrix.
+                            combined in order to produce a resulting 4x4 matrix.
                           </li>
                         </ul>
                     </li>
@@ -1453,9 +1454,12 @@
                         if the 'from' value is "scale(1) rotate(0)".
                       </p>
                       <p>
-                        The identity functions are translate(0), 
-                        translateX(0), translateY(0), scale(1), scaleX(1), scaleY(1), rotate(0),
-                        skewX(0), skewY(0) and matrix(1, 0, 0, 1, 0, 0).
+                        The identity functions are translate(0), translate3d(0, 0, 0),
+                        translateX(0), translateY(0), translateZ(0), scale(1), scale3d(1, 1, 1),
+                        scaleX(1), scaleY(1), scaleZ(1), rotate(0), rotate3d(1, 1, 1, 0),
+                        rotateX(0), rotateY(0), rotateZ(0), skew(0), skewX(0), skewY(0),
+                        matrix(1, 0, 0, 1, 0, 0) and
+                        matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1).
                       </p>
                     </li>
                   </ul>
@@ -1468,7 +1472,7 @@
                     <li>
                       Each transform function is animated with its corresponding
                       destination function in isolation using the rules described above.
-                      The individual values are then applied as a list to produce the
+                      The individual values are then applied as a list to produce
                       resulting transform value.
                     </li>
                   </ul>
@@ -1478,7 +1482,7 @@
                   <ul>
                     <li>
                       The transform function lists are each converted into the
-                      equivalent matrix value and animation proceeds using the rule
+                      equivalent matrix3d value and animation proceeds using the rule
                       for a single function above.
                     </li>
                   </ul>
@@ -1498,67 +1502,147 @@
 
               <p>
                 When interpolating between 2 matrices, each is decomposed into the
-                corresponding translation, rotation, scale and skew
+                corresponding translation, rotation, scale, skew and perspective
                 values. Not all matrices can be accurately described by these values.
                 Those that can't are decomposed into the most accurate representation
-                possible, using the technique below. This technique is taken from The
-                "unmatrix" method in "Graphics Gems II, edited by Jim Arvo", simplified
-                for the 2D case.
+                possible, using the technique below. This technique is taken from the
+                "unmatrix" method in "Graphics Gems II, edited by Jim Arvo".
+                The pseudocode below works on a 4x4 homogeneous matrix. A 3x2 2D matrix
+                is therefore first converted to 4x4 homogeneous form.
               </p>
 
               <h3 id="unmatrix">Unmatrix</h3>
               <pre>
-          Input:  a, b, c, d ; 2x2 matrix (rotate, scale, shear) components
-                  tx, ty     ; translation components
-          Output: translate  ; a 2 component vector
-                  rotate     ; an angle
-                  scale      ; a 2 component vector
-                  skew       ; skew factor
+          Input:  matrix      ; a 4x4 matrix
+          Output: translation ; a 3 component vector
+                  rotation    ; Euler angles, represented as a 3 component vector
+                  scale       ; a 3 component vector
+                  skew        ; skew factors XY,XZ,YZ represented as a 3 component vector
+                  perspective ; a 4 component vector
           Returns false if the matrix cannot be decomposed, true if it can
 
-          Supporting functions (point is a 2 component vector):
-            float  length(point)                returns the length of the passed vector
+          Supporting functions (point is a 3 component vector, matrix is a 4x4 matrix):
+            double  determinant(matrix)         returns the 4x4 determinant of the matrix
+            matrix inverse(matrix)              returns the inverse of the passed matrix
+            matrix transpose(matrix)            returns the transpose of the passed matrix
+            point  multVecMatrix(point, matrix) multiplies the passed point by the passed matrix 
+                                                and returns the transformed point
+            double  length(point)               returns the length of the passed vector
             point  normalize(point)             normalizes the length of the passed point to 1
-            float  dot(point, point)            returns the dot product of the passed points
-            float  atan2(float y, float x)      returns the principal value of the arc tangent of 
+            double  dot(point, point)           returns the dot product of the passed points
+            double  cos(double)                 returns the cosine of the passed angle in radians
+            double  asin(double)                returns the arcsine in radians of the passed value
+            double  atan2(double y, double x)   returns the principal value of the arc tangent of 
                                                 y/x, using the signs of both arguments to determine 
                                                 the quadrant of the return value
 
           Decomposition also makes use of the following function:
-            point combine(point a, point b, float ascl, float bscl)
+            point combine(point a, point b, double ascl, double bscl)
                 result[0] = (ascl * a[0]) + (bscl * b[0])
                 result[1] = (ascl * a[1]) + (bscl * b[1])
+                result[2] = (ascl * a[2]) + (bscl * b[2])
                 return result
 
-          // Make sure the matrix is invertible
-          if ((a * d - b * c) == 0)
-            return false
+          // Normalize the matrix.
+          if (matrix[3][3] == 0)
+              return false
 
-          // Take care of translation
-          translate[0] = tx
+          for (i = 0; i < 4; i++)
+              for (j = 0; j < 4; j++)
+                  matrix[i][j] /= matrix[3][3]
+
+          // perspectiveMatrix is used to solve for perspective, but it also provides
+          // an easy way to test for singularity of the upper 3x3 component.
+          perspectiveMatrix = matrix
+
+          for (i = 0; i < 3; i++)
+              perspectiveMatrix[i][3] = 0
+
+          perspectiveMatrix[3][3] = 1
+
+          if (determinant(perspectiveMatrix) == 0)
+              return false
+
+          // First, isolate perspective.
+          if (matrix[0][3] != 0 || matrix[1][3] != 0 || matrix[2][3] != 0)
+              // rightHandSide is the right hand side of the equation.
+              rightHandSide[0] = matrix[0][3];
+              rightHandSide[1] = matrix[1][3];
+              rightHandSide[2] = matrix[2][3];
+              rightHandSide[3] = matrix[3][3];
+
+              // Solve the equation by inverting perspectiveMatrix and multiplying
+              // rightHandSide by the inverse.
+              inversePerspectiveMatrix = inverse(perspectiveMatrix)
+              transposedInversePerspectiveMatrix = transposeMatrix4(inversePerspectiveMatrix)
+              perspective = multVecMatrix(rightHandSide, transposedInversePerspectiveMatrix)
+
+               // Clear the perspective partition
+              matrix[0][3] = matrix[1][3] = matrix[2][3] = 0
+              matrix[3][3] = 1
+          else
+              // No perspective.
+              perspective[0] = perspective[1] = perspective[2] = 0
+              perspective[3] = 1
+
+          // Next take care of translation
+          translate[0] = matrix[3][0]
+          matrix[3][0] = 0
           translate[1] = matrix[3][1]
+          matrix[3][1] = 0
+          translate[2] = matrix[3][2]
+          matrix[3][2] = 0
 
-          // Put the components into a 2x2 matrix 'mat'
-          mat[0][0] = a
-          mat[0][1] = b
-          mat[1][0] = c
-          mat[1][1] = d
+          // Now get scale and shear. 'row' is a 3 element array of 3 component vectors
+          for (i = 0; i < 3; i++)
+              row[i][0] = matrix[i][0]
+              row[i][1] = matrix[i][1]
+              row[i][2] = matrix[i][2]
 
           // Compute X scale factor and normalize first row.
           scale[0] = length(row[0])
           row[0] = normalize(row[0])
 
-          // Compute shear factor and make 2nd row orthogonal to 1st.
-          skew = dot(row[0], row[1])
-          row[1] = combine(row[1], row[0], 1.0, -skew)
+          // Compute XY shear factor and make 2nd row orthogonal to 1st.
+          skew[0] = dot(row[0], row[1])
+          row[1] = combine(row[1], row[0], 1.0, -skew[0])
 
           // Now, compute Y scale and normalize 2nd row.
           scale[1] = length(row[1])
           row[1] = normalize(row[1])
-          skew /= scale[1];
+          skew[0] /= scale[1];
 
-          // Now, get the rotation out
-          rotate = atan2(mat[0][1], mat[0][0])
+          // Compute XZ and YZ shears, orthogonalize 3rd row
+          skew[1] = dot(row[0], row[2])
+          row[2] = combine(row[2], row[0], 1.0, -skew[1])
+          skew[2] = dot(row[1], row[2])
+          row[2] = combine(row[2], row[1], 1.0, -skew[2])
+
+          // Next, get Z scale and normalize 3rd row.
+          scale[2] = length(row[2])
+          row[2] = normalize(row[2])
+          skew[1] /= scale[2]
+          skew[2] /= scale[2]
+
+          // At this point, the matrix (in rows) is orthonormal.
+          // Check for a coordinate system flip.  If the determinant
+          // is -1, then negate the matrix and the scaling factors.
+          pdum3 = cross(row[1], row[2])
+          if (dot(row[0], pdum3) < 0)
+              for (i = 0; i < 3; i++) {
+                  scale[0] *= -1;
+                  row[i][0] *= -1
+                  row[i][1] *= -1
+                  row[i][2] *= -1
+
+          // Now, get the rotations ou
+          rotate[1] = asin(-row[0][2]);
+          if (cos(rotate[1]) != 0)
+             rotate[0] = atan2(row[1][2], row[2][2]);
+             rotate[2] = atan2(row[0][1], row[0][0]);
+          else
+             rotate[0] = atan2(-row[2][0], row[1][1]);
+             rotate[2] = 0;
 
           return true;</pre>
 
@@ -1573,20 +1657,18 @@
               <p><em>This section is not normative.</em></p>
               <p>
                   After interpolation the resulting values are used to position the element. One way to use these values
-                  is to recompose them into a 3x2 matrix. This can be done using the Transformation Functions of the 
-                  <em>transform</em> property. The following JavaScript example produces a string for this purpose. The
+                  is to recompose them into a 4x4 matrix. This can be done using the Transformation Functions of the 
+                  <em>transform</em> property. This can be done by the following pseudo code. The
                   values passed in are the output of the Unmatrix function above:
-
               </p>
               <pre>
-        function compose(translate, rotate, scale, skew, elementID)
-        {
-            var s = " translate(" + translate[0] + ", " + translate[1] + ")";
-            s += " rotate(" + rotate + ")";
-            s += " skewX(" + skew + ")";
-            s += " scale(" + scale[0] + ", " + scale[1] + ")";
-            document.getElementById(elementID).style.transform = s;
-        }</pre>
+          matrix3d(1,0,0,0, 0,1,0,0, 0,0,1,0, perspective[0], perspective[1], perspective[2], perspective[3])
+          translate3d(translation[0], translation[1], translation[2])
+          rotateX(rotation[0]) rotateY(rotation[1]) rotateZ(rotation[2])
+          matrix3d(1,0,0,0, 0,1,0,0, 0,skew[2],1,0, 0,0,0,1)
+          matrix3d(1,0,0,0, 0,1,0,0, skew[1],0,1,0, 0,0,0,1)
+          matrix3d(1,0,0,0, skew[0],1,0,0, 0,0,1,0, 0,0,0,1)
+          scale3d(scale[0], scale[1], scale[2])</pre>
 
               <h2 id="dom-interfaces">
                 DOM Interfaces

Index: ChangeLog
===================================================================
RCS file: /sources/public/csswg/css3-transforms/ChangeLog,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- ChangeLog	10 Feb 2012 05:38:04 -0000	1.11
+++ ChangeLog	10 Feb 2012 23:41:03 -0000	1.12
@@ -1,9 +1,16 @@
+2012-02-10 dschulze@adobe.com
+    Backported 3D decomposing code from FX Transforms.
+    Backported "Transitions and animations between transform values" from CSS 3D Transforms.
+    Added 'skew' to the list of transformation functions for transitions and animations.
+    Replaced bogus link to C file by an internal link to decomposing code.
+
 2012-02-09 dschulze@adobe.com
     Introduce new term 'bounding box'.
     Specify transform origin for SVG elements.
     Change float to double for CSSOM.
     Added two optional offset arguments for rotate().
     Changed Z argument type to <length> in translateZ() and translate3d().
+    Removed link from translateZ() to SVG (was 2D translate).
     Removed solved issues.
 
 2012-02-07 simon.fraser@apple.com
Received on Friday, 10 February 2012 23:41:07 UTC

This archive was generated by hypermail 2.3.1 : Tuesday, 6 January 2015 20:44:50 UTC