matrix/index.html

Thu, 14 Mar 2013 21:41:18 -0700

author
Dirk Schulze <dschulze@adobe.com>
date
Thu, 14 Mar 2013 21:41:18 -0700
changeset 748
5a64938d0a49
parent 741
cd0593275768
child 766
df1c1e64dfa5
permissions
-rw-r--r--

Incorporate feedback from Robert O'Callahan.

     1 <!DOCTYPE html>
     2 <html>
     3   <head>
     4     <title>Transformation matrix interface</title>
     5     <meta charset='utf-8'>
     6     <!--<script src='respec-w3c-common.js' class='remove'></script>-->
     7     <script src="respec/respec.js" class="remove"></script>
     8     <script class='remove'>
     9       var respecConfig = {
    10           specStatus:           "ED",
    11           shortName:            "matrix",
    12           edDraftURI:           "https://dvcs.w3.org/hg/FXTF/raw-file/default/matrix/index.html",
    13           editors:  {name: "none"},//[
    14               //{ name: "Dirk Schulze", mailto: "dschulze@adobe.com",
    15               //  company: "Adobe Systems Inc.", companyURL: "http://adobe.com/" },
    16           //],
    17           extraCSS: ["respec/respec.css",
    18                      "matrix.css"],
    19           // Turning off inlineCSS for now since if extraCSS points to
    20           // a relative URL your testing from a file URL the XHR will fail.
    21           // Probably should turn this back on once this is hosted on a server
    22           // somewhere.
    23           inlineCSS: false,
    24           wg: [ "CSS Working Group",
    25                 "SVG Working Group" ],
    26           wgURI: [ "http://dev.w3.org/Style/CSS/members",
    27                    "http://www.w3.org/Graphics/SVG/WG" ],
    29           wgActivity: [ 
    30             [ "Style",    "http://www.w3.org/Style/Activity" ],
    31             [ "Graphics", "http://www.w3.org/Graphics/Activity" ]
    32           ],          
    33           // name (without the @w3c.org) of the public mailing to which comments are due
    34           wgPublicList: "public-fx",
    35           wgPatentURI:  "",
    36           noIDLIn:  true,
    37       };
    38     </script>
    39   </head>
    40   <body>
    41     <section id='abstract'>
    42       <p>
    43         This specification describes a transformation matrix interface with the dimension of 3x2 and 4x4.
    44       </p>
    46       <p>
    47         The transformation matrix interface replaces the SVGMatrix interface from SVG [[SVG11]]. It is a common interface used to describe 2D and 3D transformations on a graphical context for SVG, Context2D [[CANVAS-2D]], CSS3 Transforms [[CSS3-TRANSFORMS]] and WebGL [[WEBGL]].
    48       </p>
    49     </section>
    51     <section>
    52       <h2>Definitions</h2>
    53       <dl>
    54         <dt><dfn>post-multiply</dfn></dt>
    55         <dd>Term A post-multiplied by term B is equal to A &middot; B.</dd>
    56         <dt><dfn>pre-multiply</dfn></dt>
    57         <dd>Term A pre-multiplied by term B is equal to B &middot; A.</dd>
    58         <dt><dfn>multiply</dfn></dt>
    59         <dd>Multiply term A by term B is equal to A &middot; B.</dd>
    60       </dl>
    61     </section>
    63     <section>
    64       <h2>The <a>Point</a> dictionary</h2>
    65       <p>
    66         A 2D points and 3D points are represented by the following WebIDL dictionary:
    67       </p>
    69       <dl title='dictionary Point' class='idl'>
    70         <dt>double x = 0</dt>
    71         <dd>
    72           The x coordinate of the point.
    73         </dd>
    74         <dt>double y = 0</dt>
    75         <dd>
    76           The y coordinate of the point.
    77         </dd>
    78         <dt>double z = 0</dt>
    79         <dd>
    80           The z coordinate of the point.
    81         </dd>
    82         <dt>double w = 1</dt>
    83         <dd>
    84           The perspective of the point.
    85           <p class='issue'>
    86             A multiplication of a point with a matrix requires 4 values. Implementations usually normalize the point by w. It should be considered to do this here as well.
    87           </p>
    88         </dd>
    89       </dl>
    90     </section>
    92     <section>
    93       <h2>The <a>DecomposedMatrix</a> dictionary</h2>
    94       <p>
    95         The resulting values of a decomposed matrix as defined by <a href="#decomposing-the-matrix">Decomposing the matrix</a> and used in CSS Transforms [[CSS3-TRANSFORMS]] are represented by the following DecomposedMatrix dictionary:
    96       </p>
    98       <dl title='dictionary DecomposedMatrix' class='idl'>
    99         <dt>sequence&lt;double> translation</dt>
   100         <dd>
   101           Is an sequence of three double items for the translation of the matrix.
   102         </dd>
   103         <dt>sequence&lt;double> scale</dt>
   104         <dd>
   105           Is an sequence of three double items for the scaling of the matrix.
   106         </dd>
   107         <dt>sequence&lt;double> skew</dt>
   108         <dd>
   109           Is an sequence of three double items representing the shear of the matrix.
   110         </dd>
   111         <dt>sequence&lt;double> perspective</dt>
   112         <dd>
   113           Is an sequence of four double items representing the perspective of the matrix.
   114         </dd>
   115         <dt>sequence&lt;double> quaternions</dt>
   116         <dd>
   117           Is an sequence of four double items representing the quaternions for the rotation of the matrix.
   118         </dd>
   119       </dl>
   121       <p class='issue'>Define initial values.</p>
   123       <p class='issue'>
   124         It is doubtful that this can be very useful for authors. On the other hand, it allows scripted animations similar to the animations by CSS3 Transforms.
   125       </p>
   126     </section>
   128     <section>
   129       <h2>The <a>Matrix</a> interface</h2>
   131       <p>
   132         The <a>Matrix</a> interface represents a mathematical matrix with the purpose of describing transformations a graphical contexts. The following sections describe the details of the interface. For the full interface see <a href="#webidl-ref">Interface summary</a>.
   133       </p>
   135       <section>
   136         <h3>The constructors</h3>
   138         <p>
   139           A series of constructors to create a <a>Matrix</a> object.
   140         </p>
   142         <dl title='interface Matrix' class='idl'>
   143           <dt>Constructor()</dt>
   144           <dd>Creates an identity matrix.</dd>
   145           <dt>Constructor()</dt>
   146           <dd>
   147             <dl class='parameters'>
   148               <dt>DOMString transformList</dt>
   149               <dd>A DOMString of transformation functions with the syntax and specifies defined in CSS Transforms [[!CSS3-TRANSFORMS]]. One CSS pixel length maps to one unit less value in the matrix.</dd>
   150             </dl>
   151             The DOMString must consist of a transform function list as specified by CSS Transforms.
   152             <div class='example'>
   153               <p>In the following example a CSS Transform string is passed to the Matrix constructor.</p>
   154               <pre><code>var matrix = new Matrix("translate(20px,20px), scale(2,3), rotate(45deg)"</code></pre>
   155               <p>The resulting matrix is equal to the following sequence of method calls:</p>
   156               <pre><code>
   157 var matrix = new Matrix();
   158 matrix.translateBy(20,20);
   159 matrix.scaleNonUniformBy(2,3);
   160 matrix.rotateBy(45);
   161               </code></pre>
   162             </div>
   163             <p class='issue'>Should it be postponed to avoid CSS3 Transforms dependency?</p>
   164             <p class='issue'>Should unit-less values (like for SVG transform presentation attribute) be allowed too? <code>"translate(20,20)"</code></p>
   165             <p>Throws a <var>DOMException</var> with name <code>SyntaxError</code> if the <code>DOMString</code> parameter does not validate to a transform list [[!CSS3-TRANSFORMS]].
   166           </dd>
   167           <dt>Constructor()</dt>
   168           <dd>
   169             <dl class='parameters'>
   170               <dt>Matrix other</dt>
   171               <dd>All element values of the current matrix are set to the element values of the other matrix.</dd>
   172             </dl>
   173           </dd>
   174           <dt>Constructor()</dt>
   175           <dd>
   176             <dl class='parameters'>
   177               <dt>DecomposedMatrix decomposedValues</dt>
   178               <dd>
   179                 Recomposes the decomposed values as specified in <a href="#recomposing-the-matrix">Recomposing the matrix</a> and sets the element values of the current matrix.
   180               </dd>
   181             </dl>
   182           </dd>
   183           <dt>Constructor()</dt>
   184           <dd>
   185             <dl class='parameters'>
   186               <dt>Float32array array</dt>
   187               <dd>
   188                 Create an identity matrix first. An Float32array [[!TYPED-ARRAYS]] of 6 items sets the element values <code>a</code> to <code>f</code>. An array of 16 items sets the element values <code>m11</code> to <code>m44</code>.
   189               </dd>
   190             </dl>
   191             <p>Throws a <var>DOMException</var> with name <code>SyntaxError</code> if the <code>Float32array</code> parameter does not consist of 6 or 16 items.
   192           </dd>
   193           <dt>Constructor()</dt>
   194           <dd>
   195             <dl class='parameters'>
   196               <dt>Float64array array</dt>
   197               <dd>
   198                 Create an identity matrix first. An Float64array [[!TYPED-ARRAYS]] of 6 items sets the element values <code>a</code> to <code>f</code>. An array of 16 items sets the element values <code>m11</code> to <code>m44</code>.
   199               </dd>
   200             </dl>
   201             <p>Throws a <var>DOMException</var> with name <code>SyntaxError</code> if the <code>Float64array</code> parameter does not consist of 6 or 16 items.
   202           </dd>
   203           <dt>Constructor()</dt>
   204           <dd>
   205             <dl class='parameters'>
   206               <dt>sequence&lt;double> numberSequence</dt>
   207               <dd>
   208                 Create an identity matrix first. A sequence of 6 items sets the element values <code>a</code> to <code>f</code>. A sequence of 16 items sets the element values <code>m11</code> to <code>m44</code>. 
   209               </dd>
   210             </dl>
   211             <p>Throws a <var>DOMException</var> with name <code>SyntaxError</code> if the number sequence parameter does not consist of 6 or 16 items.
   212           </dd>
   213         </section>
   215         <section>
   216           <h3>Two-dimensional attributes</h3>
   218           <p>
   219             If a <a>Matrix</a> just consists of 2D transformations the 6 values <code>a</code> to <code>f</code> can represent the transformation matrix. If the <a>Matrix</a> object is immutable, a <var>DOMException</var> with name <code>NoModificationAllowedError</code> must be thrown on setting the attributes.
   220           </p>
   222           <p>
   223             The following attributes <code>a</code> to <code>f</code> are aliases to the two-dimensional elements of the 4x4 matrix.
   224           </p>
   226           <dl title='partial interface Matrix' class='idl'>
   227             <dt>// These attributes are simple aliases for certain elements of the 4x4 matrix</dt>
   228             <dd></dd>
   229             <dt>attribute double a</dt>
   230             <dd>
   231               <p>Corresponds to the attribute <span>m11</span> of the Matrix interface.</p>
   232             </dd>
   233             <dt>attribute double b</dt>
   234             <dd>
   235               <p>Corresponds to the attribute <span>m12</span> of the Matrix interface.</p>
   236             </dd>
   237             <dt>attribute double c</dt>
   238             <dd>
   239               <p>Corresponds to the attribute <span>m21</span> of the Matrix interface.</p>
   240             </dd>
   241             <dt>attribute double d</dt>
   242             <dd>
   243               <p>Corresponds to the attribute <span>m22</span> of the Matrix interface.</p>
   244             </dd>
   245             <dt>attribute double e</dt>
   246             <dd>
   247               <p>Corresponds to the attribute <span>m41</span> of the Matrix interface.</p>
   248             </dd>
   249             <dt>attribute double f</dt>
   250             <dd>
   251               <p>Corresponds to the attribute <span>m42</span> of the Matrix interface.</p>
   252             </dd>
   253           </dl>
   254         </section>
   256         <section>
   257           <h3>Three-dimensional attributes</h3>
   259           <p>
   260             The following attributes <code>m11</code> to <code>m44</code> represent the elements of the 4x4 matrix. The coordinates are in column-major order. If the <a>Matrix</a> object is immutable, a <var>DOMException</var> with name <code>NoModificationAllowedError</code> must be thrown on setting the attributes.
   261           </p>
   263           <dl title='partial interface Matrix' class='idl'>
   264             <dt>attribute double m11</dt>
   265             <dd>
   266               <p>
   267                 The value of the element in column 1, row 1 of the matrix.
   268               </p>
   269             </dd>
   270             <dt>attribute double m12</dt>
   271             <dd>
   272               <p>
   273                 The value of the element in column 1, row 2 of the matrix.
   274               </p>
   275             </dd>
   276             <dt>attribute double m13</dt>
   277             <dd>
   278               <p>
   279                 The value of the element in column 1, row 3 of the matrix.
   280               </p>
   281             </dd>
   282             <dt>attribute double m14</dt>
   283             <dd>
   284               <p>
   285                 The value of the element in column 1, row 4 of the matrix.
   286               </p>
   287             </dd>
   288             <dt>attribute double m21</dt>
   289             <dd>
   290               <p>
   291                 The value of the element in column 2, row 1 of the matrix.
   292               </p>
   293             </dd>
   294             <dt>attribute double m22</dt>
   295             <dd>
   296               <p>
   297                 The value of the element in column 2, row 2 of the matrix.
   298               </p>
   299             </dd>
   300             <dt>attribute double m23</dt>
   301             <dd>
   302               <p>
   303                 The value of the element in column 2, row 3 of the matrix.
   304               </p>
   305             </dd>
   306             <dt>attribute double m24</dt>
   307             <dd>
   308               <p>
   309                 The value of the element in column 2, row 4 of the matrix.
   310               </p>
   311             </dd>
   312             <dt>attribute double m31</dt>
   313             <dd>
   314               <p>
   315                 The value of the element in column 3, row 1 of the matrix.
   316               </p>
   317             </dd>
   318             <dt>attribute double m32</dt>
   319             <dd>
   320               <p>
   321                 The value of the element in column 3, row 2 of the matrix.
   322               </p>
   323             </dd>
   324             <dt>attribute double m33</dt>
   325             <dd>
   326               <p>
   327                 The value of the element in column 3, row 3 of the matrix.
   328               </p>
   329             </dd>
   330             <dt>attribute double m34</dt>
   331             <dd>
   332               <p>
   333                 The value of the element in column 3, row 4 of the matrix.
   334               </p>
   335             </dd>
   336             <dt>attribute double m41</dt>
   337             <dd>
   338               <p>
   339                 The value of the element in column 4, row 1 of the matrix.
   340               </p>
   341             </dd>
   342             <dt>attribute double m42</dt>
   343             <dd>
   344               <p>
   345                 The value of the element in column 4, row 2 of the matrix.
   346               </p>
   347             </dd>
   348             <dt>attribute double m43</dt>
   349             <dd>
   350               <p>
   351                 The value of the element in column 4, row 3 of the matrix.
   352               </p>
   353             </dd>
   354             <dt>attribute double m44</dt>
   355             <dd>
   356               <p>
   357                 The value of the element in column 4, row 4 of the matrix.
   358               </p>
   359             </dd>
   360           </dl>
   361         </section>
   363         <section>
   364           <h3>Immutable transformation methods</h3>
   366           <p>
   367             The following methods do not modify the current matrix and return new <a>Matrix</a> object.
   368           </p>
   370           <dl title='partial interface Matrix' class='idl'>
   371             <dt>// Immutable transform methods</dt>
   372             <dd></dd>
   373             <dt>Matrix translate()</dt>
   374             <dd>
   375               <dl class='parameters'>
   376                 <dt>double tx</dt>
   377                 <dd>Translation value along the x-axis.</dd>
   378                 <dt>double ty</dt>
   379                 <dd>Translation value along the y-axis.</dd>
   380                 <dt>optional double tz = 0</dt>
   381                 <dd>Optional translation value along the z-axis.</dd>
   382               </dl>
   383               Post-multiplies a translation transformation on the current matrix and returns the resulting matrix. The current matrix is not modified.
   384             </dd>
   385             <dt>Matrix scale()</dt>
   386             <dd>
   387               <dl class='parameters'>
   388                 <dt>double scale</dt>
   389                 <dd>Multiplier for a uniform scale transformation.</dd>
   390                 <dt>optional double originX = 0</dt>
   391                 <dd>Transformation origin on the x-axis.</dd>
   392                 <dt>optional double originY = 0</dt>
   393                 <dd>Transformation origin on the y-axis.</dd>
   394               </dl>
   395               Post-multiplies a uniform 2D scale transformation (<code>m11 = m22 = scale</code>) on the current matrix with the given origin and returns the resulting matrix. The current matrix is not modified.
   396             </dd>
   397             <dt>Matrix scale3d()</dt>
   398             <dd>
   399               <dl class='parameters'>
   400                 <dt>double scale</dt>
   401                 <dd>Multiplier for a uniform scale transformation.</dd>
   402                 <dt>optional double originX = 0</dt>
   403                 <dd>Transformation origin on the x-axis.</dd>
   404                 <dt>optional double originY = 0</dt>
   405                 <dd>Transformation origin on the y-axis.</dd>
   406                 <dt>optional double originZ = 0</dt>
   407                 <dd>Transformation origin on the z-axis.</dd>
   408               </dl>
   409               Post-multiplies a uniform scale transformation (<code>m11 = m22 = m33 = scale</code>) on the current matrix with the given origin and returns the resulting matrix. The current matrix is not modified.
   410             </dd>
   411             <dt>Matrix scaleNonUniform()</dt>
   412             <dd>
   413               <dl class='parameters'>
   414                 <dt>double scaleX</dt>
   415                 <dd>Multiplier for a non-uniform scale along the x-axis.</dd>
   416                 <dt>optional double scaleY = 1</dt>
   417                 <dd>Multiplier for a non-uniform scale along the y-axis.</dd>
   418                 <dt>optional double scaleZ = 1</dt>
   419                 <dd>Multiplier for a non-uniform scale along the z-axis.</dd>
   420                 <dt>optional double originX = 0</dt>
   421                 <dd>Transformation origin on the x-axis.</dd>
   422                 <dt>optional double originY = 0</dt>
   423                 <dd>Transformation origin on the y-axis.</dd>
   424                 <dt>optional double originZ = 0</dt>
   425                 <dd>Transformation origin on the z-axis.</dd>
   426               </dl>
   427               Post-multiplies a non-uniform scale transformation on the current matrix with the given origin and returns the resulting matrix. The current matrix is not modified.
   428             </dd>
   429             <dt>Matrix rotate()</dt>
   430             <dd>
   431               <dl class='parameters'>
   432                 <dt>double angle</dt>
   433                 <dd>Rotation angle in degrees.</dd>
   434                 <dt>optional double originX = 0</dt>
   435                 <dd>Transformation origin on the x-axis.</dd>
   436                 <dt>optional double originY = 0</dt>
   437                 <dd>Transformation origin on the y-axis.</dd>
   438               </dl>
   439               Post-multiplies a rotation transformation on the current matrix with the given origin and returns the resulting matrix. The current matrix is not modified.
   440             </dd>
   441             <dt>Matrix rotateFromVector(double x, double y)</dt>
   442             <dd>
   443               <dl class='parameters'>
   444                 <dt>double x</dt>
   445                 <dd>The x coordinate of the vector (x,y). Must not be zero.</dd>
   446                 <dt>double y</dt>
   447                 <dd>The y coordinate of the vector (x,y). Must not be zero.</dd>
   448               </dl>
   449               Post-multiplies a rotation transformation on the current matrix and returns the resulting matrix. The rotation angle is determined by taking (+/-) atan(y/x). The direction of the vector (x, y) determines whether the positive or negative angle value is used. The current matrix is not modified.
   450             </dd>
   451             <dt>Matrix rotateAxisAngle(double x, double y, double z, double angle)</dt>
   452             <dd>
   453               <dl class='parameters'>
   454                 <dt>double x</dt>
   455                 <dd>The x coordinate of the vector (x,y,z).</dd>
   456                 <dt>double y</dt>
   457                 <dd>The y coordinate of the vector (x,y,z).</dd>
   458                 <dt>double z</dt>
   459                 <dd>The z coordinate of the vector (x,y,z).</dd>
   460                 <dt>double angle</dt>
   461                 <dd>Rotation angle in degrees.</dd>
   462                 Post-multiplies a rotation transformation on the current matrix and returns the resulting matrix. The rotation of the transform is applied around the given vector. The current matrix is not modified.
   463               </dl>
   464             </dd>
   465             <dt>Matrix skewX()</dt>
   466             <dd>
   467               <dl class='parameters'>
   468                 <dt>double sx</dt>
   469                 <dd>Skew angle along the x-axis in degrees.</dd>
   470               </dl>
   471               Post-multiplies a skewX transformation on the current matrix and returns the resulting matrix. The current matrix is not modified.
   472             </dd>
   473             <dt>Matrix skewY()</dt>
   474             <dd>
   475               <dl class='parameters'>
   476                 <dt>double sy</dt>
   477                 <dd>Skew angle along the y-axis in degrees.</dd>
   478               </dl>
   479               Post-multiplies a skewX transformation on the current matrix and returns the resulting matrix.
   480             </dd>
   481             <dt>Matrix multiply()</dt>
   482             <dd>
   483               <dl class='parameters'>
   484                 <dt>Matrix other</dt>
   485                 <dd>Other matrix for multiplication</dd>
   486               </dl>
   487               Performs matrix multiplication. This matrix is post-multiplied by the other matrix, returning the resulting new matrix. The current matrix is not modified.
   488             </dd>
   489             <dt>Matrix flipX()</dt>
   490             <dd>
   491               Post-multiplies the transformation <code>Matrix(-1, 0, 0, 1, 0, 0)</code> and returns the resulting matrix. The current matrix is not modified.
   492             </dd>
   493             <dt>Matrix flipY()</dt>
   494             <dd>
   495               Post-multiplies the transformation <code>Matrix(1, 0, 0, -1, 0, 0)</code> and returns the resulting matrix. The current matrix is not modified.
   496             </dd>
   497             <dt>Matrix? inverse()</dt>
   498             <dd>
   499               Returns the inverted matrix of the current matrix if applicable. Otherwise <code>null</code>. The current matrix is not modified.
   500               <dl class='exceptions'>
   501                 <dt>DOMException of type
   502                     <code>InvalidModificationError</code></dt>
   503                 <dd>
   504                   Raised when the current matrix is singular.
   505                 </dd>
   506               </dl>
   507             </dd>
   508           </dl>
   509         </section>
   511         <section>
   512           <h3>Mutable transformation methods</h3>
   514           <p>
   515             The following methods do modify the current matrix. If the <a>Matrix</a> object is immutable, a <var>DOMException</var> with name <code>NoModificationAllowedError</code> must be thrown on calling the operations below.
   516           </p>
   518           <dl title='partial interface Matrix' class='idl'>
   519             <dt>// Mutable transform methods</dt>
   520             <dd></dd>
   521             <dt>void multiplyBy()</dt>
   522             <dd>
   523               <dl class='parameters'>
   524                 <dt>Matrix other</dt>
   525                 <dd>The matrix that gets post-multiplied.</dd>
   526               </dl>
   527               The other matrix gets post-multiplied to the current matrix.
   528             </dd>
   529             <dt>void preMultiplyBy()</dt>
   530             <dd>
   531               <dl class='parameters'>
   532                 <dt>Matrix other</dt>
   533                 <dd>The matrix that gets pre-multiplied.</dd>
   534               </dl>
   535               The other matrix gets pre-multiplied to the current matrix.
   536             </dd>
   537             <dt>void translateBy()</dt>
   538             <dd>
   539               <dl class='parameters'>
   540                 <dt>double tx</dt>
   541                 <dd>Translation value along the x-axis.</dd>
   542                 <dt>double ty</dt>
   543                 <dd>Translation value along the y-axis.</dd>
   544                 <dt>optional double tz = 0</dt>
   545                 <dd>Optional translation value along the z-axis.</dd>
   546               </dl>
   547               Post-multiplies a translation transformation on the current matrix.
   548             </dd>
   549             <dt>void scaleBy()</dt>
   550             <dd>
   551               <dl class='parameters'>
   552                 <dt>double scale</dt>
   553                 <dd>Multiplier for a uniform scale transformation.</dd>
   554                 <dt>optional double originX = 0</dt>
   555                 <dd>Transformation origin on the x-axis.</dd>
   556                 <dt>optional double originY = 0</dt>
   557                 <dd>Transformation origin on the y-axis.</dd>
   558               </dl>
   559               Post-multiplies a uniform 2D scale transformation (<code>m11 = m22 = scale</code>) on the current matrix with the given origin.
   560             </dd>
   561             <dt>void scale3dBy()</dt>
   562             <dd>
   563               <dl class='parameters'>
   564                 <dt>double scale</dt>
   565                 <dd>Multiplier for a uniform scale transformation.</dd>
   566                 <dt>optional double originX = 0</dt>
   567                 <dd>Transformation origin on the x-axis.</dd>
   568                 <dt>optional double originY = 0</dt>
   569                 <dd>Transformation origin on the y-axis.</dd>
   570                 <dt>optional double originZ = 0</dt>
   571                 <dd>Transformation origin on the z-axis.</dd>
   572               </dl>
   573               Post-multiplies a uniform 2D scale transformation (<code>m11 = m22 = m33 = scale</code>) on the current matrix with the given origin.
   574             </dd>
   575             <dt>void scaleNonUniformBy()</dt>
   576             <dd>
   577               <dl class='parameters'>
   578                 <dt>double scaleX</dt>
   579                 <dd>Multiplier for a non-uniform scale along the x-axis.</dd>
   580                 <dt>optional double scaleY = 1</dt>
   581                 <dd>Multiplier for a non-uniform scale along the y-axis.</dd>
   582                 <dt>optional double scaleZ = 1</dt>
   583                 <dd>Multiplier for a non-uniform scale along the z-axis.</dd>
   584                 <dt>optional double originX = 0</dt>
   585                 <dd>Transformation origin on the x-axis.</dd>
   586                 <dt>optional double originY = 0</dt>
   587                 <dd>Transformation origin on the y-axis.</dd>
   588                 <dt>optional double originZ = 0</dt>
   589                 <dd>Transformation origin on the z-axis.</dd>
   590               </dl>
   591               Post-multiplies a non-uniform scale transformation on the current matrix with the given origin.
   592             </dd>
   593             <dt>void rotateBy()</dt>
   594             <dd>
   595               <dl class='parameters'>
   596                 <dt>double angle</dt>
   597                 <dd>Rotation angle in degrees.</dd>
   598                 <dt>optional double originX = 0</dt>
   599                 <dd>Transformation origin on the x-axis.</dd>
   600                 <dt>optional double originY = 0</dt>
   601                 <dd>Transformation origin on the y-axis.</dd>
   602               </dl>
   603               Post-multiplies a rotation transformation on the current matrix with the given origin.
   604             </dd>
   605             <dt>void rotateFromVectorBy(double x, double y)</dt>
   606             <dd>
   607               <dl class='parameters'>
   608                 <dt>double x</dt>
   609                 <dd>The x coordinate of the vector (x,y). Must not be zero.</dd>
   610                 <dt>double y</dt>
   611                 <dd>The y coordinate of the vector (x,y). Must not be zero.</dd>
   612               </dl>
   613               Post-multiplies a rotation transformation on the current matrix. The rotation angle is determined by taking (+/-) atan(y/x). The direction of the vector (x, y) determines whether the positive or negative angle value is used.
   614             </dd>
   615             <dt>void rotateAxisAngleBy(double x, double y, double z, double angle)</dt>
   616             <dd>
   617               <dl class='parameters'>
   618                 <dt>double x</dt>
   619                 <dd>The x coordinate of the vector (x,y,z).</dd>
   620                 <dt>double y</dt>
   621                 <dd>The y coordinate of the vector (x,y,z).</dd>
   622                 <dt>double z</dt>
   623                 <dd>The z coordinate of the vector (x,y,z).</dd>
   624                 <dt>double angle</dt>
   625                 <dd>Rotation angle in degrees.</dd>
   626                 Post-multiplies a rotation transformation on the current matrix. The rotation of the transform is applied around the given vector.
   627               </dl>
   628             </dd>
   629             <dt>void skewXBy()</dt>
   630             <dd>
   631               <dl class='parameters'>
   632                 <dt>double sx</dt>
   633                 <dd>Skew angle along the x-axis in degrees.</dd>
   634               </dl>
   635               Post-multiplies a skewX transformation on the current matrix.
   636             </dd>
   637             <dt>void skewYBy()</dt>
   638             <dd>
   639               <dl class='parameters'>
   640                 <dt>double sy</dt>
   641                 <dd>Skew angle along the y-axis in degrees.</dd>
   642               </dl>
   643               Post-multiplies a skewX transformation on the current matrix.
   644             </dd>
   645             <dt>void invert()</dt>
   646             <dd>
   647               Inverts the current matrix.
   648               <dl class='exceptions'>
   649                 <dt>DOMException of type
   650                     <code>InvalidModificationError</code></dt>
   651                 <dd>
   652                   Raised when the current matrix is singular.
   653                 </dd>
   654               </dl>
   655             </dd>
   656           </dl>
   657         </section>
   659         <section>
   660           <h3>Helper methods</h3>
   662           <p>
   663             The following helper methods do not modify the <a>Matrix</a> object.
   664           </p>
   666           <dl title='partial interface Matrix' class='idl'>
   667             <dt>// Helper methods</dt>
   668             <dd></dd>
   669             <dt>boolean is2D()</dt>
   670             <dd>
   671               Returns <code>true</code> if <code>m13</code>, <code>m14</code>, <code>m23</code>, <code>m24</code>, <code>m31</code>, <code>m32</code>, <code>m34</code>, <code>m43</code> are equal to zero and <code>m33</code>, <code>m44</code> are equal to one.
   672             </dd>
   673             <dt>double determinant()</dt>
   674             <dd>
   675               Returns the determinant of the current matrix.
   676             </dd>
   677             <dt>Point transformPoint()</dt>
   678             <dd>
   679               <dl class='parameters'>
   680                 <dt>Point point</dt>
   681                 <dd>A Point dictionary.</dd>
   682               </dl>
   683               The point is post-multiplied on the current matrix and returns the resulting point. <code>point</code> is not modified.
   684             </dd>
   685             <dt>Float32Array toFloat32Array()</dt>
   686             <dd>
   687               Returns the serialized 16 elements <code>m11</code> to <code>m44</code> of the current matrix in column-major order as Float32Array [[!TYPED-ARRAYS]].
   688             </dd>
   689             <dt>Float64Array toFloat64Array()</dt>
   690             <dd>
   691               Returns the serialized 16 elements <code>m11</code> to <code>m44</code> of the current matrix in column-major order as Float64Array [[!TYPED-ARRAYS]].
   692             </dd>
   693             <dt>DecomposedMatrix decompose()</dt>
   694             <dd>
   695               Returns the decomposed matrix values of the current matrix as a DecomposedMatrix dictionary. The decomposing follows the algorithm of <a href="#decomposing-the-matrix">Decomposing the Matrix</a>.
   696             </dd>
   697             <dt>void stringifier()</dt>
   698             <dd>
   699               Returns a string in the form of a CSS Transforms <code>matrix</code> function if the current matrix is a 2D transform or a CSS Transforms <code>matrix3d</code> else. The syntax is as specified in CSS Transforms [[!CSS3-TRANSFORMS]].
   700               <p class='issue'>Should be <code>stringifier;</code>. Bug in old respec tool.</p>
   701               <div class='example'>
   702                 <p>In this example a matrix is created and several methods with 2D transformations are called.</p>
   703                 <pre><code>var matrix = new Matrix();
   704 matrix.scaleBy(2);
   705 matrix.translateBy(20,20);</code></pre>
   706                 <p>The <code>matrix.toString()</code> returns the DOM string:</p>
   707                 <pre><code>"matrix(2,0,0,2,20,20)"</code></pre>
   708                 <p>For 3D operations, the <var>stringifier</var> returns DOM string representing a 3D matrix.</p>
   709                 <pre><code>var matrix = new Matrix();
   710 matrix.scale3dBy(2);</code></pre>
   711                 <p>Calling <code>matrix.toString()</code> after the snippet above returns the DOM string:</p>
   712                 <pre><code>"matrix3d(2,0,0,0,0,2,0,0,0,0,2,0,0,0,0,1)"</code></pre>
   713               </div>
   714             </dd>
   715           </dl>
   716       </section>
   717     </section>
   719     <section>
   720       <h2>Decomposing the Matrix</h2>
   722       <p class='issue'>It is unsure if Transformation Matrix should reference the code of CSS3 Transforms
   723         or the other way around. Clearly we do not need the code twice.
   724       </p> 
   725       <p>
   726         The pseudocode below is based upon the "unmatrix" method in "Graphics Gems II,
   727         edited by Jim Arvo", but modified to use Quaternions instead of Euler angles to
   728         avoid the problem of Gimbal Locks.
   729       </p>
   731       <p>
   732         The following pseudocode works on a 4x4 homogeneous matrix:
   733       </p>
   735       <pre>Input:  matrix      ; a 4x4 matrix
   736 Output: translation ; a 3 component vector
   737         scale       ; a 3 component vector
   738         skew        ; skew factors XY,XZ,YZ represented as a 3 component vector
   739         perspective ; a 4 component vector
   740         quaternion  ; a 4 component vector
   741 Returns false if the matrix cannot be decomposed, true if it can
   743 Supporting functions (point is a 3 component vector, matrix is a 4x4 matrix):
   744   double  determinant(matrix)          returns the 4x4 determinant of the matrix
   745   matrix  inverse(matrix)              returns the inverse of the passed matrix
   746   matrix  transpose(matrix)            returns the transpose of the passed matrix
   747   point   multVecMatrix(point, matrix) multiplies the passed point by the passed matrix
   748                                        and returns the transformed point
   749   double  length(point)                returns the length of the passed vector
   750   point   normalize(point)             normalizes the length of the passed point to 1
   751   double  dot(point, point)            returns the dot product of the passed points
   752   double  sqrt(double)                 returns the root square of passed value
   753   double  max(double y, double x)      returns the bigger value of the two passed values
   755 Decomposition also makes use of the following function:
   756   point combine(point a, point b, double ascl, double bscl)
   757       result[0] = (ascl * a[0]) + (bscl * b[0])
   758       result[1] = (ascl * a[1]) + (bscl * b[1])
   759       result[2] = (ascl * a[2]) + (bscl * b[2])
   760       return result
   762 // Normalize the matrix.
   763 if (matrix[3][3] == 0)
   764     return false
   766 for (i = 0; i < 4; i++)
   767     for (j = 0; j < 4; j++)
   768         matrix[i][j] /= matrix[3][3]
   770 // perspectiveMatrix is used to solve for perspective, but it also provides
   771 // an easy way to test for singularity of the upper 3x3 component.
   772 perspectiveMatrix = matrix
   774 for (i = 0; i < 3; i++)
   775     perspectiveMatrix[i][3] = 0
   777 perspectiveMatrix[3][3] = 1
   779 if (determinant(perspectiveMatrix) == 0)
   780     return false
   782 // First, isolate perspective.
   783 if (matrix[0][3] != 0 || matrix[1][3] != 0 || matrix[2][3] != 0)
   784     // rightHandSide is the right hand side of the equation.
   785     rightHandSide[0] = matrix[0][3];
   786     rightHandSide[1] = matrix[1][3];
   787     rightHandSide[2] = matrix[2][3];
   788     rightHandSide[3] = matrix[3][3];
   790     // Solve the equation by inverting perspectiveMatrix and multiplying
   791     // rightHandSide by the inverse.
   792     inversePerspectiveMatrix = inverse(perspectiveMatrix)
   793     transposedInversePerspectiveMatrix = transposeMatrix4(inversePerspectiveMatrix)
   794     perspective = multVecMatrix(rightHandSide, transposedInversePerspectiveMatrix)
   795 else
   796     // No perspective.
   797     perspective[0] = perspective[1] = perspective[2] = 0
   798     perspective[3] = 1
   800 // Next take care of translation
   801 for (i = 0; i < 3; i++)
   802     translate[i] = matrix[3][i]
   804 // Now get scale and shear. 'row' is a 3 element array of 3 component vectors
   805 for (i = 0; i < 3; i++)
   806     row[i][0] = matrix[i][0]
   807     row[i][1] = matrix[i][1]
   808     row[i][2] = matrix[i][2]
   810 // Compute X scale factor and normalize first row.
   811 scale[0] = length(row[0])
   812 row[0] = normalize(row[0])
   814 // Compute XY shear factor and make 2nd row orthogonal to 1st.
   815 skew[0] = dot(row[0], row[1])
   816 row[1] = combine(row[1], row[0], 1.0, -skew[0])
   818 // Now, compute Y scale and normalize 2nd row.
   819 scale[1] = length(row[1])
   820 row[1] = normalize(row[1])
   821 skew[0] /= scale[1];
   823 // Compute XZ and YZ shears, orthogonalize 3rd row
   824 skew[1] = dot(row[0], row[2])
   825 row[2] = combine(row[2], row[0], 1.0, -skew[1])
   826 skew[2] = dot(row[1], row[2])
   827 row[2] = combine(row[2], row[1], 1.0, -skew[2])
   829 // Next, get Z scale and normalize 3rd row.
   830 scale[2] = length(row[2])
   831 row[2] = normalize(row[2])
   832 skew[1] /= scale[2]
   833 skew[2] /= scale[2]
   835 // At this point, the matrix (in rows) is orthonormal.
   836 // Check for a coordinate system flip.  If the determinant
   837 // is -1, then negate the matrix and the scaling factors.
   838 pdum3 = cross(row[1], row[2])
   839 if (dot(row[0], pdum3) < 0)
   840     for (i = 0; i < 3; i++)
   841         scale[i] *= -1;
   842         row[i][0] *= -1
   843         row[i][1] *= -1
   844         row[i][2] *= -1
   846 // Now, get the rotations out
   847 quaternion[0] = 0.5 * sqrt(max(1 + row[0][0] - row[1][1] - row[2][2], 0))
   848 quaternion[1] = 0.5 * sqrt(max(1 - row[0][0] + row[1][1] - row[2][2], 0))
   849 quaternion[2] = 0.5 * sqrt(max(1 - row[0][0] - row[1][1] + row[2][2], 0))
   850 quaternion[3] = 0.5 * sqrt(max(1 + row[0][0] + row[1][1] + row[2][2], 0))
   852 if (row[2][1] > row[1][2])
   853     quaternion[0] = -quaternion[0]
   854 if (row[0][2] > row[2][0])
   855     quaternion[1] = -quaternion[1]
   856 if (row[1][0] > row[0][1])
   857     quaternion[2] = -quaternion[2]
   859 return true</pre>
   860     </section>
   862     <section>
   863       <h2>Recomposing the Matrix</h2>
   865       <p class='issue'>
   866         Same as for decompose matrix
   867       </p>
   869       <p>
   870         After interpolation the resulting values are used to transform the elements user
   871         space. One way to use these values is to recompose them into a 4x4 matrix. This can
   872         be done following the pseudo-code below:
   873       </p>
   875       <pre>Input:  translation ; a 3 component vector
   876         scale       ; a 3 component vector
   877         skew        ; skew factors XY,XZ,YZ represented as a 3 component vector
   878         perspective ; a 4 component vector
   879         quaternion  ; a 4 component vector
   880 Output: matrix      ; a 4x4 matrix
   882 Supporting functions (matrix is a 4x4 matrix):
   883   matrix  multiply(matrix a, matrix b)   returns the 4x4 matrix product of a * b  
   885 // apply perspective
   886 for (i = 0; i < 4; i++)
   887   matrix[i][3] = perspective[i]
   889 // apply translation
   890 for (i = 0; i < 3; i++)
   891   for (j = 0; j < 3; j++)
   892     matrix[3][i] += translation[j] * matrix[j][i]
   894 // apply rotation
   895 x = quaternion[0]
   896 y = quaternion[1]
   897 z = quaternion[2]
   898 w = quaternion[3]
   900 // Construct a composite rotation matrix from the quaternion values
   901 // rotationMatrix is a identity 4x4 matrix initially
   902 rotationMatrix[0][0] = 1 - 2 * (y * y + z * z)
   903 rotationMatrix[0][1] = 2 * (x * y - z * w)
   904 rotationMatrix[0][2] = 2 * (x * z + y * w)
   905 rotationMatrix[1][0] = 2 * (x * y + z * w)
   906 rotationMatrix[1][1] = 1 - 2 * (x * x + z * z)
   907 rotationMatrix[1][2] = 2 * (y * z - x * w)
   908 rotationMatrix[2][0] = 2 * (x * z - y * w)
   909 rotationMatrix[2][1] = 2 * (y * z + x * w)
   910 rotationMatrix[2][2] = 1 - 2 * (x * x + y * y)
   912 matrix = multiply(matrix, rotationMatrix)
   914 // apply skew
   915 // temp is a identity 4x4 matrix initially
   916 if (skew[2])
   917     temp[2][1] = skew[2]
   918     matrix = multiply(matrix, temp)
   920 if (skew[1])
   921     temp[2][1] = 0
   922     temp[2][0] = skew[1]
   923     matrix = multiply(matrix, temp)
   925 if (skew[0])
   926     temp[2][0] = 0
   927     temp[1][0] = skew[0]
   928     matrix = multiply(matrix, temp)
   930 // apply scale
   931 for (i = 0; i < 3; i++)
   932   for (j = 0; j < 3; j++)
   933     matrix[i][j] *= scale[i]
   935 return</pre>
   936     </section>
   938     <section class='appendix' id="webidl-ref">
   939       <h2>Interface summary</h2>
   940     </section>
   942     <section class='appedix'>
   943       <h2>Conformance</h2>
   945       <section>
   946         <h3 id="conventions">
   947         Document conventions</h3>
   949         <p>Conformance requirements are expressed with a combination of
   950         descriptive assertions and RFC 2119 terminology. The key words “MUST”,
   951         “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”,
   952         “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this
   953         document are to be interpreted as described in RFC 2119.
   954         However, for readability, these words do not appear in all uppercase
   955         letters in this specification.
   957         <p>All of the text of this specification is normative except sections
   958         explicitly marked as non-normative, examples, and notes. [[!RFC2119]]</p>
   960         <p>Examples in this specification are introduced with the words “for example”
   961         or are set apart from the normative text with <code>class="example"</code>,
   962         like this:
   964         <div class="example">
   965           <p>This is an example of an informative example.</p>
   966         </div>
   968         <p>Informative notes begin with the word “Note” and are set apart from the
   969         normative text with <code>class="note"</code>, like this:
   971         <p class="note">Note, this is an informative note.</p>
   972       </section>
   974       <section>
   975         <h3 id="conformance-classes">
   976         Conformance classes</h3>
   978         <p>Conformance to this specification
   979         is defined for three conformance classes:
   980         <dl>
   981           <dt><dfn title="style sheet!!as conformance class">style sheet</dfn>
   982             <dd>A <a href="http://www.w3.org/TR/CSS21/conform.html#style-sheet">CSS
   983             style sheet</a>.
   984           <dt><dfn>renderer</dfn></dt>
   985             <dd>A <a href="http://www.w3.org/TR/CSS21/conform.html#user-agent">UA</a>
   986             that interprets the semantics of a style sheet and renders
   987             documents that use them.
   988           <dt><dfn id="authoring-tool">authoring tool</dfn></dt>
   989             <dd>A <a href="http://www.w3.org/TR/CSS21/conform.html#user-agent">UA</a>
   990             that writes a style sheet.
   991         </dl>
   993         <p>A style sheet is conformant to this specification
   994         if all of its statements that use syntax defined in this module are valid
   995         according to the generic CSS grammar and the individual grammars of each
   996         feature defined in this module.
   998         <p>A renderer is conformant to this specification
   999         if, in addition to interpreting the style sheet as defined by the
  1000         appropriate specifications, it supports all the features defined
  1001         by this specification by parsing them correctly
  1002         and rendering the document accordingly. However, the inability of a
  1003         UA to correctly render a document due to limitations of the device
  1004         does not make the UA non-conformant. (For example, a UA is not
  1005         required to render color on a monochrome monitor.)
  1007         <p>An authoring tool is conformant to this specification
  1008         if it writes style sheets that are syntactically correct according to the
  1009         generic CSS grammar and the individual grammars of each feature in
  1010         this module, and meet all other conformance requirements of style sheets
  1011         as described in this module.
  1012       </section>
  1014       <section>
  1015         <h3 id="partial">
  1016         Partial implementations</h3>
  1018         <p>So that authors can exploit the forward-compatible parsing rules to
  1019         assign fallback values, CSS renderers <strong>must</strong>
  1020         treat as invalid (and <a href="http://www.w3.org/TR/CSS21/conform.html#ignore">ignore
  1021         as appropriate</a>) any at-rules, properties, property values, keywords,
  1022         and other syntactic constructs for which they have no usable level of
  1023         support. In particular, user agents <strong>must not</strong> selectively
  1024         ignore unsupported component values and honor supported values in a single
  1025         multi-value property declaration: if any value is considered invalid
  1026         (as unsupported values must be), CSS requires that the entire declaration
  1027         be ignored.</p>
  1028       </section>
  1030       <section>
  1031         <h3 id="experimental">
  1032         Experimental implementations</h3>
  1034         <p>To avoid clashes with future CSS features, the CSS2.1 specification
  1035         reserves a <a href="http://www.w3.org/TR/CSS21/syndata.html#vendor-keywords">prefixed
  1036         syntax</a> for proprietary and experimental extensions to CSS.
  1038         <p>Prior to a specification reaching the Candidate Recommendation stage
  1039         in the W3C process, all implementations of a CSS feature are considered
  1040         experimental. The CSS Working Group recommends that implementations
  1041         use a vendor-prefixed syntax for such features, including those in
  1042         W3C Working Drafts. This avoids incompatibilities with future changes
  1043         in the draft.
  1044         </p>
  1045       </section>
  1047       <section>
  1048         <h3 id="testing">
  1049         Non-experimental implementations</h3>
  1051         <p>Once a specification reaches the Candidate Recommendation stage,
  1052         non-experimental implementations are possible, and implementors should
  1053         release an unprefixed implementation of any CR-level feature they
  1054         can demonstrate to be correctly implemented according to spec.
  1056         <p>To establish and maintain the interoperability of CSS across
  1057         implementations, the CSS Working Group requests that non-experimental
  1058         CSS renderers submit an implementation report (and, if necessary, the
  1059         testcases used for that implementation report) to the W3C before
  1060         releasing an unprefixed implementation of any CSS features. Testcases
  1061         submitted to W3C are subject to review and correction by the CSS
  1062         Working Group.
  1064         <p>Further information on submitting testcases and implementation reports
  1065         can be found from on the CSS Working Group's website at
  1066         <a href="http://www.w3.org/Style/CSS/Test/">http://www.w3.org/Style/CSS/Test/</a>.
  1067         Questions should be directed to the
  1068         <a href="http://lists.w3.org/Archives/Public/public-css-testsuite">public-css-testsuite@w3.org</a>
  1069         mailing list.
  1070       </section>
  1071     </section>
  1073     <section class='appendix'>
  1074       <h2>Acknowledgments</h2>
  1075       <p>
  1076         Many thanks to Dean Jackson for his initial proposal to make this specification possible.
  1077       </p>
  1078     </section>
  1079   </body>
  1080 </html>

mercurial