css3-transforms/Overview.html

Tue, 05 Feb 2013 13:50:38 -0700

author
L. David Baron <dbaron@dbaron.org>
date
Tue, 05 Feb 2013 13:50:38 -0700
changeset 7349
55d46b236cf3
parent 7338
7c1a3923a1d5
child 7701
74e801dd7a86
permissions
-rwxr-xr-x

[css3-transforms] Add Animatable: lines to propdef tables.

simon@5276 1 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"
simon@5276 2 "http://www.w3.org/TR/html4/strict.dtd">
simon@5276 3
simon@5276 4 <html lang=en>
bert@6706 5 <head
bert@6706 6 profile="http://dublincore.org/documents/2008/08/04/dc-html/ http://www.w3.org/2006/03/hcard">
bert@6706 7 <meta content="text/html; charset=utf-8" http-equiv=Content-Type>
simon@5276 8 <title>CSS Transforms</title>
bert@6706 9
dschulze@6881 10 <link href="http://purl.org/dc/terms/" rel=schema.dcterms>
bert@6706 11 <link href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright"
dschulze@6881 12 rel=dcterms.rights>
dschulze@6881 13 <meta content="CSS Transforms" name=dcterms.title>
dschulze@6881 14 <meta content=text name=dcterms.type>
dbaron@7338 15 <meta content=2013-02-05 name=dcterms.issued>
dschulze@6881 16 <meta content="http://dev.w3.org/csswg/css3-transforms/"
dschulze@6881 17 name=dcterms.creator>
dschulze@6881 18 <meta content=W3C name=dcterms.publisher>
dbaron@7338 19 <meta content="http://www.w3.org/TR/2013/ED-css3-transforms-20130205/"
dschulze@6881 20 name=dcterms.identifier>
simon@5276 21 <link href="../default.css" rel=stylesheet type="text/css">
bert@6706 22 <script defer=defer
bert@6706 23 src="http://test.csswg.org/harness/annotate.js#CSS3-TRANSFORMS_DEV"
bert@6706 24 type="text/javascript"></script>
simon@5276 25 <style type="text/css">
simon@5276 26 .term {
simon@5276 27 font-style: italic;
simon@5276 28 }
simon@5276 29 </style>
bert@6706 30 <link href="http://www.w3.org/StyleSheets/TR/W3C-ED.css" rel=stylesheet
bert@6706 31 type="text/css">
simon@5276 32
simon@5276 33 <body>
simon@5276 34 <div class=head id=div-head> <!--begin-logo-->
simon@5276 35 <p><a href="http://www.w3.org/"><img alt=W3C height=48
simon@5276 36 src="http://www.w3.org/Icons/w3c_home" width=72></a> <!--end-logo-->
simon@5276 37
simon@5276 38 <h1>CSS Transforms</h1>
simon@5276 39
dbaron@7338 40 <h2 class="no-num no-toc" id=longstatus-date>Editor's Draft 5 February
dbaron@7338 41 2013</h2>
simon@5276 42
simon@5276 43 <dl>
simon@5276 44 <dt>This version:
simon@5276 45
simon@5276 46 <dd> <a
dbaron@7338 47 href="http://www.w3.org/TR/2013/ED-css3-transforms-20130205/">http://dev.w3.org/csswg/css3-transforms/</a>
dbaron@7338 48 <!--http://www.w3.org/TR/2013/WD-css3-transforms-20130205/-->
simon@5276 49
simon@5276 50 <dt>Latest version:
simon@5276 51
simon@5276 52 <dd><a
dschulze@5541 53 href="http://www.w3.org/TR/css3-transforms/">http://www.w3.org/TR/css3-transforms/</a>
simon@5276 54
simon@5276 55 <dt>Editor's draft:
simon@5276 56
simon@5276 57 <dd><a
simon@5276 58 href="http://dev.w3.org/csswg/css3-transforms/">http://dev.w3.org/csswg/css3-transforms/</a>
bert@6706 59
bert@6706 60 <dt>Previous version:
simon@5276 61
simon@5276 62 <dd><a
bert@6706 63 href="http://www.w3.org/TR/2012/WD-css3-transforms-20120911/">http://www.w3.org/TR/2012/WD-css3-transforms-20120911/</a>
simon@5276 64
simon@5276 65 <dt id=editors-list>Editors:
simon@5276 66
simon@5276 67 <dd>Simon Fraser (<a href="http://www.apple.com/">Apple Inc</a>)
dschulze@5892 68 &lt;simon.fraser @apple.com&gt;
simon@5276 69
simon@5276 70 <dd>Dean Jackson (<a href="http://www.apple.com/">Apple Inc</a>) &lt;dino
dschulze@5892 71 @apple.com&gt;
simon@5276 72
simon@6214 73 <dd>Edward O'Connor (<a href="http://www.apple.com/">Apple Inc</a>)
simon@6214 74 &lt;eoconnor @apple.com&gt;
simon@6214 75
simon@6214 76 <dd>Dirk Schulze (<a href="http://www.adobe.com/">Adobe Systems, Inc</a>)
simon@6214 77 &lt;dschulze @adobe.com&gt;
simon@6214 78
simon@6214 79 <dd>Aryeh Gregor (<a href="http://www.mozilla.org/">Mozilla</a>) &lt;ayg
simon@6214 80 @aryeh.name&gt;
simon@6214 81
bert@6706 82 <dt id=former-editors-list>Former Editors:
simon@6214 83
simon@5276 84 <dd>David Hyatt (<a href="http://www.apple.com/">Apple Inc</a>) &lt;hyatt
dschulze@5892 85 @apple.com&gt;
simon@5276 86
simon@5276 87 <dd>Chris Marrin (<a href="http://www.apple.com/">Apple Inc</a>)
dschulze@5892 88 &lt;cmarrin @apple.com&gt;
simon@5276 89
simon@5276 90 <dt>Issues list:
simon@5276 91
simon@5276 92 <dd><a
simon@5276 93 href="https://www.w3.org/Bugs/Public/buglist.cgi?query_format=advanced&amp;product=CSS&amp;component=Transforms&amp;resolution=---&amp;cmdtype=doit">in
simon@5276 94 Bugzilla</a>
simon@5276 95
simon@5276 96 <dt>Test suite:
simon@5276 97
simon@5276 98 <dd>none yet
simon@5276 99 </dl>
simon@5276 100 <!--begin-copyright-->
simon@5276 101 <p class=copyright><a
simon@5276 102 href="http://www.w3.org/Consortium/Legal/ipr-notice#Copyright"
dbaron@7338 103 rel=license>Copyright</a> © 2013 <a href="http://www.w3.org/"><abbr
dschulze@5892 104 title="World Wide Web Consortium">W3C</abbr></a><sup>®</sup> (<a
simon@5276 105 href="http://www.csail.mit.edu/"><abbr
simon@5276 106 title="Massachusetts Institute of Technology">MIT</abbr></a>, <a
simon@5276 107 href="http://www.ercim.eu/"><abbr
simon@5276 108 title="European Research Consortium for Informatics and Mathematics">ERCIM</abbr></a>,
dbaron@7338 109 <a href="http://www.keio.ac.jp/">Keio</a>, <a
dbaron@7338 110 href="http://ev.buaa.edu.cn/">Beihang</a>), All Rights Reserved. W3C <a
simon@5276 111 href="http://www.w3.org/Consortium/Legal/ipr-notice#Legal_Disclaimer">liability</a>,
simon@5276 112 <a
simon@5276 113 href="http://www.w3.org/Consortium/Legal/ipr-notice#W3C_Trademarks">trademark</a>
simon@5276 114 and <a
simon@5276 115 href="http://www.w3.org/Consortium/Legal/copyright-documents">document
simon@5276 116 use</a> rules apply.</p>
simon@5276 117 <!--end-copyright-->
simon@5276 118 <hr title="Separator for header">
simon@5276 119 </div>
simon@5276 120
simon@5276 121 <h2 class="no-num no-toc" id=abstract>Abstract</h2>
simon@5276 122
simon@5276 123 <p>CSS transforms allows elements styled with CSS to be transformed in
simon@5276 124 two-dimensional or three-dimensional space. This specification is the
simon@5276 125 convergence of the <a href="http://www.w3.org/TR/css3-2d-transforms/">CSS
simon@5276 126 2D transforms</a>, <a href="http://www.w3.org/TR/css3-3d-transforms/">CSS
simon@5276 127 3D transforms</a> and <a
simon@5276 128 href="http://www.w3.org/TR/2009/WD-SVG-Transforms-20090320/">SVG
simon@5276 129 transforms</a> specifications.
simon@5276 130
simon@5276 131 <h2 class="no-num no-toc" id=status>Status of this document</h2>
simon@5276 132 <!--begin-status-->
simon@5276 133
simon@5276 134 <p>This is a public copy of the editors' draft. It is provided for
simon@5276 135 discussion only and may change at any moment. Its publication here does
simon@5276 136 not imply endorsement of its contents by W3C. Don't cite this document
simon@5276 137 other than as work in progress.
simon@5276 138
simon@5276 139 <p>The (<a
dschulze@5624 140 href="http://lists.w3.org/Archives/Public/public-fx/">archived</a>) public
dschulze@5624 141 mailing list <a href="mailto:public-fx@w3.org">public-fx@w3.org</a> (see
dschulze@5624 142 <a href="http://www.w3.org/Mail/Request">instructions</a>) is preferred
dschulze@5624 143 for discussion of this specification. When sending e-mail, please put the
dschulze@5892 144 text “css3-transforms” in the subject, preferably like this:
dschulze@5892 145 “[<!---->css3-transforms<!---->] <em>…summary of comment…</em>”
simon@5276 146
dschulze@5624 147 <p>This document was produced by the <a
dschulze@5624 148 href="http://www.w3.org/Style/CSS/members">CSS Working Group</a> (part of
dschulze@5624 149 the <a href="http://www.w3.org/Style/">Style Activity</a>) and the <a
dschulze@5624 150 href="http://www.w3.org/Graphics/SVG/">SVG Working Group</a> (part of the
dschulze@5624 151 <a href="http://www.w3.org/Graphics/">Graphics Activity</a>).
dschulze@5624 152
dschulze@5624 153 <p>This document was produced by groups operating under the <a
dschulze@5624 154 href="http://www.w3.org/Consortium/Patent-Policy-20040205/">5 February
dschulze@5624 155 2004 W3C Patent Policy</a>. W3C maintains a <a
dschulze@5624 156 href="http://www.w3.org/2004/01/pp-impl/32061/status"
dschulze@5624 157 rel=disclosure>public list of any patent disclosures (CSS)</a> and a <a
dschulze@5624 158 href="http://www.w3.org/2004/01/pp-impl/19480/status"
dschulze@5624 159 rel=disclosure>public list of any patent disclosures (SVG)</a> made in
dschulze@5624 160 connection with the deliverables of each group; these pages also include
simon@5276 161 instructions for disclosing a patent. An individual who has actual
simon@5276 162 knowledge of a patent which the individual believes contains <a
dschulze@5624 163 href="http://www.w3.org/Consortium/Patent-Policy-20040205/#def-essential">Essential
simon@5276 164 Claim(s)</a> must disclose the information in accordance with <a
dschulze@5624 165 href="http://www.w3.org/Consortium/Patent-Policy-20040205/#sec-Disclosure">section
dschulze@5624 166 6 of the W3C Patent Policy</a>.</p>
simon@5276 167 <!--end-status-->
simon@5276 168
dschulze@5541 169 <p> This specification replaces the former <a
dschulze@5541 170 href="http://www.w3.org/TR/css3-2d-transforms/"
dschulze@5541 171 title="CSS 2D Transforms">CSS 2D Transforms</a> and <a
dschulze@5541 172 href="http://www.w3.org/TR/css3-3d-transforms/"
dschulze@5541 173 title="CSS 3D Transforms Module Level 3">CSS 3D Transforms</a>
dschulze@5541 174 specifications, as well as <a href="http://www.w3.org/TR/SVG-Transforms/"
dschulze@5541 175 title="SVG Transforms 1.0">SVG Transforms</a>.
dschulze@5541 176
simon@5276 177 <p> The <a href=ChangeLog>list of changes made to this specification</a> is
simon@5276 178 available.
simon@5276 179
simon@5276 180 <h2 class="no-num no-toc" id=contents>Table of contents</h2>
simon@5276 181 <!--begin-toc-->
simon@5276 182
simon@5276 183 <ul class=toc>
simon@5276 184 <li><a href="#introduction"><span class=secno>1. </span>Introduction</a>
simon@5276 185
simon@5276 186 <li><a href="#module-interactions"><span class=secno>2. </span>Module
simon@5276 187 Interactions</a>
simon@5276 188
simon@5276 189 <li><a href="#css-values"><span class=secno>3. </span>CSS Values</a>
simon@5276 190
simon@5276 191 <li><a href="#definitions"><span class=secno>4. </span>Definitions</a>
simon@5276 192
dschulze@5740 193 <li><a href="#two-dimensional-subset"><span class=secno>5. </span> Two
dschulze@5726 194 Dimensional Subset </a>
dschulze@5726 195
dschulze@5726 196 <li><a href="#transform-rendering"><span class=secno>6. </span>The
simon@5276 197 Transform Rendering Model</a>
simon@5276 198 <ul class=toc>
dschulze@5726 199 <li><a href="#transform-3d-rendering"><span class=secno>6.1. </span>3D
simon@5276 200 Transform Rendering</a>
ayg@5901 201
ayg@5901 202 <li><a href="#processing-of-perspective-transformed-boxes"><span
ayg@5901 203 class=secno>6.2. </span> Processing of Perspective-Transformed Boxes
ayg@5901 204 </a>
simon@5276 205 </ul>
simon@5276 206
dschulze@5726 207 <li><a href="#transform-property"><span class=secno>7. </span> The
dschulze@6300 208 ‘<code class=property>transform</code>’ Property </a>
simon@5276 209
dschulze@5726 210 <li><a href="#transform-origin-property"><span class=secno>8. </span> The
dschulze@6300 211 ‘<code class=property>transform-origin</code>’ Property </a>
dschulze@5642 212
dschulze@5726 213 <li><a href="#transform-style-property"><span class=secno>9. </span> The
dschulze@6300 214 ‘<code class=property>transform-style</code>’ Property </a>
dschulze@5642 215
dschulze@5726 216 <li><a href="#perspective-property"><span class=secno>10. </span> The
dschulze@6300 217 ‘<code class=property>perspective</code>’ Property </a>
dschulze@5642 218
dschulze@5726 219 <li><a href="#perspective-origin-property"><span class=secno>11. </span>
dschulze@6300 220 The ‘<code class=property>perspective-origin</code>’ Property </a>
dschulze@5642 221
dschulze@5726 222 <li><a href="#backface-visibility-property"><span class=secno>12. </span>
dschulze@6300 223 The ‘<code class=property>backface-visibility</code>’ Property </a>
dschulze@5642 224
dschulze@5726 225 <li><a href="#svg-transform"><span class=secno>13. </span> The SVG
dschulze@5892 226 ‘<code class=property>transform</code>’ Attribute </a>
simon@5276 227 <ul class=toc>
dschulze@5726 228 <li><a href="#transform-attribute-specificity"><span class=secno>13.1.
dschulze@5892 229 </span> SVG ‘<code class=property>transform</code>’ attribute
dschulze@5892 230 specificity </a>
dschulze@5751 231
dschulze@5751 232 <li><a href="#svg-syntax"><span class=secno>13.2. </span> Syntax of the
dschulze@5892 233 SVG ‘<code class=property>transform</code>’ attribute </a>
simon@5276 234 <ul class=toc>
dschulze@5751 235 <li><a href="#svg-transform-list"><span class=secno>13.2.1. </span>
dschulze@5751 236 Transform List </a>
simon@5276 237
dschulze@5726 238 <li><a href="#svg-functional-notation"><span class=secno>13.2.2.
dschulze@5751 239 </span> Functional Notation </a>
dschulze@5751 240
dschulze@5751 241 <li><a href="#svg-data-types"><span class=secno>13.2.3. </span> SVG
dschulze@5751 242 Data Types </a>
simon@5276 243 <ul class=toc>
dschulze@5726 244 <li><a href="#svg-transform-value"><span class=secno>13.2.3.1.
dschulze@5751 245 </span> The <var>&lt;translation-value&gt;</var> and
dschulze@5751 246 <var>&lt;length&gt;</var> type </a>
dschulze@5751 247
dschulze@5751 248 <li><a href="#svg-angle"><span class=secno>13.2.3.2. </span> The
dschulze@5751 249 <var>&lt;angle&gt;</var> type </a>
dschulze@5751 250
dschulze@5751 251 <li><a href="#svg-number"><span class=secno>13.2.3.3. </span> The
dschulze@5751 252 <var>&lt;number&gt;</var> type </a>
simon@5276 253 </ul>
simon@5276 254 </ul>
simon@5276 255
simon@5276 256 <li><a href="#svg-gradient-transform-pattern-transform"><span
dschulze@5892 257 class=secno>13.3. </span> The SVG ‘<code
dschulze@5892 258 class=property>gradientTransform</code>’ and ‘<code
dschulze@5892 259 class=property>patternTransform</code>’ attributes </a>
simon@5276 260
dschulze@5726 261 <li><a href="#svg-transform-functions"><span class=secno>13.4. </span>
dschulze@5658 262 SVG transform functions </a>
dschulze@5642 263
dschulze@5726 264 <li><a href="#svg-three-dimensional-functions"><span class=secno>13.5.
simon@5276 265 </span>SVG and 3D transform functions</a>
simon@5276 266
dschulze@5751 267 <li><a href="#svg-user-coordinate-space"><span class=secno>13.6. </span>
dschulze@5751 268 User coordinate space </a>
dschulze@5751 269
dschulze@5751 270 <li><a href="#transform-attribute-dom"><span class=secno>13.7. </span>
dschulze@5892 271 SVG DOM interface for the ‘<code class=property>transform</code>’
dschulze@5892 272 attribute </a>
simon@5276 273 </ul>
simon@5276 274
dschulze@5895 275 <li><a href="#svg-animation"><span class=secno>14. </span> SVG Animation
dschulze@5895 276 </a>
dschulze@5895 277 <ul class=toc>
dschulze@5921 278 <li><a href="#svg-animate-element"><span class=secno>14.1. </span> The
dschulze@5921 279 ‘<code class=property>animate</code>’ and ‘<code
dschulze@5921 280 class=property>set</code>’ element </a>
dschulze@5895 281
dschulze@5900 282 <li><a href="#neutral-element"><span class=secno>14.2. </span> Neutral
dschulze@5900 283 element for addition </a>
dschulze@5900 284
dschulze@5900 285 <li><a href="#svg-attribute-name"><span class=secno>14.3. </span> The
dschulze@5895 286 SVG ‘<code class=property>attributeName</code>’ attribute </a>
dschulze@5895 287 </ul>
dschulze@5895 288
dschulze@5895 289 <li><a href="#transform-functions"><span class=secno>15. </span> The
simon@5276 290 Transform Functions </a>
simon@5276 291 <ul class=toc>
dschulze@5895 292 <li><a href="#two-d-transform-functions"><span class=secno>15.1.
simon@5276 293 </span>2D Transform Functions</a>
simon@5276 294
dschulze@5895 295 <li><a href="#three-d-transform-functions"><span class=secno>15.2.
simon@5276 296 </span>3D Transform Functions</a>
simon@5276 297 </ul>
simon@5276 298
dschulze@5895 299 <li><a href="#transform-function-lists"><span class=secno>16. </span> The
simon@5276 300 Transform Function Lists </a>
simon@5276 301
dschulze@5895 302 <li><a href="#animation"><span class=secno>17. </span> Interpolation of
dschulze@5690 303 Transforms </a>
dschulze@5892 304
dschulze@5895 305 <li><a href="#transform-primitives"><span class=secno>18. </span>
dschulze@5892 306 Transform function primitives and derivatives </a>
dschulze@5892 307
dschulze@5895 308 <li><a href="#interpolation-of-transform-functions"><span class=secno>19.
dschulze@5892 309 </span> Interpolation of primitives and derived transform functions </a>
dschulze@5892 310
dschulze@5895 311 <li><a href="#matrix-interpolation"><span class=secno>20. </span>
dschulze@5892 312 Interpolation of Matrices </a>
dschulze@5690 313 <ul class=toc>
dschulze@5895 314 <li><a href="#matrix-decomposing"><span class=secno>20.1.
dschulze@5892 315 </span>Decomposing the Matrix</a>
dschulze@5892 316
dschulze@5895 317 <li><a href="#matrix-values-interpolation"><span class=secno>20.2.
dschulze@5892 318 </span> Interpolation of decomposed matrix values </a>
dschulze@5892 319
dschulze@5895 320 <li><a href="#matrix-recomposing"><span class=secno>20.3. </span>
dschulze@5892 321 Recomposing the Matrix </a>
dschulze@5690 322 </ul>
simon@5276 323
dschulze@5895 324 <li><a href="#mathematical-description"><span class=secno>21. </span>
simon@5276 325 Mathematical Description of Transform Functions </a>
simon@5276 326
dschulze@5895 327 <li><a href="#references"><span class=secno>22. </span>References</a>
simon@5276 328 <ul class=toc>
simon@5276 329 <li class=no-num><a href="#normative-references">Normative
simon@5276 330 references</a>
simon@5276 331
simon@5276 332 <li class=no-num><a href="#other-references">Other references</a>
simon@5276 333 </ul>
simon@5276 334
simon@5276 335 <li class=no-num><a href="#property-index">Property index</a>
simon@5276 336
simon@5276 337 <li class=no-num><a href="#index">Index</a>
simon@5276 338 </ul>
simon@5276 339 <!--end-toc-->
simon@5276 340
simon@5276 341 <h2 id=introduction><span class=secno>1. </span>Introduction</h2>
simon@5276 342
simon@5276 343 <p><em>This section is not normative.</em>
simon@5276 344
simon@5276 345 <p> The CSS <a href="http://www.w3.org/TR/REC-CSS2/visuren.html">visual
simon@5276 346 formatting model</a> describes a coordinate system within each element is
simon@5276 347 positioned. Positions and sizes in this coordinate space can be thought of
simon@5276 348 as being expressed in pixels, starting in the origin of point with
simon@5276 349 positive values proceeding to the right and down.
simon@5276 350
dschulze@5892 351 <p> This coordinate space can be modified with the ‘<a
dschulze@5892 352 href="#effects"><code class=property>transform</code></a>’ property.
dschulze@5740 353 Using transform, elements can be translated, rotated and scaled in two or
dschulze@5740 354 three dimensional space.
simon@5276 355
simon@5276 356 <p> Additional properties make working with transforms easier, and allow
simon@5276 357 the author to control how nested three-dimensional transforms interact.
simon@5276 358
simon@5276 359 <ul>
dschulze@5892 360 <li> The ‘<a href="#transform-origin"><code
dschulze@5892 361 class=property>transform-origin</code></a>’ property provides a
dschulze@5740 362 convenient way to control the origin about which transforms on an element
dschulze@5740 363 are applied.
dschulze@5740 364
dschulze@5892 365 <li> The ‘<a href="#perspective"><code
dschulze@5892 366 class=property>perspective</code></a>’ property allows the author to
dschulze@5892 367 make child elements with three-dimensional transforms appear as if they
dschulze@5892 368 live in a common three-dimensional space. The ‘<a
dschulze@5740 369 href="#perspective-origin"><code
dschulze@5892 370 class=property>perspective-origin</code></a>’ property provides control
dschulze@5892 371 over the origin at which perspective is applied, effectively changing the
dschulze@5892 372 location of the "vanishing point".
dschulze@5892 373
dschulze@5892 374 <li> The ‘<a href="#transform-style"><code
dschulze@5892 375 class=property>transform-style</code></a>’ property allows
simon@5276 376 3D-transformed elements and their 3D-transformed descendants to share a
simon@5276 377 common three-dimensional space, allowing the construction of hierarchies
simon@5276 378 of three-dimensional objects.
simon@5276 379
dschulze@5892 380 <li> The ‘<a href="#backface-visibility"><code
dschulze@5892 381 class=property>backface-visibility</code></a>’ property comes into play
dschulze@5892 382 when an element is flipped around via three-dimensional transforms such
dschulze@5892 383 that its reverse side is visible to the viewer. In some situations it is
dschulze@5892 384 desirable to hide the element in this situation, which is possible using
dschulze@5892 385 the value of ‘<code class=css>hidden</code>’ for this property.
simon@5276 386 </ul>
simon@5276 387
dschulze@5892 388 <p> Note that while some values of the ‘<a href="#effects"><code
dschulze@5892 389 class=property>transform</code></a>’ property allow an element to be
dschulze@5740 390 transformed in a three-dimensional coordinate system, the elements
dschulze@5740 391 themselves are not three-dimensional objects. Instead, they exist on a
dschulze@5740 392 two-dimensional plane (a flat surface) and have no depth.</p>
simon@5276 393 <!-- ======================================================================================================= -->
simon@5276 394
simon@5276 395 <h2 id=module-interactions><span class=secno>2. </span>Module Interactions</h2>
simon@5276 396
simon@5276 397 <p>This module defines a set of CSS properties that affect the visual
simon@5276 398 rendering of elements to which those properties are applied; these effects
simon@5276 399 are applied after elements have been sized and positioned according to the
simon@5276 400 <a href="http://www.w3.org/TR/CSS2/visuren.html"
simon@5276 401 title="Visual formatting model">Visual formatting model</a> from <a
simon@5276 402 href="#CSS21" rel=biblioentry>[CSS21]<!--{{!CSS21}}--></a>. Some values of
simon@5276 403 these properties result in the creation of a <a
simon@5276 404 href="http://www.w3.org/TR/CSS2/visuren.html#containing-block"
simon@5276 405 title="Visual formatting model">containing block</a>, and/or the creation
simon@5276 406 of a <a href="http://www.w3.org/TR/CSS2/visuren.html#z-index"
simon@5276 407 title="Visual formatting model">stacking context</a>.
simon@5276 408
simon@5276 409 <p> Three-dimensional transforms can also affect the visual layering of
simon@5276 410 elements, and thus override the back-to-front painting order described in
simon@5276 411 <a href="http://www.w3.org/TR/CSS2/zindex.html"
simon@5276 412 title="Elaborate description of Stacking Contexts">Appendix E</a> of <a
simon@6214 413 href="#CSS21" rel=biblioentry>[CSS21]<!--{{!CSS21}}--></a>.
simon@6214 414
simon@6214 415 <p> Transforms affect the rendering of backgounds on elements with a value
dschulze@6300 416 of ‘<code class=css>fixed</code>’ for the ‘<code class=css><code
dschulze@6300 417 class=property><a
dschulze@6300 418 href="http://www.w3.org/TR/css3-background/#the-background-attachment">background-attachment</a></code></code>’
simon@6214 419 property, which is specified in <a href="#CSS3BG"
dschulze@6893 420 rel=biblioentry>[CSS3BG]<!--{{!CSS3BG}}--></a>.
simon@5276 421
simon@5276 422 <h2 id=css-values><span class=secno>3. </span>CSS Values</h2>
simon@5276 423
simon@5276 424 <p>This specification follows the <a
simon@5276 425 href="http://www.w3.org/TR/CSS21/about.html#property-defs">CSS property
simon@5276 426 definition conventions</a> from <a href="#CSS21"
simon@5276 427 rel=biblioentry>[CSS21]<!--{{!CSS21}}--></a>. Value types not defined in
simon@5276 428 this specification are defined in CSS Level 2 Revision 1 <a
simon@5276 429 href="#CSS21" rel=biblioentry>[CSS21]<!--{{!CSS21}}--></a>.
simon@5276 430
simon@5276 431 <p>In addition to the property-specific values listed in their definitions,
simon@5276 432 all properties defined in this specification also accept the <a
simon@5276 433 href="http://www.w3.org/TR/CSS21/cascade.html#value-def-inherit">inherit</a>
simon@5276 434 keyword as their property value. For readability it has not been repeated
simon@5276 435 explicitly.
simon@5276 436
simon@5276 437 <h2 id=definitions><span class=secno>4. </span>Definitions</h2>
simon@5276 438
simon@5276 439 <p> When used in this specification, terms have the meanings assigned in
simon@5276 440 this section.
simon@5276 441
simon@5276 442 <dl>
simon@5276 443 <dt id=TermBoundingBox><dfn id=bounding-box>bounding box</dfn>
simon@5276 444
simon@5276 445 <dd>
simon@5276 446 <p> A bounding box is the object bounding box for all SVG elements
simon@5276 447 without an associated CSS layout box and the border box for all other
simon@5276 448 elements. The bounding box of a table is the border box of its <a
simon@5276 449 href="http://www.w3.org/TR/CSS21/tables.html#model">table wrapper
bert@6706 450 box</a>, not its table box.
simon@5276 451
simon@5276 452 <dt id=TermTransformableElement><dfn
simon@5276 453 id=transformable-element>transformable element</dfn>
simon@5276 454
simon@5276 455 <dd>
eoconnor@6894 456 <p> A transformable element is an element in one of these categories:
eoconnor@6894 457
eoconnor@6894 458 <ul>
eoconnor@6894 459 <li> an element whose layout is governed by the CSS box model which is
eoconnor@6894 460 either a <a
eoconnor@6894 461 href="http://www.w3.org/TR/CSS2/visuren.html#block-level">block-level</a>
eoconnor@6894 462 or <a href="http://www.w3.org/TR/CSS2/visuren.html#x13">atomic
eoconnor@6894 463 inline-level element</a>, or whose ‘<code
eoconnor@6894 464 class=property>display</code>’ property computes to ‘<code
eoconnor@6894 465 class=css>table-row</code>’, ‘<code
eoconnor@6894 466 class=css>table-row-group</code>’, ‘<code
eoconnor@6894 467 class=css>table-header-group</code>’, ‘<code
eoconnor@6894 468 class=css>table-footer-group</code>’, ‘<code
eoconnor@6894 469 class=css>table-cell</code>’, or ‘<code
eoconnor@6894 470 class=css>table-caption</code>’ <a href="#CSS21"
eoconnor@6894 471 rel=biblioentry>[CSS21]<!--{{!CSS21}}--></a>
eoconnor@6894 472
dschulze@6901 473 <li> an element in the SVG namespace and not governed by the CSS box
dschulze@6901 474 model which has the attributes ‘<a href="#effects"><code
dschulze@6901 475 class=property>transform</code></a>’, ‘<code
eoconnor@6894 476 class=property>patternTransform</code>’ or ‘<code
eoconnor@6894 477 class=property>gradientTransform</code>’ <a href="#SVG11"
eoconnor@6894 478 rel=biblioentry>[SVG11]<!--{{!SVG11}}--></a>
eoconnor@6894 479 </ul>
simon@5276 480
dschulze@5931 481 <dt id=TermLocalCoordinateSystem><dfn id=local-coordinate-system>local
dschulze@5931 482 coordinate system</dfn>
dschulze@5931 483
dschulze@5931 484 <dd>
dschulze@5931 485 <p> In general, a coordinate system defines locations and distances on
dschulze@5931 486 the current canvas. The current local coordinate system (also user
dschulze@5931 487 coordinate system) is the coordinate system that is currently active and
dschulze@5931 488 which is used to define how coordinates and lengths are located and
bert@6706 489 computed, respectively, on the current canvas.
dschulze@5931 490
dschulze@6300 491 <dt id=TermUserCoordinateSystem><dfn id=user-coordinate-system>user
dschulze@6300 492 coordinate system</dfn>
dschulze@6300 493
dschulze@6300 494 <dd>
dschulze@6300 495 <p> See definition of <a class=term href="#local-coordinate-system">local
bert@6706 496 coordinate system</a>.
dschulze@6300 497
simon@5276 498 <dt id=TermPerspectiveMatrix><dfn id=perspective-matrix>perspective
simon@5276 499 matrix</dfn>
simon@5276 500
simon@5276 501 <dd>
dschulze@5892 502 <p> A matrix computed from the values of the ‘<a
dschulze@5931 503 href="#perspective"><code class=property>perspective</code></a>’ and
dschulze@5931 504 ‘<a href="#perspective-origin"><code
dschulze@5931 505 class=property>perspective-origin</code></a>’ properties as described
bert@6706 506 <a href="#perspective-matrix-computation">below</a>.
simon@5276 507
simon@5276 508 <dt id=TermTransformationMatrix><dfn
simon@5276 509 id=transformation-matrix>transformation matrix</dfn>
simon@5276 510
simon@5276 511 <dd>
dschulze@5931 512 <p> A matrix that defines the mathematical mapping from one coordinate
dschulze@5931 513 system into another. It is computed from the values of the ‘<a
dschulze@5931 514 href="#effects"><code class=property>transform</code></a>’ and ‘<a
dschulze@5931 515 href="#transform-origin"><code
dschulze@5931 516 class=property>transform-origin</code></a>’ properties as described <a
bert@6706 517 href="#transformation-matrix-computation">below</a>.
dschulze@5931 518
dschulze@5931 519 <dt id=TermCurrentTransformationMatrix><dfn
dschulze@5931 520 id=current-transformation-matrix-ctm>current transformation matrix
dschulze@5931 521 (CTM)</dfn>
dschulze@5931 522
dschulze@5931 523 <dd>
dschulze@5931 524 <p> A matrix that defines the mapping from the local coordinate system
bert@6706 525 into the viewport coordinate system.
simon@5276 526
simon@5276 527 <dt id=TermAccumulated3DTransformationMatrix> <dfn
simon@5276 528 id=accumulated-3d-transformation-matrix>accumulated 3D transformation
simon@5276 529 matrix</dfn>
simon@5276 530
simon@5276 531 <dd>
simon@5276 532 <p> A matrix computed for elements in a <a href="#d-rendering-context">3D
simon@5276 533 rendering context</a>, as described <a
bert@6706 534 href="#accumulated-3d-transformation-matrix-computation">below</a>.
simon@5276 535
dschulze@5690 536 <dt id=TermIdentityTransformFunction> <dfn
dschulze@5931 537 id=identity-transform-function>identity transform function</dfn>
dschulze@5690 538
dschulze@5690 539 <dd>
dschulze@5690 540 <p> A <a href="#transform-functions">transform function</a> that is
dschulze@5690 541 equivalent to a identity 4x4 matrix (see <a
dschulze@5690 542 href="#mathematical-description">Mathematical Description of Transform
dschulze@5892 543 Functions</a>). Examples for identity transform functions are ‘<code
dschulze@5892 544 class=css>translate(0)</code>’, ‘<code class=css>translate3d(0, 0,
dschulze@5892 545 0)</code>’, ‘<code class=css>translateX(0)</code>’, ‘<code
dschulze@5892 546 class=css>translateY(0)</code>’, ‘<code
dschulze@5892 547 class=css>translateZ(0)</code>’, ‘<code
dschulze@5892 548 class=css>scale(1)</code>’, ‘<code class=css>scaleX(1)</code>’,
dschulze@5892 549 ‘<code class=css>scaleY(1)</code>’, ‘<code
dschulze@5892 550 class=css>scaleZ(1)</code>’, ‘<code class=css>rotate(0)</code>’,
dschulze@5892 551 ‘<code class=css>rotate3d(1, 1, 1, 0)</code>’, ‘<code
dschulze@5892 552 class=css>rotateX(0)</code>’, ‘<code class=css>rotateY(0)</code>’,
dschulze@6608 553 ‘<code class=css>rotateZ(0)</code>’, ‘<code class=css>skew(0,
dschulze@6608 554 0)</code>’, ‘<code class=css>skewX(0)</code>’, ‘<code
dschulze@6608 555 class=css>skewY(0)</code>’, ‘<code class=css>matrix(1, 0, 0, 1, 0,
dschulze@6608 556 0)</code>’ and ‘<code class=css>matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0,
dschulze@6608 557 0, 1, 0, 0, 0, 0, 1)</code>’. A special case is perspective: ‘<code
dschulze@5900 558 class=css>perspective(infinity)</code>’. The value of m<sub>34</sub>
dschulze@5900 559 becomes infinitesimal small and the transform function is therefore
bert@6706 560 assumed to be equal to the identity matrix.
dschulze@5690 561
simon@5276 562 <dt id=Term3DRenderingContext><dfn id=d-rendering-context>3D rendering
simon@5276 563 context</dfn>
simon@5276 564
simon@5276 565 <dd>
simon@5276 566 <p> A containing block hierarchy of one or more levels, instantiated by
dschulze@5892 567 elements with a computed value for the ‘<a
dschulze@6300 568 href="#transform-style"><code
dschulze@6300 569 class=property>transform-style</code></a>’ property of ‘<code
dschulze@6300 570 class=css>preserve-3d</code>’, whose elements share a common
bert@6706 571 three-dimensional coordinate system.
simon@5276 572 </dl>
simon@5276 573 <!-- ======================================================================================================= -->
simon@5276 574
dschulze@5740 575 <h2 id=two-dimensional-subset><span class=secno>5. </span> Two Dimensional
dschulze@5740 576 Subset</h2>
dschulze@5726 577
dschulze@5726 578 <p> UAs may not always be able to render three-dimensional transforms and
dschulze@5726 579 then just support a two-dimensional subset of this specification. In this
dschulze@5726 580 case <a href="#three-d-transform-functions">three-dimensional
dschulze@5892 581 transforms</a> and the properties ‘<a href="#transform-style"><code
dschulze@5892 582 class=property>transform-style</code></a>’, ‘<a
dschulze@5892 583 href="#perspective"><code class=property>perspective</code></a>’, ‘<a
dschulze@5892 584 href="#perspective-origin"><code
dschulze@5892 585 class=property>perspective-origin</code></a>’ and ‘<a
dschulze@5726 586 href="#backface-visibility"><code
dschulze@5892 587 class=property>backface-visibility</code></a>’ must not be supported.
dschulze@5892 588 Section <a href="#transform-3d-rendering">3D Transform Rendering</a> does
dschulze@5892 589 not apply. Matrix decomposing uses the technique taken from the "unmatrix"
dschulze@5892 590 method in "Graphics Gems II, edited by Jim Arvo", simplified for the 2D
dschulze@5892 591 case. Section <a href="#mathematical-description">Mathematical Description
dschulze@5892 592 of Transform Functions</a> is still effective but can be reduced by using
dschulze@5900 593 a 3x3 transformation matrix where <em>a</em> equals
dschulze@5900 594 <em>m<sub>11</sub></em>, <em>b</em> equals <em>m<sub>12</sub></em>,
dschulze@5900 595 <em>c</em> equals <em>m<sub>21</sub></em>, <em>d</em> equals
dschulze@5900 596 <em>m<sub>22</sub></em>, <em>e</em> equals <em>m<sub>41</sub></em> and
dschulze@5900 597 <em>f</em> equals <em>m<sub>42</sub></em> (see <a href="#MatrixDefined">A
dschulze@5900 598 2D 3x2 matrix with six parameter</a>).
dschulze@5726 599
dschulze@5726 600 <div class=figure> <img alt="3x3 matrix" height=79 src=3x3matrix.png
dschulze@5726 601 title="\begin{bmatrix} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{bmatrix}"
dschulze@5726 602 width=82>
bert@6706 603 <p class=caption> 3x3 matrix for two-dimensional transformations.
dschulze@5726 604 </div>
dschulze@5726 605
dschulze@5726 606 <div class=example>
dschulze@5726 607 <p> Authors can easily provide a fallback if UAs do not provide support
dschulze@5726 608 for three-dimensional transforms. The following example has two property
dschulze@5892 609 definitions for ‘<a href="#effects"><code
dschulze@5892 610 class=property>transform</code></a>’. The first one consists of two
dschulze@5726 611 two-dimensional transform functions. The second one has a two-dimensional
bert@6706 612 and a three-dimensional transform function.
dschulze@5726 613
dschulze@5726 614 <pre>div {
dschulze@5726 615 transform: scale(2) rotate(45deg);
dschulze@5726 616 transform: scale(2) rotate3d(0, 0, 1, 45deg);
dschulze@5726 617 }</pre>
dschulze@5726 618
dschulze@5726 619 <p> With 3D support, the second definition will override the first one.
dschulze@5726 620 Without 3D support, the second definition is invalid and a UA falls back
bert@6706 621 to the first definition.
dschulze@5726 622 </div>
dschulze@5726 623 <!-- ======================================================================================================= -->
dschulze@5726 624
dschulze@5726 625 <h2 id=transform-rendering><span class=secno>6. </span>The Transform
simon@5276 626 Rendering Model</h2>
dschulze@6893 627
dschulze@6908 628 <p><em>This section is normative.</em>
simon@5276 629
dschulze@5892 630 <p> Specifying a value other than ‘<code class=css>none</code>’ for the
dschulze@5892 631 ‘<a href="#effects"><code class=css>transform</code></a>’ property
dschulze@5931 632 establishes a new <a class=term href="#local-coordinate-system">local
dschulze@5931 633 coordinate system</a> at the element that it is applied to. The mapping
dschulze@5931 634 from where the element would have rendered into that local coordinate
dschulze@5931 635 system is given by the element's <a class=term
dschulze@5931 636 href="#transformation-matrix">transformation matrix</a>. Transformations
dschulze@5931 637 are cumulative. That is, elements establish their local coordinate system
dschulze@5931 638 within the coordinate system of their parent. From the perspective of the
dschulze@5931 639 user, an element effectively accumulates all the ‘<a
dschulze@5892 640 href="#effects"><code class=property>transform</code></a>’ properties of
dschulze@5892 641 its ancestors as well as any local transform applied to it. The
dschulze@5931 642 accumulation of these transforms defines a <a class=term
dschulze@5931 643 href="#current-transformation-matrix-ctm">current transformation matrix
dschulze@5931 644 (CTM)</a> for the element.
simon@5276 645
dschulze@5932 646 <p> The coordinate space is a coordinate system with two axes: the X axis
dschulze@5932 647 increases horizontally to the right; the Y axis increases vertically
eoconnor@6037 648 downwards. Three-dimensional transform functions extend this coordinate
dschulze@5932 649 space into three dimensions, adding a Z axis perpendicular to the plane of
dschulze@5932 650 the screen, that increases towards the viewer.
dschulze@5932 651
dschulze@5936 652 <div class=figure> <img alt="Demonstration of the initial coordinate space"
dschulze@5937 653 height=240 src=coordinates.svg width=270>
bert@6706 654 <p class=caption> Demonstration of the initial coordinate space.
dschulze@5936 655 </div>
dschulze@5931 656
dschulze@5931 657 <p id=transformation-matrix-computation> The <a class=term
dschulze@5931 658 href="#transformation-matrix">transformation matrix</a> is computed from
dschulze@5931 659 the ‘<a href="#effects"><code class=property>transform</code></a>’ and
dschulze@5931 660 ‘<a href="#transform-origin"><code
dschulze@5892 661 class=property>transform-origin</code></a>’ properties as follows:
simon@5276 662
simon@5276 663 <ol>
simon@5276 664 <li>Start with the identity matrix.
simon@5276 665
dschulze@5892 666 <li>Translate by the computed X, Y and Z values of ‘<a
dschulze@5740 667 href="#transform-origin"><code
dschulze@5892 668 class=property>transform-origin</code></a>’
dschulze@5892 669
dschulze@5892 670 <li>Multiply by each of the transform functions in ‘<a
dschulze@6960 671 href="#effects"><code class=property>transform</code></a>’ property
dschulze@6960 672 from left to right
dschulze@5892 673
dschulze@5892 674 <li>Translate by the negated computed X, Y and Z values of ‘<a
dschulze@5740 675 href="#transform-origin"><code
dschulze@5892 676 class=property>transform-origin</code></a>’
simon@5276 677 </ol>
simon@5276 678
simon@5276 679 <p> Transforms apply to <a class=term
simon@5276 680 href="#transformable-element">transformable elements</a>.
simon@5276 681
simon@5276 682 <div class=example>
simon@5276 683 <pre>
simon@5276 684 div {
simon@5276 685 transform: translate(100px, 100px);
simon@5276 686 }
simon@5276 687 </pre>
simon@5276 688
simon@5276 689 <p>This transform moves the element by 100 pixels in both the X and Y
bert@6706 690 directions.
simon@5276 691
dschulze@5644 692 <div class=figure> <img alt="The 100px translation in X and Y" height=250
dschulze@5644 693 src="examples/translate1.svg" width=470></div>
simon@5276 694 </div>
simon@5276 695
simon@5276 696 <div class=example>
dschulze@5625 697 <pre>div {
dschulze@5625 698 height: 100px; width: 100px;
dschulze@5625 699 transform-origin: 50px 50px;
dschulze@5625 700 transform: rotate(45deg);
dschulze@5740 701 }</pre>
dschulze@5740 702
dschulze@5892 703 <p> The ‘<a href="#transform-origin"><code
dschulze@5892 704 class=property>transform-origin</code></a>’ property moves the point of
dschulze@5892 705 origin by 50 pixels in both the X and Y directions. The transform rotates
dschulze@5892 706 the element clockwise by 45° about the point of origin. After all
dschulze@5892 707 transform functions were applied, the translation of the origin gets
bert@6706 708 translated back by -50 pixels in both the X and Y directions.
dschulze@5625 709
dschulze@5740 710 <div class=figure> <img
dschulze@5740 711 alt="The point of origin gets translated temporary" height=250
dschulze@5740 712 src="examples/origin1.svg" width=735></div>
dschulze@5625 713 </div>
dschulze@5625 714
dschulze@5625 715 <div class=example>
simon@5276 716 <pre>
simon@5276 717 div {
simon@5276 718 height: 100px; width: 100px;
simon@5276 719 transform: translate(80px, 80px) scale(1.5, 1.5) rotate(45deg);
simon@5276 720 }
simon@5276 721 </pre>
simon@5276 722
dschulze@5740 723 <p> This transform moves the element by 80 pixels in both the X and Y
dschulze@5892 724 directions, then scales the element by 150%, then rotates it 45°
simon@5276 725 clockwise about the Z axis. Note that the scale and rotation operate
simon@5276 726 about the center of the element, since the element has the default
bert@6706 727 transform-origin of ‘<code class=css>50% 50%</code>’.
simon@5276 728
dschulze@5648 729 <div class=figure> <img alt="The transform specified above" height=270
dschulze@5648 730 src="examples/compound_transform.svg" width=270></div>
simon@5276 731
dschulze@5740 732 <p> Note that an identical rendering can be obtained by nesting elements
bert@6706 733 with the equivalent transforms:
simon@5276 734
simon@5276 735 <pre>
simon@5276 736 &lt;div style="transform: translate(80px, 80px)"&gt;
simon@5276 737 &lt;div style="transform: scale(1.5, 1.5)"&gt;
simon@5276 738 &lt;div style="transform: rotate(45deg)"&gt;&lt;/div&gt;
simon@5276 739 &lt;/div&gt;
dschulze@5740 740 &lt;/div&gt;</pre>
simon@5276 741 </div>
simon@5276 742
dschulze@6901 743 <p> For elements whose layout is governed by the CSS box model, the
dschulze@6901 744 transform property does not affect the flow of the content surrounding the
dschulze@6901 745 transformed element. However, the extent of the overflow area takes into
dschulze@6901 746 account transformed elements. This behavior is similar to what happens
dschulze@6901 747 when elements are offset via relative positioning. Therefore, if the value
dschulze@6901 748 of the ‘<code class=property>overflow</code>’ property is ‘<code
dschulze@5892 749 class=css>scroll</code>’ or ‘<code class=css>auto</code>’,
dschulze@5892 750 scrollbars will appear as needed to see content that is transformed
dschulze@5892 751 outside the visible area.
dschulze@5892 752
dschulze@6901 753 <p> For elements whose layout is governed by the CSS box model, any value
dschulze@6901 754 other than ‘<code class=css>none</code>’ for the transform results in
dschulze@6901 755 the creation of both a stacking context and a containing block. The object
dschulze@6901 756 acts as a containing block for fixed positioned descendants.
simon@5276 757
simon@5276 758 <p class=issue> Is this effect on position:fixed necessary? If so, need to
simon@5276 759 go into more detail here about why fixed positioned objects should do
dschulze@6900 760 this, i.e., that it's much harder to implement otherwise. See <a
dschulze@6900 761 href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=16328">Bug 16328</a>.
simon@5276 762
simon@6214 763 <p> <a href="http://www.w3.org/TR/css3-background/#fixed0">Fixed
simon@6214 764 backgrounds</a> on the root element are affected by any transform
simon@6214 765 specified for that element. For all other elements that are effected by a
simon@6214 766 transform (i.e. have a transform applied to them, or to any of their
dschulze@6300 767 ancestor elements), a value of ‘<code class=css>fixed</code>’ for the
dschulze@6300 768 ‘<code class=property>background-attachment</code>’ property is
dschulze@6904 769 treated as if it had a value of ‘<code class=css>scroll</code>’. The
dschulze@6904 770 computed value of ‘<code class=property>background-attachment</code>’
dschulze@6904 771 is not affected.
simon@6214 772
simon@6214 773 <p class=note> If the root element is transformed, the transformation
simon@6214 774 applies to the entire canvas, including any background specified for the
simon@6214 775 root element. Since <a
simon@6214 776 href="http://www.w3.org/TR/css3-background/#special-backgrounds"> the
simon@5276 777 background painting area for the root element</a> is the entire canvas,
simon@5276 778 which is infinite, the transformation might cause parts of the background
simon@5276 779 that were originally off-screen to appear. For example, if the root
dschulze@6300 780 element's background were repeating dots, and a transformation of ‘<code
dschulze@6300 781 class=css>scale(0.5)</code>’ were specified on the root element, the
dschulze@6300 782 dots would shrink to half their size, but there will be twice as many, so
dschulze@6300 783 they still cover the whole viewport.
simon@5276 784
dschulze@5726 785 <h3 id=transform-3d-rendering><span class=secno>6.1. </span>3D Transform
simon@5276 786 Rendering</h3>
simon@5276 787
simon@5276 788 <p> Normally, elements render as flat planes, and are rendered into the
simon@5276 789 same plane as their containing block. Often this is the plane shared by
simon@5276 790 the rest of the page. Two-dimensional transform functions can alter the
simon@5276 791 appearance of an element, but that element is still rendered into the same
simon@5276 792 plane as its containing block.
simon@5276 793
simon@5276 794 <p> Three-dimensional transforms can result in transformation matrices with
simon@6216 795 a non-zero Z component (where the Z axis projects out of the plane of the
simon@6216 796 screen). This can result in an element rendering on a different plane than
simon@6216 797 that of its containing block. This may affect the front-to-back rendering
simon@6216 798 order of that element relative to other elements, as well as causing it to
simon@6216 799 intersect with other elements. This behavior depends on whether the
simon@5276 800 element is a member of a <a class=term href="#d-rendering-context">3D
simon@5276 801 rendering context</a>, as described below.
simon@5276 802
simon@5276 803 <div class=issue>
simon@5276 804 <p class=desc>This description does not exactly match what WebKit
simon@5276 805 implements. Perhaps it should be changed to match current
dschulze@6900 806 implementations? See <a
dschulze@6900 807 href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=19637">Bug
dschulze@6900 808 19637</a>.
simon@5276 809 </div>
simon@5276 810
simon@5276 811 <div class=example>
simon@5276 812 <p>This example shows the effect of three-dimensional transform applied to
bert@6706 813 an element.
simon@5276 814
simon@5276 815 <pre>
simon@5276 816 &lt;style&gt;
simon@5276 817 div {
simon@5276 818 height: 150px;
simon@5276 819 width: 150px;
simon@5276 820 }
simon@5276 821 .container {
simon@5276 822 border: 1px solid black;
simon@5276 823 }
simon@5276 824 .transformed {
simon@5276 825 transform: rotateY(50deg);
simon@5276 826 }
simon@5276 827 &lt;/style&gt;
simon@5276 828
simon@5276 829 &lt;div class="container"&gt;
simon@5276 830 &lt;div class="transformed"&gt;&lt;/div&gt;
simon@5276 831 &lt;/div&gt;
simon@5276 832 </pre>
simon@5276 833
simon@5276 834 <div class=figure> <img alt="Div with a rotateY transform." height=190
simon@5276 835 src="examples/simple-3d-example.png" width=210></div>
simon@5276 836
dschulze@5892 837 <p>The transform is a 50° rotation about the vertical, Y axis. Note how
bert@6706 838 this makes the blue box appear narrower, but not three-dimensional.
simon@5276 839 </div>
simon@5276 840
dschulze@6300 841 <p> The ‘<a href="#perspective"><code
dschulze@6300 842 class=property>perspective</code></a>’ and ‘<a
dschulze@6300 843 href="#perspective-origin"><code
dschulze@6300 844 class=property>perspective-origin</code></a>’ properties can be used to
dschulze@6300 845 add a feeling of depth to a scene by making elements higher on the Z axis
dschulze@6300 846 (closer to the viewer) appear larger, and those further away to appear
dschulze@6300 847 smaller. The scaling is proportional to <var>d</var>/(<var>d</var> −
dschulze@6300 848 <var>Z</var>) where <var>d</var>, the value of ‘<a
dschulze@6300 849 href="#perspective"><code class=property>perspective</code></a>’, is the
dschulze@6300 850 distance from the drawing plane to the the assumed position of the
dschulze@6300 851 viewer's eye.
simon@5276 852
simon@5276 853 <div class=figure> <img alt="Diagram of scale vs. Z position"
simon@5276 854 src="perspective_distance.png">
dschulze@5892 855 <p class=caption> Diagrams showing how scaling depends on the ‘<a
dschulze@6300 856 href="#perspective"><code class=property>perspective</code></a>’
dschulze@6300 857 property and Z position. In the top diagram, <var>Z</var> is half of
dschulze@6300 858 <var>d</var>. In order to make it appear that the original circle (solid
dschulze@6300 859 outline) appears at <var>Z</var> (dashed circle), the circle is scaled up
dschulze@6300 860 by a factor of two, resulting in the light blue circle. In the bottom
dschulze@6300 861 diagram, the circle is scaled down by a factor of one-third to make it
bert@6706 862 appear behind the original position.
simon@5276 863 </div>
simon@5276 864
simon@5276 865 <p> Normally the assumed position of the viewer's eye is centered on a
dschulze@5892 866 drawing. This position can be moved if desired – for example, if a web
dschulze@5892 867 page contains multiple drawings that should share a common perspective –
dschulze@6300 868 by setting ‘<a href="#perspective-origin"><code
dschulze@6300 869 class=property>perspective-origin</code></a>’.
simon@5276 870
simon@5276 871 <div class=figure> <img alt="Diagram of different perspective-origin"
simon@5276 872 src="perspective_origin.png">
simon@5276 873 <p class=caption> Diagram showing the effect of moving the perspective
bert@6706 874 origin upward.
simon@5276 875 </div>
simon@5276 876
simon@5276 877 <p id=perspective-matrix-computation> The <a
simon@5276 878 href="#TermPerspectiveMatrix"><i>perspective matrix</i></a> is computed as
dschulze@6893 879 follows:
simon@5276 880
simon@5276 881 <ol>
simon@5276 882 <li>Start with the identity matrix.
simon@5276 883
dschulze@5892 884 <li>Translate by the computed X and Y values of ‘<a
dschulze@6300 885 href="#perspective-origin"><code
dschulze@6300 886 class=property>perspective-origin</code></a>’
dschulze@5892 887
dschulze@5892 888 <li>Multiply by the matrix that would be obtained from the ‘<code
simon@5276 889 class=css><a href="#perspective-function"><code
dschulze@5892 890 class=css>perspective(&lt;length&gt;)</code></a></code>’ transform
dschulze@5892 891 function, where the length is provided by the value of the ‘<a
dschulze@6300 892 href="#perspective"><code class=property>perspective</code></a>’
dschulze@6300 893 property
dschulze@5892 894
dschulze@5892 895 <li>Translate by the negated computed X and Y values of ‘<a
dschulze@6300 896 href="#perspective-origin"><code
dschulze@6300 897 class=property>perspective-origin</code></a>’
simon@5276 898 </ol>
simon@5276 899
simon@5276 900 <div class=example>
simon@5276 901 <p>This example shows how perspective can be used to cause
bert@6706 902 three-dimensional transforms to appear more realistic.
simon@5276 903
simon@5276 904 <pre>
simon@5276 905 &lt;style&gt;
simon@5276 906 div {
simon@5276 907 height: 150px;
simon@5276 908 width: 150px;
simon@5276 909 }
simon@5276 910 .container {
simon@5276 911 perspective: 500px;
simon@5276 912 border: 1px solid black;
simon@5276 913 }
simon@5276 914 .transformed {
simon@5276 915 transform: rotateY(50deg);
simon@5276 916 }
simon@5276 917 &lt;/style&gt;
simon@5276 918
simon@5276 919 &lt;div class="container"&gt;
simon@5276 920 &lt;div class="transformed"&gt;&lt;/div&gt;
simon@5276 921 &lt;/div&gt;
simon@5276 922 </pre>
simon@5276 923
simon@5276 924 <div class=figure> <img
simon@5276 925 alt="Div with a rotateY transform, and perspective on its container"
simon@5276 926 height=190 src="examples/simple-perspective-example.png" width=210></div>
simon@5276 927
simon@5276 928 <p>The inner element has the same transform as in the previous example,
simon@5276 929 but its rendering is now influenced by the perspective property on its
simon@5276 930 parent element. Perspective causes vertices that have positive Z
simon@5276 931 coordinates (closer to the viewer) to be scaled up in X and Y, and those
simon@5276 932 further away (negative Z coordinates) to be scaled down, giving an
bert@6706 933 appearance of depth.
simon@5276 934 </div>
simon@5276 935
simon@5276 936 <p> An element with a three-dimensional transform that is not contained in
simon@5276 937 a <a class=term href="#d-rendering-context">3D rendering context</a>
simon@5276 938 renders with the appropriate transform applied, but does not intersect
simon@5276 939 with any other elements. The three-dimensional transform in this case can
simon@5276 940 be considered just as a painting effect, like two-dimensional transforms.
simon@5276 941 Similarly, the transform does not affect painting order. For example, a
simon@5276 942 transform with a positive Z translation may make an element look larger,
simon@5276 943 but does not cause that element to render in front of elements with no
simon@5276 944 translation in Z.
simon@5276 945
simon@5276 946 <p> An element with a three-dimensional transform that is contained in a <a
simon@5276 947 class=term href="#d-rendering-context">3D rendering context</a> can
simon@5276 948 visibly interact with other elements in that same 3D rendering context;
simon@5276 949 the set of elements participating in the same <a class=term
simon@5276 950 href="#d-rendering-context">3D rendering context</a> may obscure each
simon@5276 951 other or intersect, based on their computed transforms. They are rendered
simon@5276 952 as if they are all siblings, positioned in a common 3D coordinate space.
simon@5276 953 The position of each element in that three-dimensional space is determined
simon@5276 954 by accumulating the transformation matrices up from the element that
simon@5276 955 establishes the <a class=term href="#d-rendering-context">3D rendering
simon@5276 956 context</a> through each element that is a containing block for the given
simon@5276 957 element, as described below.
simon@5276 958
simon@5276 959 <div class=example>
simon@5276 960 <pre>
simon@5276 961 &lt;style&gt;
simon@5276 962 div {
simon@5276 963 height: 150px;
simon@5276 964 width: 150px;
simon@5276 965 }
simon@5276 966 .container {
simon@5276 967 perspective: 500px;
simon@5276 968 border: 1px solid black;
simon@5276 969 }
simon@5276 970 .transformed {
simon@5276 971 transform: rotateY(50deg);
simon@5276 972 background-color: blue;
simon@5276 973 }
simon@5276 974 .child {
simon@5276 975 transform-origin: top left;
simon@5276 976 transform: rotateX(40deg);
simon@5276 977 background-color: lime;
simon@5276 978 }
simon@5276 979 &lt;/style&gt;
simon@5276 980
simon@5276 981 &lt;div class="container"&gt;
simon@5276 982 &lt;div class="transformed"&gt;
simon@5276 983 &lt;div class="child"&gt;&lt;/div&gt;
simon@5276 984 &lt;/div&gt;
simon@5276 985 &lt;/div&gt;
simon@5276 986 </pre>
simon@5276 987
simon@5276 988 <p>This example shows how nested 3D transforms are rendered in the absence
dschulze@6300 989 of ‘<code class=css>transform-style: preserve-3d</code>’. The blue
dschulze@6300 990 div is transformed as in the previous example, with its rendering
dschulze@6300 991 influenced by the perspective on its parent element. The lime element
dschulze@6300 992 also has a 3D transform, which is a rotation about the X axis (anchored
dschulze@6300 993 at the top, by virtue of the transform-origin). However, the lime element
dschulze@6300 994 is being rendered into the plane of its parent because it is not a member
bert@6706 995 of a 3D rendering context; the parent is "flattening".
simon@5276 996
simon@5276 997 <div class=figure> <img alt="Nested 3D transforms, with flattening"
simon@5276 998 height=200 src="examples/3d-rendering-context-flat.png" width=240></div>
simon@5276 999 </div>
simon@5276 1000
simon@5276 1001 <p>Elements establish and participate in 3D rendering contexts as follows:
simon@5276 1002
simon@5276 1003 <ul>
simon@5276 1004 <li> A <a class=term href="#d-rendering-context">3D rendering context</a>
simon@5276 1005 is established by a a <a class=term
simon@5276 1006 href="#transformable-element">transformable element</a> whose computed
dschulze@6300 1007 value for ‘<a href="#transform-style"><code
dschulze@6300 1008 class=property>transform-style</code></a>’ is ‘<code
dschulze@6300 1009 class=css>preserve-3d</code>’, and which itself is not part of a 3D
dschulze@6300 1010 rendering context. Note that such an element is always a containing
dschulze@6300 1011 block. An element that establishes a 3D rendering context also
dschulze@6300 1012 participates in that context.
simon@5276 1013
dschulze@5892 1014 <li> An element whose computed value for ‘<a
dschulze@6300 1015 href="#transform-style"><code
dschulze@6300 1016 class=property>transform-style</code></a>’ is ‘<code
dschulze@6300 1017 class=css>preserve-3d</code>’, and which itself participates in a <a
dschulze@6300 1018 class=term href="#d-rendering-context">3D rendering context</a>, extends
dschulze@6300 1019 that 3D rendering context rather than establishing a new one.
simon@5276 1020
simon@5276 1021 <li> An element participates in a <a class=term
simon@5276 1022 href="#d-rendering-context">3D rendering context</a> if its containing
simon@5276 1023 block establishes or extends a <a class=term
simon@5276 1024 href="#d-rendering-context">3D rendering context</a>.
simon@5276 1025 </ul>
simon@5276 1026
simon@5276 1027 <p id=accumulated-3d-transformation-matrix-computation> The final value of
simon@5276 1028 the transform used to render an element in a <a class=term
simon@5276 1029 href="#d-rendering-context">3D rendering context</a> is computed by
simon@5276 1030 accumulating an <a href="#TermAccumulated3DTransformationMatrix">
simon@5276 1031 accumulated 3D transformation matrix</a> as follows:
simon@5276 1032
simon@5276 1033 <ol>
simon@5276 1034 <li>Start with the identity matrix.
simon@5276 1035
simon@5276 1036 <li>For each containing block between the root of the <a class=term
simon@5276 1037 href="#d-rendering-context">3D rendering context</a> and the element in
simon@5276 1038 question:
simon@5276 1039 <ol>
dschulze@6300 1040 <li>multiply the accumulated matrix with the <a class=term
dschulze@6300 1041 href="#perspective-matrix">perspective matrix</a> on the element's
dschulze@6300 1042 containing block (if any). That containing block is not necessarily a
dschulze@6300 1043 member of the 3D rendering context.
simon@5276 1044
simon@5276 1045 <li>apply to the accumulated matrix a translation equivalent to the
simon@5276 1046 horizontal and vertical offset of the element relative to its
simon@5276 1047 containing block as specified by the CSS visual formatting model.
simon@5276 1048
dschulze@6300 1049 <li>multiply the accumulated matrix with the <a class=term
dschulze@6300 1050 href="#transformation-matrix">transformation matrix</a>.
simon@5276 1051 </ol>
simon@5276 1052 </ol>
simon@5276 1053
simon@5276 1054 <div class=example>
simon@5276 1055 <pre>
simon@5276 1056 &lt;style&gt;
simon@5276 1057 div {
simon@5276 1058 height: 150px;
simon@5276 1059 width: 150px;
simon@5276 1060 }
simon@5276 1061 .container {
simon@5276 1062 perspective: 500px;
simon@5276 1063 border: 1px solid black;
simon@5276 1064 }
simon@5276 1065 .transformed {
simon@5276 1066 <b>transform-style: preserve-3d</b>;
simon@5276 1067 transform: rotateY(50deg);
simon@5276 1068 background-color: blue;
simon@5276 1069 }
simon@5276 1070 .child {
simon@5276 1071 transform-origin: top left;
simon@5276 1072 transform: rotateX(40deg);
simon@5276 1073 background-color: lime;
simon@5276 1074 }
simon@5276 1075 &lt;/style&gt;
simon@5276 1076 </pre>
simon@5276 1077
dschulze@6300 1078 <p> This example is identical to the previous example, with the addition
dschulze@6300 1079 of ‘<code class=css>transform-style: preserve-3d</code>’ on the blue
dschulze@6300 1080 element. The blue element now establishes a 3D rendering context, of
dschulze@6300 1081 which the lime element is a member. Now both blue and lime elements share
dschulze@6300 1082 a common three-dimensional space, so the lime element renders as tilting
bert@6706 1083 out from its parent, influenced by the perspective on the container.
simon@5276 1084
simon@5276 1085 <div class=figure> <img alt="Nested 3D transforms, with preserve-3d."
simon@5276 1086 height=200 src="examples/3d-rendering-context-3d.png" width=240></div>
simon@5276 1087 </div>
simon@5276 1088
simon@5276 1089 <p> Elements in the same <a class=term href="#d-rendering-context">3D
simon@5276 1090 rendering context</a> may intersect with each other. User agents must
simon@5276 1091 render intersection by subdividing the planes of intersecting elements as
simon@5276 1092 described by <a
simon@5276 1093 href="http://en.wikipedia.org/wiki/Newell's_algorithm">Newell's
simon@5276 1094 algorithm</a>.
simon@5276 1095
simon@5276 1096 <p> Untransformed elements in a <a class=term
simon@5276 1097 href="#d-rendering-context">3D rendering context</a> render on the Z=0
simon@5276 1098 plane, yet may still intersect with transformed elements.
simon@5276 1099
simon@5276 1100 <p> Within a <a class=term href="#d-rendering-context">3D rendering
simon@5276 1101 context</a>, the rendering order of non-intersecting elements is based on
simon@5276 1102 their position on the Z axis after the application of the accumulated
simon@5276 1103 transform. Elements at the same Z position render in <a
simon@5276 1104 href="http://www.w3.org/TR/CSS2/zindex.html#painting-order">stacking
simon@5276 1105 context order</a>.
simon@5276 1106
simon@5276 1107 <div class=example>
simon@5276 1108 <pre>
simon@5276 1109 &lt;style&gt;
simon@5276 1110 .container {
simon@5276 1111 background-color: rgba(0, 0, 0, 0.3);
simon@5276 1112 transform-style: preserve-3d;
simon@5276 1113 perspective: 500px;
simon@5276 1114 }
simon@5276 1115 .container > div {
simon@5276 1116 position: absolute;
simon@5276 1117 left: 0;
simon@5276 1118 }
simon@5276 1119 .container > :first-child {
simon@5276 1120 transform: rotateY(45deg);
simon@5276 1121 background-color: orange;
simon@5276 1122 top: 10px;
simon@5276 1123 height: 135px;
simon@5276 1124 }
simon@5276 1125 .container > :last-child {
simon@5276 1126 transform: translateZ(40px);
simon@5276 1127 background-color: rgba(0, 0, 255, 0.75);
simon@5276 1128 top: 50px;
simon@5276 1129 height: 100px;
simon@5276 1130 }
simon@5276 1131 &lt;/style&gt;
simon@5276 1132
simon@5276 1133 &lt;div class="container"&gt;
simon@5276 1134 &lt;div&gt;&lt;/div&gt;
simon@5276 1135 &lt;div&gt;&lt;/div&gt;
simon@5276 1136 &lt;/div&gt;
simon@5276 1137 </pre>
simon@5276 1138
simon@5276 1139 <p> This example shows show elements in a 3D rendering context can
simon@5276 1140 intersect. The container element establishes a 3D rendering context for
simon@5276 1141 itself and its two children. The children intersect with eachother, and
bert@6706 1142 the orange element also intersects with the container.
simon@5276 1143
simon@5276 1144 <div class=figure> <img alt="Intersecting sibling elements." height=200
simon@5276 1145 src="examples/3d-intersection.png" width=200></div>
simon@5276 1146 </div>
simon@5276 1147
simon@5276 1148 <p> Using three-dimensional transforms, it's possible to transform an
ayg@5901 1149 element such that its reverse side is towards the viewer. 3D-transformed
simon@5276 1150 elements show the same content on both sides, so the reverse side looks
simon@5276 1151 like a mirror-image of the front side (as if the element were projected
simon@5276 1152 onto a sheet of glass). Normally, elements whose reverse side is towards
dschulze@5892 1153 the viewer remain visible. However, the ‘<a
dschulze@6300 1154 href="#backface-visibility"><code
dschulze@6300 1155 class=property>backface-visibility</code></a>’ property allows the
dschulze@6300 1156 author to make an element invisible when its reverse side is towards the
dschulze@6300 1157 viewer. This behavior is "live"; if an element with ‘<code
dschulze@6300 1158 class=css>backface-visibility: hidden</code>’ were animating, such that
dschulze@6300 1159 its front and reverse sides were alternately visible, then it would only
dschulze@6300 1160 be visible when the front side were towards the viewer.
ayg@5901 1161
ayg@5901 1162 <h3 id=processing-of-perspective-transformed-boxes><span class=secno>6.2.
ayg@5901 1163 </span> Processing of Perspective-Transformed Boxes</h3>
ayg@5901 1164
ayg@5901 1165 <div class=issue>
ayg@5901 1166 <p class=desc> This is a first pass at an attempt to precisely specify how
ayg@5901 1167 exactly to transform elements using the provided matrices. It might not
ayg@5901 1168 be ideal, and implementer feedback is encouraged. See <a
ayg@5901 1169 href="https://www.w3.org/Bugs/Public/show_bug.cgi?id=15605">bug
bert@6706 1170 15605</a>.
ayg@5901 1171 </div>
ayg@5901 1172
dschulze@6300 1173 <p> The <a class=term
dschulze@6300 1174 href="#accumulated-3d-transformation-matrix">accumulated 3D transformation
dschulze@6300 1175 matrix</a> is a 4×4 matrix, while the objects to be transformed are
dschulze@6300 1176 two-dimensional boxes. To transform each corner (<var>a</var>,
dschulze@6300 1177 <var>b</var>) of a box, the matrix must first be applied to (<var>a</var>,
dschulze@6300 1178 <var>b</var>, 0, 1), which will result in a four-dimensional point
dschulze@6300 1179 (<var>x</var>, <var>y</var>, <var>z</var>, <var>w</var>). This is
dschulze@6300 1180 transformed back to a three-dimensional point (<var>x</var>′,
dschulze@6300 1181 <var>y</var>′, <var>z</var>′) as follows:
ayg@5901 1182
ayg@5901 1183 <p> If <var>w</var> &gt; 0, (<var>x</var>′, <var>y</var>′,
ayg@5901 1184 <var>z</var>′) = (<var>x</var>/<var>w</var>, <var>y</var>/<var>w</var>,
ayg@5901 1185 <var>z</var>/<var>w</var>).
ayg@5901 1186
ayg@5901 1187 <p> If <var>w</var> = 0, (<var>x</var>′, <var>y</var>′,
ayg@5901 1188 <var>z</var>′) = (<var>x</var> ⋅ <var>n</var>, <var>y</var> ⋅
ayg@5901 1189 <var>n</var>, <var>z</var> ⋅ <var>n</var>). <var>n</var> is an
ayg@5901 1190 implementation-dependent value that should be chosen so that
ayg@5901 1191 <var>x</var>′ or <var>y</var>′ is much larger than the viewport size,
ayg@5901 1192 if possible. For example, (5px, 22px, 0px, 0) might become (5000px,
ayg@5901 1193 22000px, 0px), with <var>n</var> = 1000, but this value of <var>n</var>
ayg@5901 1194 would be too small for (0.1px, 0.05px, 0px, 0). This specification does
ayg@5901 1195 not define the value of <var>n</var> exactly. Conceptually,
ayg@5901 1196 (<var>x</var>′, <var>y</var>′, <var>z</var>′) is <a
ayg@5901 1197 href="http://en.wikipedia.org/wiki/Plane_at_infinity">infinitely far</a>
ayg@5901 1198 in the direction (<var>x</var>, <var>y</var>, <var>z</var>).
ayg@5901 1199
ayg@5901 1200 <p> If <var>w</var> &lt; 0 for all four corners of the transformed box, the
ayg@5901 1201 box is not rendered.
ayg@5901 1202
ayg@5901 1203 <p> If <var>w</var> &lt; 0 for one to three corners of the transformed box,
ayg@5901 1204 the box must be replaced by a polygon that has any parts with <var>w</var>
ayg@5901 1205 &lt; 0 cut out. This will in general be a polygon with three to five
ayg@5901 1206 vertices, of which exactly two will have <var>w</var> = 0 and the rest
ayg@5901 1207 <var>w</var> &gt; 0. These vertices are then transformed to
ayg@5901 1208 three-dimensional points using the rules just stated. Conceptually, a
ayg@5901 1209 point with <var>w</var> &lt; 0 is "behind" the viewer, so should not be
ayg@5901 1210 visible.
ayg@5901 1211
ayg@5901 1212 <div class=example>
ayg@5901 1213 <pre>&lt;style&gt;
ayg@5901 1214 .transformed {
ayg@5901 1215 height: 100px;
ayg@5901 1216 width: 100px;
ayg@5901 1217 background: lime;
ayg@5901 1218 transform: perspective(50px) translateZ(100px);
ayg@5901 1219 }
ayg@5901 1220 &lt;/style&gt;</pre>
ayg@5901 1221
ayg@5901 1222 <p> All of the box's corners have <var>z</var>-coordinates greater than
ayg@5901 1223 the perspective. This means that the box is behind the viewer and will
ayg@5901 1224 not display. Mathematically, the point (<var>x</var>, <var>y</var>) first
ayg@5901 1225 becomes (<var>x</var>, <var>y</var>, 0, 1), then is translated to
ayg@5901 1226 (<var>x</var>, <var>y</var>, 100, 1), and then applying the perspective
ayg@5901 1227 results in (<var>x</var>, <var>y</var>, 100, −1). The
ayg@5901 1228 <var>w</var>-coordinate is negative, so it does not display. An
ayg@5901 1229 implementation that doesn't handle the <var>w</var> &lt; 0 case
ayg@5901 1230 separately might incorrectly display this point as (−<var>x</var>,
bert@6706 1231 −<var>y</var>, −100), dividing by −1 and mirroring the box.
ayg@5901 1232 </div>
ayg@5901 1233
ayg@5901 1234 <div class=example>
ayg@5901 1235 <pre>&lt;style&gt;
ayg@5901 1236 .transformed {
ayg@5901 1237 height: 100px;
ayg@5901 1238 width: 100px;
ayg@5901 1239 background: radial-gradient(yellow, blue);
ayg@5901 1240 transform: perspective(50px) translateZ(50px);
ayg@5901 1241 }
ayg@5901 1242 &lt;/style&gt;</pre>
ayg@5901 1243
ayg@5901 1244 <p> Here, the box is translated upward so that it sits at the same place
ayg@5901 1245 the viewer is looking from. This is like bringing the box closer and
ayg@5901 1246 closer to one's eye until it fills the entire field of vision. Since the
ayg@5901 1247 default transform-origin is at the center of the box, which is yellow,
bert@6706 1248 the screen will be filled with yellow.
ayg@5901 1249
ayg@5901 1250 <p> Mathematically, the point (<var>x</var>, <var>y</var>) first becomes
ayg@5901 1251 (<var>x</var>, <var>y</var>, 0, 1), then is translated to (<var>x</var>,
ayg@5901 1252 <var>y</var>, 50, 1), then becomes (<var>x</var>, <var>y</var>, 50, 0)
ayg@5901 1253 after applying perspective. Relative to the transform-origin at the
ayg@5901 1254 center, the upper-left corner was (−50, −50), so it becomes (−50,
ayg@5901 1255 −50, 50, 0). This is transformed to something very far to the upper
ayg@5901 1256 left, such as (−5000, −5000, 5000). Likewise the other corners are
ayg@5901 1257 sent very far away. The radial gradient is stretched over the whole box,
ayg@5901 1258 now enormous, so the part that's visible without scrolling should be the
ayg@5901 1259 color of the middle pixel: yellow. However, since the box is not actually
dschulze@6893 1260 infinite, the user can still scroll to the edges to see the blue parts.
dschulze@6893 1261 </div>
ayg@5901 1262
ayg@5901 1263 <div class=example>
ayg@5901 1264 <pre>&lt;style&gt;
ayg@5901 1265 .transformed {
ayg@5901 1266 height: 50px;
ayg@5901 1267 width: 50px;
ayg@5901 1268 background: lime;
ayg@5901 1269 border: 25px solid blue;
ayg@5901 1270 transform-origin: left;
ayg@5901 1271 transform: perspective(50px) rotateY(-45deg);
ayg@5901 1272 }
ayg@5901 1273 &lt;/style&gt;</pre>
ayg@5901 1274
ayg@5901 1275 <p> The box will be rotated toward the viewer, with the left edge staying
ayg@5901 1276 fixed while the right edge swings closer. The right edge will be at about
ayg@5901 1277 <var>z</var> = 70.7px, which is closer than the perspective of 50px.
ayg@5901 1278 Therefore, the rightmost edge will vanish ("behind" the viewer), and the
bert@6706 1279 visible part will stretch out infinitely far to the right.
ayg@5901 1280
ayg@5901 1281 <p> Mathematically, the top right vertex of the box was originally (100,
ayg@5901 1282 −50), relative to the transform-origin. It is first expanded to (100,
ayg@5901 1283 −50, 0, 1). After applying the transform specified, this will get
ayg@5901 1284 mapped to about (70.71, −50, 70.71, −0.4142). This has <var>w</var> =
ayg@5901 1285 −0.4142 &lt; 0, so we need to slice away the part of the box with
ayg@5901 1286 <var>w</var> &lt; 0. This results in the new top-right vertex being (50,
ayg@5901 1287 −50, 50, 0). This is then mapped to some faraway point in the same
ayg@5901 1288 direction, such as (5000, −5000, 5000), which is up and to the right
ayg@5901 1289 from the transform-origin. Something similar is done to the lower right
ayg@5901 1290 corner, which gets mapped far down and to the right. The resulting box
bert@6706 1291 stretches far past the edge of the screen.
ayg@5901 1292
ayg@5901 1293 <p> Again, the rendered box is still finite, so the user can scroll to see
ayg@5901 1294 the whole thing if he or she chooses. However, the right part has been
ayg@5901 1295 chopped off. No matter how far the user scrolls, the rightmost 30px or so
ayg@5901 1296 of the original box will not be visible. The blue border was only 25px
ayg@5901 1297 wide, so it will be visible on the left, top, and bottom, but not the
bert@6706 1298 right.
ayg@5901 1299
ayg@5901 1300 <p> The same basic procedure would apply if one or three vertices had
ayg@5901 1301 <var>w</var> &lt; 0. However, in that case the result of truncating the
ayg@5901 1302 <var>w</var> &lt; 0 part would be a triangle or pentagon instead of a
bert@6706 1303 quadrilateral.
ayg@5901 1304 </div>
simon@5276 1305 <!-- ======================================================================================================= -->
simon@5276 1306
dschulze@5892 1307 <h2 id=transform-property><span class=secno>7. </span> The ‘<a
dschulze@6300 1308 href="#effects"><code class=property>transform</code></a>’ Property</h2>
simon@5276 1309
simon@5276 1310 <p> A transformation is applied to the coordinate system an element renders
dschulze@6300 1311 in through the ‘<a href="#effects"><code
dschulze@6300 1312 class=property>transform</code></a>’ property. This property contains a
dschulze@6300 1313 list of <a href="#transform-functions">transform functions</a>. The final
dschulze@6300 1314 transformation value for a coordinate system is obtained by converting
dschulze@6300 1315 each function in the list to its corresponding matrix like defined in <a
dschulze@6300 1316 href="#mathematical-description">Mathematical Description of Transform
dschulze@6300 1317 Functions</a>, then multiplying the matrices.
simon@5276 1318
simon@5276 1319 <table class=propdef>
simon@5276 1320 <tbody>
simon@5276 1321 <tr>
simon@5276 1322 <td> <em>Name:</em>
simon@5276 1323
simon@5276 1324 <td> <dfn id=effects>transform</dfn>
simon@5276 1325
simon@5276 1326 <tr>
simon@5276 1327 <td> <em>Value:</em>
simon@5276 1328
simon@5276 1329 <td> none | &lt;transform-function&gt; [ &lt;transform-function&gt; ]*
simon@5276 1330
simon@5276 1331 <tr>
simon@5276 1332 <td> <em>Initial:</em>
simon@5276 1333
simon@5276 1334 <td> none
simon@5276 1335
simon@5276 1336 <tr>
dbaron@7338 1337 <td> <em>Applies to:</em>
simon@5276 1338
simon@5276 1339 <td> <a href="#TermTransformableElement">transformable elements</a>
simon@5276 1340
simon@5276 1341 <tr>
simon@5276 1342 <td> <em>Inherited:</em>
simon@5276 1343
simon@5276 1344 <td> no
simon@5276 1345
simon@5276 1346 <tr>
simon@5276 1347 <td> <em>Percentages:</em>
simon@5276 1348
dschulze@7030 1349 <td> refer to the size of <a href="#bounding-box"><var>bounding
dschulze@7030 1350 box</var></a>
simon@5276 1351
simon@5276 1352 <tr>
simon@5276 1353 <td> <em>Media:</em>
simon@5276 1354
simon@5276 1355 <td> visual
simon@5276 1356
simon@5276 1357 <tr>
simon@5276 1358 <td> <em>Computed value:</em>
simon@5276 1359
simon@5276 1360 <td> As specified, but with relative lengths converted into absolute
simon@5276 1361 lengths.
dbaron@7349 1362
dbaron@7349 1363 <tr>
dbaron@7349 1364 <td> <em>Animatable:</em>
dbaron@7349 1365
dbaron@7349 1366 <td> as <a href="#animation">transform</a>
simon@5276 1367 </table>
simon@5276 1368
dschulze@6300 1369 <p> Any value other than ‘<code class=css>none</code>’ for the
dschulze@6300 1370 transform results in the creation of both a stacking context and a
dschulze@6300 1371 containing block. The object acts as a containing block for fixed
dschulze@6300 1372 positioned descendants.</p>
simon@5276 1373 <!-- ======================================================================================================= -->
simon@5276 1374
dschulze@5892 1375 <h2 id=transform-origin-property><span class=secno>8. </span> The ‘<a
dschulze@6300 1376 href="#transform-origin"><code
dschulze@6300 1377 class=property>transform-origin</code></a>’ Property</h2>
dschulze@5642 1378
dschulze@5642 1379 <table class=propdef>
dschulze@5642 1380 <tbody>
dschulze@5642 1381 <tr>
dschulze@5642 1382 <td> <em>Name:</em>
dschulze@5642 1383
dschulze@5642 1384 <td> <dfn id=transform-origin>transform-origin</dfn>
dschulze@5642 1385
dschulze@5642 1386 <tr>
dschulze@5642 1387 <td> <em>Value:</em>
dschulze@5642 1388
dschulze@5642 1389 <td> [ &lt;percentage> | &lt;length> | left | center | right | top |
dschulze@5642 1390 bottom]<br>
dschulze@5642 1391 |<br>
dschulze@5642 1392 [<br>
dschulze@5892 1393   [ &lt;percentage> | &lt;length&gt; | left | center | right ]<br>
dschulze@5892 1394   &amp;&amp;<br>
dschulze@5892 1395   [ &lt;percentage> | &lt;length&gt; | top | center | bottom ]<br>
dschulze@5642 1396 ] &lt;length&gt;?<br>
dschulze@5642 1397
dschulze@5642 1398 <tr>
dschulze@5642 1399 <td> <em>Initial:</em>
dschulze@5642 1400
dschulze@5740 1401 <td> 50% 50%
dschulze@5642 1402
dschulze@5642 1403 <tr>
dbaron@7338 1404 <td> <em>Applies to:</em>
dschulze@5642 1405
dschulze@5642 1406 <td> <a href="#TermTransformableElement">transformable elements</a>
dschulze@5642 1407
dschulze@5642 1408 <tr>
dschulze@5642 1409 <td> <em>Inherited:</em>
dschulze@5642 1410
dschulze@5642 1411 <td> no
dschulze@5642 1412
dschulze@5642 1413 <tr>
dschulze@5642 1414 <td> <em>Percentages:</em>
dschulze@5642 1415
dschulze@7030 1416 <td> refer to the size of <a href="#bounding-box"><var>bounding
dschulze@7030 1417 box</var></a>
dschulze@5642 1418
dschulze@5642 1419 <tr>
dschulze@5642 1420 <td> <em>Media:</em>
dschulze@5642 1421
dschulze@5642 1422 <td> visual
dschulze@5642 1423
dschulze@5642 1424 <tr>
dschulze@5642 1425 <td> <em>Computed value:</em>
dschulze@5642 1426
dschulze@5642 1427 <td> For &lt;length&gt; the absolute value, otherwise a percentage
dbaron@7349 1428
dbaron@7349 1429 <tr>
dbaron@7349 1430 <td> <em>Animatable:</em>
dbaron@7349 1431
dbaron@7349 1432 <td> as <a
dbaron@7349 1433 href="http://dev.w3.org/csswg/css3-transitions/#animtype-simple-list">simple
dbaron@7349 1434 list</a> of <a
dbaron@7349 1435 href="http://dev.w3.org/csswg/css3-transitions/#animtype-lpcalc">length,
dbaron@7349 1436 percentage, or calc</a>
dschulze@5642 1437 </table>
dschulze@5642 1438
dschulze@5740 1439 <p> The default value for SVG elements without associated CSS layout box is
dschulze@5892 1440 ‘<code class=css>0 0</code>’.
dschulze@5892 1441
dschulze@5892 1442 <p> The values of the ‘<a href="#effects"><code
dschulze@5892 1443 class=property>transform</code></a>’ and ‘<a
dschulze@5658 1444 href="#transform-origin"><code
dschulze@5892 1445 class=property>transform-origin</code></a>’ properties are used to
dschulze@6300 1446 compute the <a class=term href="#transformation-matrix">transformation
dschulze@6300 1447 matrix</a>, as described above.
dschulze@5642 1448
dschulze@5658 1449 <p> If only one value is specified, the second value is assumed to be
dschulze@5892 1450 ‘<code class=css>center</code>’. If one or two values are specified,
dschulze@5892 1451 the third value is assumed to be ‘<code class=css>0px</code>’.
dschulze@5658 1452
dschulze@5658 1453 <p> If two or more values are defined and either no value is a keyword, or
dschulze@5892 1454 the only used keyword is ‘<code class=css>center</code>’, then the
dschulze@5892 1455 first value represents the horizontal position (or offset) and the second
dschulze@5892 1456 represents the vertical position (or offset). A third value always
dschulze@5740 1457 represents the Z position (or offset) and must be of type
dschulze@5740 1458 <var>&lt;length&gt;</var>.
dschulze@5740 1459
dschulze@7030 1460 <dl>
dschulze@7030 1461 <dt><var>&lt;percentage&gt;</var>
dschulze@7030 1462
dschulze@7030 1463 <dd>
dschulze@7030 1464 <p>A percentage for the horizontal offset is relative to the width of the
dschulze@7030 1465 <a href="#bounding-box"><var>bounding box</var></a>. A percentage for
dschulze@7030 1466 the vertical offset is relative to height of the <a
dschulze@7030 1467 href="#bounding-box"><var>bounding box</var></a>. The value for the
dschulze@7030 1468 horizontal and vertical offset represent an offset from the top left
dschulze@7030 1469 corner of the <a href="#bounding-box"><var>bounding box</var></a>.
dschulze@7030 1470
dschulze@7030 1471 <dt><var>&lt;length&gt;</var>
dschulze@7030 1472
dschulze@7030 1473 <dd>
dschulze@7030 1474 <p>A length value gives a fixed length as the offset. The value for the
dschulze@7030 1475 horizontal and vertical offset represent an offset from the top left
dschulze@7030 1476 corner of the <a href="#bounding-box"><var>bounding box</var></a>.
dschulze@7030 1477
dschulze@7030 1478 <p>For SVG elements without an associated CSS layout box the horizontal
dschulze@7030 1479 and vertical offset represent an offset from the point of origin of the
dschulze@7030 1480 element's local coordinate space.
dschulze@7030 1481
dschulze@7030 1482 <dt><dfn id=top title="''top''!!'transform-origin' value">‘<code
dschulze@7030 1483 class=css>top</code>’</dfn>
dschulze@7030 1484
dschulze@7030 1485 <dd>Computes to ‘<code class=css>0%</code>’ for the vertical position.
dschulze@7030 1486
dschulze@7030 1487 <dt><dfn id=right title="''right''!!'transform-origin' value">‘<code
dschulze@7030 1488 class=css>right</code>’</dfn>
dschulze@7030 1489
dschulze@7030 1490 <dd>Computes to ‘<code class=css>100%</code>’ for the horizontal
dschulze@7030 1491 position.
dschulze@7030 1492
dschulze@7030 1493 <dt><dfn id=bottom title="''bottom''!!'transform-origin' value">‘<code
dschulze@7030 1494 class=css>bottom</code>’</dfn>
dschulze@7030 1495
dschulze@7030 1496 <dd>Computes to ‘<code class=css>100%</code>’ for the vertical
dschulze@7030 1497 position.
dschulze@7030 1498
dschulze@7030 1499 <dt><dfn id=left title="''left''!!'transform-origin' value">‘<code
dschulze@7030 1500 class=css>left</code>’</dfn>
dschulze@7030 1501
dschulze@7030 1502 <dd>Computes to ‘<code class=css>0%</code>’ for the horizontal
dschulze@7030 1503 position.
dschulze@7030 1504
dschulze@7030 1505 <dt><dfn id=center title="''center''!!'transform-origin' value">‘<code
dschulze@7030 1506 class=css>center</code>’</dfn>
dschulze@7030 1507
dschulze@7030 1508 <dd>Computes to ‘<code class=css>50%</code>’ (‘<code class=css>left
dschulze@7030 1509 50%</code>’) for the horizontal position if the horizontal position is
dschulze@7030 1510 not otherwise specified, or ‘<code class=css>50%</code>’ (‘<code
dschulze@7030 1511 class=css>top 50%</code>’) for the vertical position if it is.
dschulze@7030 1512 </dl>
dschulze@5642 1513
dschulze@5642 1514 <p> The <a href="http://www.w3.org/TR/cssom/#resolved-value">resolved
dschulze@6300 1515 value</a> of ‘<a href="#transform-origin"><code
dschulze@6300 1516 class=property>transform-origin</code></a>’ is the <a
dschulze@5642 1517 href="http://www.w3.org/TR/CSS21/cascade.html#used-value">used value</a>
dschulze@5642 1518 (i.e., percentages are resolved to absolute lengths).</p>
dschulze@5642 1519 <!-- ======================================================================================================= -->
dschulze@5642 1520
dschulze@5892 1521 <h2 id=transform-style-property><span class=secno>9. </span> The ‘<a
dschulze@6300 1522 href="#transform-style"><code class=property>transform-style</code></a>’
dschulze@6300 1523 Property</h2>
dschulze@5642 1524
dschulze@5642 1525 <table class=propdef>
dschulze@5642 1526 <tbody>
dschulze@5642 1527 <tr>
dschulze@5642 1528 <td> <em>Name:</em>
dschulze@5642 1529
dschulze@5642 1530 <td> <dfn id=transform-style>transform-style</dfn>
dschulze@5642 1531
dschulze@5642 1532 <tr>
dschulze@5642 1533 <td> <em>Value:</em>
dschulze@5642 1534
dschulze@5642 1535 <td> flat | preserve-3d
dschulze@5642 1536
dschulze@5642 1537 <tr>
dschulze@5642 1538 <td> <em>Initial:</em>
dschulze@5642 1539
dschulze@5642 1540 <td> flat
dschulze@5642 1541
dschulze@5642 1542 <tr>
dbaron@7338 1543 <td> <em>Applies to:</em>
dschulze@5642 1544
dschulze@5642 1545 <td> <a href="#TermTransformableElement">transformable elements</a>
dschulze@5642 1546
dschulze@5642 1547 <tr>
dschulze@5642 1548 <td> <em>Inherited:</em>
dschulze@5642 1549
dschulze@5642 1550 <td> no
dschulze@5642 1551
dschulze@5642 1552 <tr>
dschulze@5642 1553 <td> <em>Percentages:</em>
dschulze@5642 1554
dschulze@5642 1555 <td> N/A
dschulze@5642 1556
dschulze@5642 1557 <tr>
dschulze@5642 1558 <td> <em>Media:</em>
dschulze@5642 1559
dschulze@5642 1560 <td> visual
dschulze@5642 1561
dschulze@5642 1562 <tr>
dschulze@5642 1563 <td> <em>Computed value:</em>
dschulze@5642 1564
dschulze@5642 1565 <td> Same as specified value.
dbaron@7349 1566
dbaron@7349 1567 <tr>
dbaron@7349 1568 <td> <em>Animatable:</em>
dbaron@7349 1569
dbaron@7349 1570 <td> no
dschulze@5642 1571 </table>
dschulze@5642 1572
dschulze@6300 1573 <p> A value of ‘<code class=css>preserve-3d</code>’ for ‘<a
dschulze@6300 1574 href="#transform-style"><code class=property>transform-style</code></a>’
dschulze@6300 1575 establishes a stacking context.
dschulze@5642 1576
dschulze@5642 1577 <p> The following CSS property values require the user agent to create a
dschulze@5642 1578 flattened representation of the descendant elements before they can be
dschulze@6300 1579 applied, and therefore override the behavior of ‘<code
dschulze@6300 1580 class=css>transform-style: preserve-3d</code>’:
dschulze@5642 1581
dschulze@5642 1582 <ul>
dschulze@6300 1583 <li>‘<code class=property>overflow</code>’: any value other than
dschulze@6300 1584 ‘<code class=css>visible</code>’.
dschulze@6300 1585
dschulze@6300 1586 <li>‘<code class=property>opacity</code>’: any value other than
dschulze@6300 1587 ‘<code class=css>1</code>’.
dschulze@6300 1588
dschulze@6300 1589 <li>‘<code class=property>filter</code>’: any value other than
dschulze@6893 1590 ‘<code class=css>none</code>’.
dschulze@5642 1591 </ul>
dschulze@5642 1592
dschulze@6904 1593 <p> The computed value of ‘<a href="#transform-style"><code
dschulze@6904 1594 class=property>transform-style</code></a>’ is not affected.
dschulze@5642 1595
dschulze@6300 1596 <p> The values of the ‘<a href="#effects"><code
dschulze@6300 1597 class=property>transform</code></a>’ and ‘<a
dschulze@6300 1598 href="#transform-origin"><code
dschulze@6300 1599 class=property>transform-origin</code></a>’ properties are used to
dschulze@6300 1600 compute the <a class=term href="#transformation-matrix">transformation
dschulze@6300 1601 matrix</a>, as described above.</p>
dschulze@5642 1602 <!-- ======================================================================================================= -->
dschulze@5642 1603
dschulze@5892 1604 <h2 id=perspective-property><span class=secno>10. </span> The ‘<a
dschulze@6300 1605 href="#perspective"><code class=property>perspective</code></a>’
dschulze@6300 1606 Property</h2>
dschulze@5642 1607
dschulze@5642 1608 <table class=propdef>
dschulze@5642 1609 <tbody>
dschulze@5642 1610 <tr>
dschulze@5642 1611 <td> <em>Name:</em>
dschulze@5642 1612
dschulze@5642 1613 <td> <dfn id=perspective>perspective</dfn>
dschulze@5642 1614
dschulze@5642 1615 <tr>
dschulze@5642 1616 <td> <em>Value:</em>
dschulze@5642 1617
dschulze@5642 1618 <td> none | &lt;length&gt;
dschulze@5642 1619
dschulze@5642 1620 <tr>
dschulze@5642 1621 <td> <em>Initial:</em>
dschulze@5642 1622
dschulze@5642 1623 <td> none
dschulze@5642 1624
dschulze@5642 1625 <tr>
dbaron@7338 1626 <td> <em>Applies to:</em>
dschulze@5642 1627
dschulze@5642 1628 <td> <a href="#TermTransformableElement">transformable elements</a>
dschulze@5642 1629
dschulze@5642 1630 <tr>
dschulze@5642 1631 <td> <em>Inherited:</em>
dschulze@5642 1632
dschulze@5642 1633 <td> no
dschulze@5642 1634
dschulze@5642 1635 <tr>
dschulze@5642 1636 <td> <em>Percentages:</em>
dschulze@5642 1637
dschulze@5642 1638 <td> N/A
dschulze@5642 1639
dschulze@5642 1640 <tr>
dschulze@5642 1641 <td> <em>Media:</em>
dschulze@5642 1642
dschulze@5642 1643 <td> visual
dschulze@5642 1644
dschulze@5642 1645 <tr>
dschulze@5642 1646 <td> <em>Computed value:</em>
dschulze@5642 1647
dschulze@5642 1648 <td> Absolute length or "none".
dbaron@7349 1649
dbaron@7349 1650 <tr>
dbaron@7349 1651 <td> <em>Animatable:</em>
dbaron@7349 1652
dbaron@7349 1653 <td> as <a
dbaron@7349 1654 href="http://dev.w3.org/csswg/css3-transitions/#animtype-length">length</a>
dschulze@5642 1655 </table>
dschulze@5642 1656
dschulze@6300 1657 <p> If the value is ‘<code class=css>none</code>’, no perspective
dschulze@6300 1658 transform is applied. Lengths must be positive.
dschulze@5642 1659
dschulze@5892 1660 <p> The use of this property with any value other than ‘<code
dschulze@6300 1661 class=css>none</code>’ establishes a stacking context. It also
dschulze@6300 1662 establishes a containing block (somewhat similar to ‘<code
dschulze@6300 1663 class=css>position: relative</code>’), just like the ‘<a
dschulze@6300 1664 href="#effects"><code class=property>transform</code></a>’ property
dschulze@6300 1665 does.
dschulze@6300 1666
dschulze@6300 1667 <p> The values of the ‘<a href="#perspective"><code
dschulze@6300 1668 class=property>perspective</code></a>’ and ‘<a
dschulze@6300 1669 href="#perspective-origin"><code
dschulze@6300 1670 class=property>perspective-origin</code></a>’ properties are used to
dschulze@6300 1671 compute the <a class=term href="#perspective-matrix">perspective
dschulze@6300 1672 matrix</a>, as described above.</p>
dschulze@5642 1673 <!-- ======================================================================================================= -->
dschulze@5642 1674
dschulze@5892 1675 <h2 id=perspective-origin-property><span class=secno>11. </span> The ‘<a
dschulze@6300 1676 href="#perspective-origin"><code
dschulze@6300 1677 class=property>perspective-origin</code></a>’ Property</h2>
dschulze@6300 1678
dschulze@6300 1679 <p> The ‘<a href="#perspective-origin"><code
dschulze@6300 1680 class=property>perspective-origin</code></a>’ property establishes the
dschulze@6300 1681 origin for the <a href="#perspective"><em>perspective</em></a> property.
dschulze@6300 1682 It effectively sets the X and Y position at which the viewer appears to be
dschulze@6300 1683 looking at the children of the element.
dschulze@5642 1684
dschulze@5642 1685 <table class=propdef>
dschulze@5642 1686 <tbody>
dschulze@5642 1687 <tr>
dschulze@5642 1688 <td> <em>Name:</em>
dschulze@5642 1689
dschulze@5642 1690 <td> <dfn id=perspective-origin>perspective-origin</dfn>
dschulze@5642 1691
dschulze@5642 1692 <tr>
dschulze@5642 1693 <td> <em>Value:</em>
dschulze@5642 1694
dschulze@5642 1695 <td> [ &lt;percentage> | &lt;length> | left | center | right | top |
dschulze@5642 1696 bottom]<br>
dschulze@5642 1697 |<br>
dschulze@5642 1698 [<br>
dschulze@5892 1699   [ &lt;percentage> | &lt;length&gt; | left | center | right ]<br>
dschulze@5892 1700   &amp;&amp;<br>
dschulze@5892 1701   [ &lt;percentage> | &lt;length&gt; | top | center | bottom ]<br>
dschulze@5642 1702 ]<br>
dschulze@5642 1703
dschulze@5642 1704 <tr>
dschulze@5642 1705 <td> <em>Initial:</em>
dschulze@5642 1706
dschulze@5642 1707 <td> 50% 50%
dschulze@5642 1708
dschulze@5642 1709 <tr>
dbaron@7338 1710 <td> <em>Applies to:</em>
dschulze@5642 1711
dschulze@5642 1712 <td> <a href="#TermTransformableElement">transformable elements</a>
dschulze@5642 1713
dschulze@5642 1714 <tr>
dschulze@5642 1715 <td> <em>Inherited:</em>
dschulze@5642 1716
dschulze@5642 1717 <td> no
dschulze@5642 1718
dschulze@5642 1719 <tr>
dschulze@5642 1720 <td> <em>Percentages:</em>
dschulze@5642 1721
dschulze@7030 1722 <td> refer to the size of the <a href="#bounding-box"><var>bounding
dschulze@7030 1723 box</var></a>
dschulze@5642 1724
dschulze@5642 1725 <tr>
dschulze@5642 1726 <td> <em>Media:</em>
dschulze@5642 1727
dschulze@5642 1728 <td> visual
dschulze@5642 1729
dschulze@5642 1730 <tr>
dschulze@5642 1731 <td> <em>Computed value:</em>
dschulze@5642 1732
dschulze@5642 1733 <td> For &lt;length&gt; the absolute value, otherwise a percentage.
dbaron@7349 1734
dbaron@7349 1735 <tr>
dbaron@7349 1736 <td> <em>Animatable:</em>
dbaron@7349 1737
dbaron@7349 1738 <td> as <a
dbaron@7349 1739 href="http://dev.w3.org/csswg/css3-transitions/#animtype-simple-list">simple
dbaron@7349 1740 list</a> of <a
dbaron@7349 1741 href="http://dev.w3.org/csswg/css3-transitions/#animtype-lpcalc">length,
dbaron@7349 1742 percentage, or calc</a>
dschulze@5642 1743 </table>
dschulze@5642 1744
dschulze@5895 1745 <p> The values of the ‘<a href="#perspective"><code
dschulze@5895 1746 class=property>perspective</code></a>’ and ‘<a
dschulze@5895 1747 href="#perspective-origin"><code
dschulze@5895 1748 class=property>perspective-origin</code></a>’ properties are used to
dschulze@6300 1749 compute the <a class=term href="#perspective-matrix">perspective
dschulze@6300 1750 matrix</a>, as described above.
dschulze@6300 1751
dschulze@6300 1752 <p> If only one value is specified, the second value is assumed to be
dschulze@6300 1753 ‘<code class=css>center</code>’.
dschulze@6300 1754
dschulze@6300 1755 <p> If at least one of the two values is not a keyword, then the first
dschulze@6300 1756 value represents the horizontal position (or offset) and the second
dschulze@6300 1757 represents the vertical position (or offset).
dschulze@6300 1758
dschulze@7030 1759 <p> The values for ‘<a href="#perspective-origin"><code
dschulze@7030 1760 class=property>perspective-origin</code></a>’ represent an offset of the
dschulze@7030 1761 perspective origin from the top left corner of the <a
dschulze@7030 1762 href="#bounding-box"><var>bounding box</var></a>.
dschulze@7030 1763
dschulze@7030 1764 <dl>
dschulze@7030 1765 <dt><var>&lt;percentage&gt;</var>
dschulze@7030 1766
dschulze@7030 1767 <dd>
dschulze@7030 1768 <p>A percentage for the horizontal perspctive offset is relative to the
dschulze@7030 1769 width of the <a href="#bounding-box"><var>bounding box</var></a>. A
dschulze@7030 1770 percentage for the vertical offset is relative to height of the <a
dschulze@7030 1771 href="#bounding-box"><var>bounding box</var></a>. The value for the
dschulze@7030 1772 horizontal and vertical offset represent an offset from the top left
dschulze@7030 1773 corner of the <a href="#bounding-box"><var>bounding box</var></a>.
dschulze@7030 1774
dschulze@7030 1775 <dt><var>&lt;length&gt;</var>
dschulze@7030 1776
dschulze@7030 1777 <dd>
dschulze@7030 1778 <p>A length value gives a fixed length as the offset. The value for the
dschulze@7030 1779 horizontal and vertical offset represent an offset from the top left
dschulze@7030 1780 corner of the <a href="#bounding-box"><var>bounding box</var></a>.
dschulze@7030 1781
dschulze@7030 1782 <dt><dfn id=top0 title="''top''!!'perspective-origin' value">‘<code
dschulze@7030 1783 class=css>top</code>’</dfn>
dschulze@7030 1784
dschulze@7030 1785 <dd>Computes to ‘<code class=css>0%</code>’ for the vertical position.
dschulze@7030 1786
dschulze@7030 1787 <dt><dfn id=right0 title="''right''!!'perspective-origin' value">‘<code
dschulze@7030 1788 class=css>right</code>’</dfn>
dschulze@7030 1789
dschulze@7030 1790 <dd>Computes to ‘<code class=css>100%</code>’ for the horizontal
dschulze@7030 1791 position.
dschulze@7030 1792
dschulze@7030 1793 <dt><dfn id=bottom0
dschulze@7030 1794 title="''bottom''!!'perspective-origin' value">‘<code
dschulze@7030 1795 class=css>bottom</code>’</dfn>
dschulze@7030 1796
dschulze@7030 1797 <dd>Computes to ‘<code class=css>100%</code>’ for the vertical
dschulze@7030 1798 position.
dschulze@7030 1799
dschulze@7030 1800 <dt><dfn id=left0 title="''left''!!'perspective-origin' value">‘<code
dschulze@7030 1801 class=css>left</code>’</dfn>
dschulze@7030 1802
dschulze@7030 1803 <dd>Computes to ‘<code class=css>0%</code>’ for the horizontal
dschulze@7030 1804 position.
dschulze@7030 1805
dschulze@7030 1806 <dt><dfn id=center0
dschulze@7030 1807 title="''center''!!'perspective-origin' value">‘<code
dschulze@7030 1808 class=css>center</code>’</dfn>
dschulze@7030 1809
dschulze@7030 1810 <dd>Computes to ‘<code class=css>50%</code>’ (‘<code class=css>left
dschulze@7030 1811 50%</code>’) for the horizontal position if the horizontal position is
dschulze@7030 1812 not otherwise specified, or ‘<code class=css>50%</code>’ (‘<code
dschulze@7030 1813 class=css>top 50%</code>’) for the vertical position if it is.
dschulze@7030 1814 </dl>
dschulze@5642 1815
dschulze@5642 1816 <p> The <a href="http://www.w3.org/TR/cssom/#resolved-value">resolved
dschulze@6300 1817 value</a> of ‘<a href="#perspective-origin"><code
dschulze@6300 1818 class=property>perspective-origin</code></a>’ is the <a
dschulze@5642 1819 href="http://www.w3.org/TR/CSS21/cascade.html#used-value">used value</a>
dschulze@5642 1820 (i.e., percentages are resolved to absolute lengths).</p>
dschulze@5642 1821 <!-- ======================================================================================================= -->
dschulze@5642 1822
dschulze@5892 1823 <h2 id=backface-visibility-property><span class=secno>12. </span> The ‘<a
dschulze@6300 1824 href="#backface-visibility"><code
dschulze@6300 1825 class=property>backface-visibility</code></a>’ Property</h2>
dschulze@6300 1826
dschulze@6300 1827 <p> The ‘<a href="#backface-visibility"><code
dschulze@6300 1828 class=property>backface-visibility</code></a>’ property determines
dschulze@6300 1829 whether or not the "back" side of a transformed element is visible when
dschulze@6300 1830 facing the viewer. With an identity transform, the front side of an
dschulze@6300 1831 element faces the viewer. Applying a rotation about Y of 180 degrees (for
dschulze@6893 1832 instance) would cause the back side of the element to face the viewer.
dschulze@6893 1833
dschulze@6893 1834 <p class=note> Note that this property is useful when you place two
dschulze@6893 1835 elements back-to-back, as you would to create a playing card. Without this
dschulze@6893 1836 property, the front and back elements could switch places at times during
dschulze@6893 1837 an animation to flip the card. Another example is creating a box out of 6
dschulze@6893 1838 elements, but where you want to see the inside faces of the box. This is
dschulze@6893 1839 useful when creating the backdrop for a 3 dimensional stage.
dschulze@5642 1840
dschulze@5642 1841 <table class=propdef>
dschulze@5642 1842 <tbody>
dschulze@5642 1843 <tr>
dschulze@5642 1844 <td> <em>Name:</em>
dschulze@5642 1845
dschulze@5642 1846 <td> <dfn id=backface-visibility>backface-visibility</dfn>
dschulze@5642 1847
dschulze@5642 1848 <tr>
dschulze@5642 1849 <td> <em>Value:</em>
dschulze@5642 1850
dschulze@5642 1851 <td> visible | hidden
dschulze@5642 1852
dschulze@5642 1853 <tr>
dschulze@5642 1854 <td> <em>Initial:</em>
dschulze@5642 1855
dschulze@5642 1856 <td> visible
dschulze@5642 1857
dschulze@5642 1858 <tr>
dbaron@7338 1859 <td> <em>Applies to:</em>
dschulze@5642 1860
dschulze@5642 1861 <td> <a href="#TermTransformableElement">transformable elements</a>
dschulze@5642 1862
dschulze@5642 1863 <tr>
dschulze@5642 1864 <td> <em>Inherited:</em>
dschulze@5642 1865
dschulze@5642 1866 <td> no
dschulze@5642 1867
dschulze@5642 1868 <tr>
dschulze@5642 1869 <td> <em>Percentages:</em>
dschulze@5642 1870
dschulze@5642 1871 <td> N/A
dschulze@5642 1872
dschulze@5642 1873 <tr>
dschulze@5642 1874 <td> <em>Media:</em>
dschulze@5642 1875
dschulze@5642 1876 <td> visual
dschulze@5642 1877
dschulze@5642 1878 <tr>
dschulze@5642 1879 <td> <em>Computed value:</em>
dschulze@5642 1880
dschulze@5642 1881 <td> Same as specified value.
dbaron@7349 1882
dbaron@7349 1883 <tr>
dbaron@7349 1884 <td> <em>Animatable:</em>
dbaron@7349 1885
dbaron@7349 1886 <td> no
dschulze@5642 1887 </table>
dschulze@5642 1888
dschulze@6300 1889 <p> The visibility of an element with ‘<code
dschulze@6300 1890 class=css>backface-visibility: hidden</code>’ is determined as follows:
dschulze@5642 1891
dschulze@5642 1892 <ol>
dschulze@5921 1893 <li> For an element in a <a class=term href="#d-rendering-context">3D
dschulze@5921 1894 rendering context</a>, compute its <a class=term
dschulze@5921 1895 href="#accumulated-3d-transformation-matrix"> accumulated 3D
dschulze@5921 1896 transformation matrix</a>. For an element not in a <a class=term
dschulze@5642 1897 href="#d-rendering-context">3D rendering context</a>, compute its <a
dschulze@5921 1898 class=term href="#transformation-matrix">transformation matrix</a>.
dschulze@5642 1899
dschulze@5642 1900 <li> If the component of the matrix in row 3, column 3 is negative, then
dschulze@5642 1901 the element should be hidden. Otherwise it is visible.
dschulze@5642 1902 </ol>
dschulze@5642 1903
dschulze@5642 1904 <p class=note> The reasoning for this definition is as follows. Assume
dschulze@5892 1905 elements are rectangles in the <var>x</var>–<var>y</var> plane with
dschulze@5642 1906 infinitesimal thickness. The front of the untransformed element has
dschulze@5892 1907 coordinates like (<var>x</var>, <var>y</var>, <var>ε</var>), and the back
dschulze@5892 1908 is (<var>x</var>, <var>y</var>, −<var>ε</var>), for some very small
dschulze@5892 1909 <var>ε</var>. We want to know if after the transformation, the front of
dschulze@5892 1910 the element is closer to the viewer than the back (higher
dschulze@5892 1911 <var>z</var>-value) or further away. The <var>z</var>-coordinate of the
dschulze@5892 1912 front will be <var>M</var><sub>13</sub><var>x</var> +
dschulze@5892 1913 <var>M</var><sub>23</sub><var>y</var> +
dschulze@5892 1914 <var>M</var><sub>33</sub><var>ε</var> + <var>M</var><sub>43</sub>, before
dschulze@5892 1915 accounting for perspective, and the back will be
dschulze@5642 1916 <var>M</var><sub>13</sub><var>x</var> +
dschulze@5892 1917 <var>M</var><sub>23</sub><var>y</var> −
dschulze@5892 1918 <var>M</var><sub>33</sub><var>ε</var> + <var>M</var><sub>43</sub>. The
dschulze@5892 1919 first quantity is greater than the second if and only if
dschulze@5642 1920 <var>M</var><sub>33</sub> > 0. (If it equals zero, the front and back are
dschulze@5642 1921 equally close to the viewer. This probably means something like a
dschulze@5642 1922 90-degree rotation, which makes the element invisible anyway, so we don't
dschulze@5642 1923 really care whether it vanishes.)</p>
dschulze@5642 1924 <!-- ======================================================================================================= -->
dschulze@5642 1925
dschulze@5892 1926 <h2 id=svg-transform><span class=secno>13. </span> The SVG ‘<a
dschulze@5892 1927 href="#effects"><code class=property>transform</code></a>’ Attribute</h2>
simon@5276 1928
simon@5276 1929 <p> The <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/">SVG 1.1
dschulze@5892 1930 specification</a> did not specify the attributes ‘<a
dschulze@5892 1931 href="#effects"><code class=property>transform</code></a>’, ‘<code
dschulze@5892 1932 class=property>gradientTransform</code>’ or ‘<code
dschulze@5892 1933 class=property>patternTransform</code>’ as <a
simon@5276 1934 href="http://www.w3.org/TR/2011/REC-SVG11-20110816/styling.html#UsingPresentationAttributes"><em>presentation
simon@5276 1935 attributes</em></a>. In order to improve the integration of SVG and HTML,
dschulze@5892 1936 this specification makes these SVG attributes ‘<code
dschulze@5892 1937 class=css>presentation attributes</code>’ and makes the ‘<a
dschulze@5892 1938 href="#effects"><code class=property>transform</code></a>’ property one
dschulze@5892 1939 that applies to <a class=term href="#transformable-element">transformable
dschulze@5892 1940 elements</a> in the SVG namespace.
simon@5276 1941
simon@5276 1942 <p> This specification will also introduce the new presentation attributes
dschulze@5892 1943 ‘<a href="#transform-origin"><code
dschulze@5892 1944 class=property>transform-origin</code></a>’, ‘<a
dschulze@5892 1945 href="#perspective"><code class=property>perspective</code></a>’, ‘<a
dschulze@5892 1946 href="#perspective-origin"><code
dschulze@5892 1947 class=property>perspective-origin</code></a>’, ‘<a
dschulze@5892 1948 href="#transform-style"><code class=property>transform-style</code></a>’
dschulze@5892 1949 and ‘<a href="#backface-visibility"><code
dschulze@5892 1950 class=property>backface-visibility</code></a>’.
dschulze@5627 1951
dschulze@5627 1952 <p> Values on new introduced presentation attributes get parsed following
dschulze@5923 1953 the syntax rules on <a href="#svg-data-types">SVG Data Types</a> <a
dschulze@5923 1954 href="#SVG11" rel=biblioentry>[SVG11]<!--{{SVG11}}--></a>.
simon@5276 1955
dschulze@5751 1956 <h3 id=transform-attribute-specificity><span class=secno>13.1. </span> SVG
dschulze@5892 1957 ‘<a href="#effects"><code class=property>transform</code></a>’
dschulze@5751 1958 attribute specificity</h3>
dschulze@5751 1959
dschulze@5751 1960 <p> Since the previously named SVG attributes become presentation
simon@5276 1961 attributes, their participation in the CSS cascade is determined by the
simon@5276 1962 specificity of presentation attributes, as <a
simon@5276 1963 href="http://www.w3.org/TR/2011/REC-SVG11-20110816/styling.html#UsingPresentationAttributes">explained</a>
simon@5276 1964 in the SVG specification.
simon@5276 1965
simon@5276 1966 <div class=example>
dschulze@5892 1967 <p> This example shows the combination of the ‘<a href="#effects"><code
dschulze@5892 1968 class=property>transform</code></a>’ style property and the ‘<a
dschulze@5892 1969 href="#effects"><code class=property>transform</code></a>’ presentation
bert@6706 1970 attribute.
simon@5276 1971
simon@5276 1972 <pre>&lt;svg xmlns="http://www.w3.org/2000/svg"&gt;
simon@5276 1973 &lt;style&gt;
simon@5276 1974 .container {
simon@5276 1975 transform: translate(100px, 100px);
simon@5276 1976 }
simon@5276 1977 &lt;/style&gt;
simon@5276 1978
simon@5276 1979 &lt;g class="container" transform="translate(200 200)"&gt;
simon@5276 1980 &lt;rect width="100" height="100" fill="blue" /&gt;
simon@5276 1981 &lt;/g&gt;
simon@5276 1982 &lt;/svg&gt;</pre>
simon@5276 1983
dschulze@5626 1984 <div class=figure> <img alt="Translated SVG container element." height=240
dschulze@5626 1985 src="examples/svg-translate1.svg" width=470></div>
simon@5276 1986
dschulze@5892 1987 <p> Because of the participation to the CSS cascade, the ‘<a
dschulze@5892 1988 href="#effects"><code class=property>transform</code></a>’ style
dschulze@5892 1989 property overrides the ‘<a href="#effects"><code
dschulze@5892 1990 class=property>transform</code></a>’ presentation attribute. Therefore
dschulze@5892 1991 the container gets translated by ‘<code class=css>100px</code>’ in
dschulze@5892 1992 both the horizontal and the vertical directions, instead of ‘<code
bert@6706 1993 class=css>200px</code>’.
simon@5276 1994 </div>
simon@5276 1995
dschulze@5892 1996 <h3 id=svg-syntax><span class=secno>13.2. </span> Syntax of the SVG ‘<a
dschulze@5892 1997 href="#effects"><code class=property>transform</code></a>’ attribute</h3>
dschulze@5892 1998
dschulze@5892 1999 <p> To provide backwards compatibility, the syntax of the ‘<a
dschulze@5892 2000 href="#effects"><code class=property>transform</code></a>’ presentation
dschulze@5892 2001 attribute differs from the syntax of the ‘<a href="#effects"><code
dschulze@5892 2002 class=property>transform</code></a>’ style property as shown in the
dschulze@5892 2003 example above. However, the syntax used for the ‘<a
dschulze@5892 2004 href="#effects"><code class=property>transform</code></a>’ style
dschulze@5892 2005 property can be used for a ‘<a href="#effects"><code
dschulze@5892 2006 class=property>transform</code></a>’ presentation attribute value.
dschulze@5751 2007 Authors are advised to follow the rules of <a
simon@5276 2008 href="http://www.w3.org/TR/css3-values/#functional-notation">CSS Values
dschulze@5892 2009 and Units Module</a>. Therefore an author should write ‘<code
dschulze@5892 2010 class=css>transform="translate(200px, 200px)"</code>’ instead of
dschulze@5892 2011 ‘<code class=css>transform="translate (200 200)"</code>’ because the
dschulze@5892 2012 second example with the spaces before the ‘<code class=css>(</code>’,
dschulze@5892 2013 the missing comma between the arguments and the values without the
dschulze@5892 2014 explicit unit notation would be valid for the attribute only.
dschulze@5751 2015
dschulze@5751 2016 <h4 id=svg-transform-list><span class=secno>13.2.1. </span> Transform List</h4>
simon@5276 2017
dschulze@5892 2018 <p> The value for the ‘<a href="#effects"><code
dschulze@5892 2019 class=property>transform</code></a>’ attribute consists of a transform
dschulze@5892 2020 list with zero or more transform functions using <a
simon@5276 2021 href="#svg-functional-notation">functional notation</a>. If the transform
simon@5276 2022 list consists of more than one transform function, these functions are
dschulze@5892 2023 separated by optional whitespace, an optional comma (‘<code
dschulze@5892 2024 class=css>,</code>’) and optional whitespace. The transform list can
simon@5276 2025 have optional whitespace characters before and after the list.
simon@5276 2026
dschulze@5751 2027 <h4 id=svg-functional-notation><span class=secno>13.2.2. </span> Functional
simon@5276 2028 Notation</h4>
simon@5276 2029
simon@5276 2030 <p> The syntax starts with the name of the function followed by optional
simon@5276 2031 whitespace characters followed by a left parenthesis followed by optional
simon@5276 2032 whitespace followed by the argument(s) to the notation followed by
simon@5276 2033 optional whitespace followed by a right parenthesis. If a function takes
simon@5276 2034 more than one argument, the arguments are either separated by a comma
dschulze@5892 2035 (‘<code class=css>,</code>’) with optional whitespace characters
dschulze@5892 2036 before and after the comma, or by one or more whitespace characters.
dschulze@5751 2037
dschulze@5751 2038 <h4 id=svg-data-types><span class=secno>13.2.3. </span> SVG Data Types</h4>
simon@5276 2039
dschulze@5627 2040 <p> Arguments on all new introduced presentation attributes consist of data
dschulze@5627 2041 types in the sense of <a
dschulze@5627 2042 href="http://www.w3.org/TR/css3-values/#functional-notation">CSS Values
simon@5276 2043 and Units Module</a>. The definitions of data types in CSS Values and
simon@5276 2044 Units Module are enhanced as follows:
simon@5276 2045
dschulze@5751 2046 <h5 id=svg-transform-value><span class=secno>13.2.3.1. </span> The
simon@5276 2047 <var>&lt;translation-value&gt;</var> and <var>&lt;length&gt;</var> type</h5>
simon@5276 2048
simon@5276 2049 <p> A translation-value or length can be a <var>&lt;number&gt;</var>
simon@5276 2050 without an unit identifier. In this case the <a
simon@5276 2051 href="#svg-number"><var>number</var></a> gets interpreted as "user unit".
simon@5276 2052 A user unit in the the <a
simon@5276 2053 href="http://www.w3.org/TR/2003/REC-SVG11-20030114/coords.html#InitialCoordinateSystem">initial
simon@5276 2054 coordinate system</a> is equivalent to the parent environment's notion of
simon@5276 2055 a pixel unit.
simon@5276 2056
dschulze@5751 2057 <h5 id=svg-angle><span class=secno>13.2.3.2. </span> The
simon@5276 2058 <var>&lt;angle&gt;</var> type</h5>
simon@5276 2059
simon@5276 2060 <p> An angle can be a <var>&lt;number&gt;</var> without an unit identifier.
simon@5276 2061 In this case the <a href="#svg-number"><i>number</i></a> gets interpreted
simon@5276 2062 as a value in degrees.
simon@5276 2063
dschulze@5751 2064 <h5 id=svg-number><span class=secno>13.2.3.3. </span> The
simon@5276 2065 <var>&lt;number&gt;</var> type</h5>
simon@5276 2066
simon@5276 2067 <p> SVG supports scientific notations for numbers. Therefore a
simon@5276 2068 <var>number</var> gets parsed like described in SVG <a
simon@5276 2069 href="http://www.w3.org/TR/SVG/types.html#DataTypeNumber">Basic data
simon@5276 2070 types</a> for SVG attributes.
simon@5276 2071
dschulze@5726 2072 <h3 id=svg-gradient-transform-pattern-transform><span class=secno>13.3.
dschulze@5892 2073 </span> The SVG ‘<code class=property>gradientTransform</code>’ and
dschulze@5892 2074 ‘<code class=property>patternTransform</code>’ attributes</h3>
dschulze@5892 2075
dschulze@5892 2076 <p> SVG specifies the attributes ‘<code
dschulze@5892 2077 class=property>gradientTransform</code>’ and ‘<code
dschulze@5892 2078 class=property>patternTransform</code>’. This specification makes both
dschulze@5892 2079 attributes presentation attributes. Both attributes use the same <a
dschulze@5892 2080 href="#svg-syntax">syntax</a> as the SVG ‘<a href="#effects"><code
dschulze@5892 2081 class=property>transform</code></a>’ attribute. This specification does
dschulze@5892 2082 not introduce corresponding CSS style properties. Both, the ‘<code
dschulze@5892 2083 class=property>gradientTransform</code>’ and the ‘<code
dschulze@5892 2084 class=property>patternTransform</code>’ attribute, are presentation
dschulze@5892 2085 attributes for the ‘<a href="#effects"><code
dschulze@5892 2086 class=property>transform</code></a>’ property.
simon@5276 2087
dschulze@5726 2088 <h3 id=svg-transform-functions><span class=secno>13.4. </span> SVG
dschulze@5658 2089 transform functions</h3>
simon@5276 2090
simon@5276 2091 <p> For backwards compatibility with existing SVG content, this
simon@5276 2092 specification supports all transform functions defined by <a
simon@5276 2093 href="http://www.w3.org/TR/SVG/coords.html#TransformAttribute">The
dschulze@6300 2094 ‘<code class=property>transform</code>’ attribute</a> in <a
dschulze@6300 2095 href="#SVG11" rel=biblioentry>[SVG11]<!--{{SVG11}}--></a>. Therefore the
dschulze@6300 2096 two-dimensional transform function ‘<code
dschulze@6300 2097 class=css>rotate(&lt;angle&gt;)</code>’ is extended as follows:
simon@5276 2098
simon@5276 2099 <dl>
dschulze@5743 2100 <dt id=rotate-three-function> <code class=css>rotate(&lt;angle&gt;[,
dschulze@5743 2101 &lt;translation-value&gt;, &lt;translation-value&gt;])</code>
simon@5276 2102
simon@5276 2103 <dd> specifies a <a href="#RotateDefined">2D rotation</a> by the angle
simon@5276 2104 specified in the parameter about the origin of the element, as defined by
dschulze@5892 2105 the ‘<a href="#transform-origin"><code
dschulze@5892 2106 class=property>transform-origin</code></a>’ property. If the optional
dschulze@5892 2107 translation values are specified, the transform origin is translated by
dschulze@5892 2108 that amount (using the current transformation matrix) for the duration of
dschulze@5921 2109 the rotate operation. For example ‘<code class=css>rotate(90deg, 100px,
dschulze@5921 2110 100px)</code>’ would cause elements to appear rotated one-quarter of a
dschulze@6299 2111 turn in the clockwise direction after a translation of the
dschulze@6299 2112 transform-origin of 100 pixel in the horizontal and vertical directions.
simon@5276 2113 </dl>
simon@5276 2114
simon@5276 2115 <p> User agents are just required to support the two optional arguments for
simon@5276 2116 translation on elements in the SVG namespace.
simon@5276 2117
dschulze@5726 2118 <h3 id=svg-three-dimensional-functions><span class=secno>13.5. </span>SVG
simon@5276 2119 and 3D transform functions</h3>
simon@5276 2120
simon@5276 2121 <p> This specification explicitly requires three-dimensional transform
simon@5276 2122 functions to apply to the <a
simon@5276 2123 href="http://www.w3.org/TR/SVG/intro.html#TermContainerElement"><em>container
dschulze@5892 2124 elements</em></a>: ‘<code class=property>a</code>’, ‘<code
dschulze@5892 2125 class=property>g</code>’, ‘<code class=property>svg</code>’, all <a
simon@5276 2126 href="http://www.w3.org/TR/SVG/intro.html#TermGraphicsElement"><em>graphics
simon@5276 2127 elements</em></a>, all <a
simon@5276 2128 href="http://www.w3.org/TR/SVG/intro.html#TermGraphicsReferencingElement"><em>graphics
dschulze@5892 2129 referencing elements</em></a> and the SVG ‘<code class=css><a
dschulze@5892 2130 href="http://www.w3.org/TR/SVG/extend.html#ForeignObjectElement">foreignObject</a></code>’
dschulze@5751 2131 element.
simon@5276 2132
dschulze@5892 2133 <p> Three-dimensional transform functions and the properties ‘<a
dschulze@5892 2134 href="#perspective"><code class=property>perspective</code></a>’, ‘<a
dschulze@5892 2135 href="#perspective-origin"><code
dschulze@5892 2136 class=property>perspective-origin</code></a>’, ‘<a
dschulze@5892 2137 href="#transform-style"><code class=property>transform-style</code></a>’
dschulze@5892 2138 and ‘<a href="#backface-visibility"><code
dschulze@5892 2139 class=property>backface-visibility</code></a>’ can not be used for the
dschulze@5892 2140 elements: ‘<code class=property>clipPath</code>’, ‘<code
dschulze@5892 2141 class=property>linearGradient</code>’, ‘<code
dschulze@5892 2142 class=property>radialGradient</code>’ and ‘<code
dschulze@5892 2143 class=property>pattern</code>’. If a transform list includes a
simon@5276 2144 three-dimensional transform function, the complete transform list must be
simon@5276 2145 ignored. The values of every previously named property must be ignored. <a
simon@5276 2146 class=term href="#transformable-element">Transformable elements</a> that
simon@5276 2147 are contained by one of these elements can have three-dimensional
dschulze@5892 2148 transform functions. Before a ‘<code class=property>clipPath</code>’,
dschulze@5892 2149 ‘<code class=property>mask</code>’ or ‘<code
dschulze@5892 2150 class=property>pattern</code>’ element can get applied to a target
simon@5276 2151 element, user agents must take the drawn results as static images in
simon@5276 2152 analogue of "flattening" the elements and taking the rendered content as a
simon@5276 2153 two-dimensional canvas.
simon@5276 2154
dschulze@5909 2155 <p> If the ‘<code class=property>vector-effect</code>’ property is set
dschulze@5909 2156 to ‘<code class=css>non-scaling-stroke</code>’ and an object is within
dschulze@5921 2157 a <a class=term href="#d-rendering-context">3D rendering context</a> the
dschulze@5921 2158 property has no affect on stroking the object.
dschulze@5909 2159
dschulze@5751 2160 <h3 id=svg-user-coordinate-space><span class=secno>13.6. </span> User
dschulze@5751 2161 coordinate space</h3>
dschulze@5751 2162
dschulze@6286 2163 <p> For the ‘<code class=property>pattern</code>’, ‘<code
dschulze@6286 2164 class=property>linearGradient</code>’, ‘<code
dschulze@6897 2165 class=property>radialGradient</code>’ and ‘<code
dschulze@6286 2166 class=property>clipPath</code>’ elements the ‘<a href="#effects"><code
dschulze@6286 2167 class=property>transform</code></a>’, ‘<code
dschulze@6286 2168 class=property>patternTransform</code>’, ‘<code
dschulze@6286 2169 class=property>gradientTransform</code>’ presentation attributes
dschulze@6286 2170 represents values in the current user coordinate system in place at the
dschulze@6286 2171 time when these elements are referenced (i.e., the user coordinate system
dschulze@6286 2172 for the element referencing the ‘<code class=property>pattern</code>’
dschulze@6286 2173 element via a ‘<code class=property>fill</code>’ or ‘<code
dschulze@6929 2174 class=property>stroke</code>’ property). Percentage values are relative
dschulze@6929 2175 to the <a href="#bounding-box">bounding box</a> of the referencing
dschulze@6929 2176 element.
dschulze@6286 2177
dschulze@6286 2178 <p> In particualar the ‘<code class=property>patternUnit</code>’,
dschulze@6286 2179 ‘<code class=property>gradientUnit</code>’ and ‘<code
dschulze@6286 2180 class=property>maskUnit</code>’ attributes don't affect the user
dschulze@6286 2181 coordinate system used for transformations <a href="#SVG11"
dschulze@6286 2182 rel=biblioentry>[SVG11]<!--{{SVG11}}--></a>.
dschulze@5751 2183
dschulze@5921 2184 <p> For all other <a class=term href="#transformable-element">transformable
dschulze@5892 2185 elements</a> the ‘<a href="#effects"><code
dschulze@5892 2186 class=property>transform</code></a>’ presentation attribute represents
dschulze@5892 2187 values in the current user coordinate system of the parent. All percentage
dschulze@5892 2188 values of the ‘<a href="#effects"><code
dschulze@5892 2189 class=property>transform</code></a>’ presentation attribute are relative
dschulze@7030 2190 to the element's <a href="#bounding-box"><var>bounding box</var></a>.
simon@5276 2191
simon@5276 2192 <div class=example>
dschulze@5892 2193 <p> The ‘<a href="#transform-origin"><code
dschulze@5892 2194 class=property>transform-origin</code></a>’ property on the pattern in
dschulze@5892 2195 the following example specifies a ‘<code class=css>50%</code>’
dschulze@5892 2196 translation of the origin in the horizontal and vertical dimension. The
dschulze@5892 2197 ‘<a href="#effects"><code class=property>transform</code></a>’
bert@6706 2198 property specifies a translation as well, but in absolute lengths.
simon@5276 2199
simon@5276 2200 <pre>&lt;svg xmlns="http://www.w3.org/2000/svg"&gt;
simon@5276 2201 &lt;style&gt;
simon@5276 2202 pattern {
dschulze@5751 2203 transform: rotate(45deg);
simon@5276 2204 transform-origin: 50% 50%;
simon@5276 2205 }
simon@5276 2206 &lt;/style&gt;
simon@5276 2207
simon@5276 2208 &lt;defs&gt;
simon@5276 2209 &lt;pattern id="pattern-1"&gt;
simon@5276 2210 &lt;rect id="rect1" width="100" height="100" fill="blue" /&gt;
simon@5276 2211 &lt;/pattern&gt;
simon@5276 2212 &lt;/defs&gt;
simon@5276 2213
dschulze@6929 2214 &lt;rect width="200" height="200" fill="url(#pattern-1)" /&gt;
simon@5276 2215 &lt;/svg&gt;</pre>
simon@5276 2216
dschulze@5892 2217 <p> An SVG ‘<code class=property>pattern</code>’ element doesn't have
dschulze@7030 2218 a bounding box. The <a href="#bounding-box"><var>bounding box</var></a>
dschulze@5921 2219 of the referencing ‘<code class=property>rect</code>’ element is used
dschulze@5921 2220 instead to solve the relative values of the ‘<a
dschulze@5921 2221 href="#transform-origin"><code
dschulze@5892 2222 class=property>transform-origin</code></a>’ property. Therefore the
dschulze@6929 2223 point of origin will get translated by 100 pixels temporarily to rotate
dschulze@5892 2224 the user space of the ‘<code class=property>pattern</code>’ elements
bert@6706 2225 content.
simon@5276 2226 </div>
simon@5276 2227
dschulze@5751 2228 <h3 id=transform-attribute-dom><span class=secno>13.7. </span> SVG DOM
dschulze@5892 2229 interface for the ‘<a href="#effects"><code
dschulze@5892 2230 class=property>transform</code></a>’ attribute</h3>
dschulze@5892 2231
dschulze@5892 2232 <p> The SVG specification defines the ‘<code class=css><a
dschulze@5892 2233 href="http://www.w3.org/TR/2011/REC-SVG11-20110816/coords.html#InterfaceSVGAnimatedTransformList">SVGAnimatedTransformList</a></code>’
dschulze@5751 2234 interface in the SVG DOM to provide access to the animated and the base
dschulze@5892 2235 value of the SVG ‘<a href="#effects"><code
dschulze@5892 2236 class=property>transform</code></a>’, ‘<code
dschulze@5892 2237 class=property>gradientTransform</code>’ and ‘<code
dschulze@5892 2238 class=property>patternTransform</code>’ attributes. To ensure backwards
dschulze@5892 2239 compatibility, this API must still be supported by user agents.
dschulze@5892 2240
dschulze@5892 2241 <p> The ‘<a href="#effects"><code class=property>transform</code></a>’
dschulze@5892 2242 property contributes to the CSS cascade. According to SVG 1.1 user agents
dschulze@5892 2243 conceptually insert a <a
simon@5276 2244 href="http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes">new
simon@5276 2245 author style sheet</a> for presentation attributes, which is the first in
dschulze@5892 2246 the author style sheet collection. ‘<code
dschulze@5892 2247 class=property>baseVal</code>’ gives the author the possibility to
dschulze@5892 2248 access and modify the values of the SVG ‘<a href="#effects"><code
dschulze@5892 2249 class=property>transform</code></a>’ attribute. To provide the necessary
dschulze@5892 2250 backwards compatibility to the SVG DOM, ‘<code
dschulze@5892 2251 class=property>baseVal</code>’ must reflect the values of this author
dschulze@5892 2252 style sheet. All modifications to SVG DOM objects of ‘<code
dschulze@5892 2253 class=property>baseVal</code>’ must affect this author style sheet
dschulze@5751 2254 immediately.
dschulze@5751 2255
dschulze@5892 2256 <p> ‘<code class=property>animVal</code>’ represents the computed style
dschulze@5892 2257 of the ‘<a href="#effects"><code class=property>transform</code></a>’
dschulze@5892 2258 property. Therefore it includes all applied <a
dschulze@5892 2259 href="http://www.w3.org/TR/css3-transitions/">CSS3 Transitions</a>, <a
dschulze@5892 2260 href="http://www.w3.org/TR/css3-animations/">CSS3 Animations</a> or <a
dschulze@5892 2261 href="#svg-animation">SVG Animations</a> if any of those are underway. The
dschulze@5892 2262 computed style and SVG DOM objects of ‘<code
dschulze@5892 2263 class=property>animVal</code>’ can not be modified.
dschulze@5892 2264
dschulze@5892 2265 <p> The attribute ‘<code class=css><a
dschulze@5892 2266 href="http://www.w3.org/TR/SVG/coords.html#__svg__SVGTransform__type">type</a></code>’
dschulze@5892 2267 of ‘<code class=css><a
dschulze@5892 2268 href="http://www.w3.org/TR/SVG/coords.html#InterfaceSVGTransform">SVGTransform</a></code>’
dschulze@5892 2269 must return ‘<code class=css><a
dschulze@5921 2270 href="http://www.w3.org/TR/SVG/coords.html#__svg__SVGTransform__SVG_TRANSFORM_UNKNOWN">SVG_TRANSFORM_UNKNOWN</a></code>’
dschulze@5921 2271 for <a href="#transform-functions">Transform Functions</a> or unit types
dschulze@5921 2272 that are not supported by this interface. If a two-dimensional transform
dschulze@5921 2273 function is not supported, the attribute ‘<code class=css><a
dschulze@5892 2274 href="http://www.w3.org/TR/SVG/coords.html#__svg__SVGTransform__matrix">matrix</a></code>’
dschulze@5892 2275 must return a 3x2 ‘<code class=css><a
dschulze@5892 2276 href="http://www.w3.org/TR/SVG/coords.html#InterfaceSVGMatrix">SVGMatrix</a></code>’
dschulze@5751 2277 with the corresponding values as described in the section <a
simon@5276 2278 href="#mathematical-description">Mathematical Description of Transform
simon@5276 2279 Functions</a>.
simon@5276 2280
dschulze@5895 2281 <h2 id=svg-animation><span class=secno>14. </span> SVG Animation</h2>
dschulze@5895 2282
dschulze@5921 2283 <h3 id=svg-animate-element><span class=secno>14.1. </span> The ‘<code
dschulze@5921 2284 class=property>animate</code>’ and ‘<code class=property>set</code>’
dschulze@5921 2285 element</h3>
dschulze@5921 2286
dschulze@5921 2287 <p> With this specification, the ‘<code class=property>animate</code>’
dschulze@5921 2288 element and the ‘<code class=property>set</code>’ element can animate
dschulze@5921 2289 the data type <var>&lt;transform-list&gt;</var>.
dschulze@5921 2290
dschulze@5921 2291 <p> The animation effect is post-multiplied to the underlying value for
dschulze@5921 2292 additive ‘<code class=property>animate</code>’ animations (see below)
dschulze@5921 2293 instead of added to the underlying value, due to the specific behavior of
dschulze@5921 2294 <var>&lt;transform-list&gt;</var> animations.
dschulze@5921 2295
dschulze@5921 2296 <p> <var>From-to</var>, <var>from-by</var> and <var>by</var> animations are
dschulze@5921 2297 defined in SMIL to be equivalent to a corresponding <var>values</var>
dschulze@5921 2298 animation. However, <var>to</var> animations are a mixture of additive and
dschulze@5921 2299 non-additive behavior <a href="#SMIL3"
dschulze@5921 2300 rel=biblioentry>[SMIL3]<!--{{SMIL3}}--></a>.
dschulze@5921 2301
dschulze@5921 2302 <p> <var>To</var> animations on ‘<code class=property>animate</code>’
dschulze@5921 2303 provide specific functionality to get a smooth change from the underlying
dschulze@5921 2304 value to the ‘<code class=property>to</code>’ attribute value, which
dschulze@5921 2305 conflicts mathematically with the requirement for additive transform
dschulze@5921 2306 animations to be post-multiplied. As a consequence, the behavior of
dschulze@5921 2307 <var>to</var> animations for ‘<code class=property>animate</code>’ is
dschulze@5921 2308 undefined. Authors are suggested to use <var>from-to</var>,
dschulze@5921 2309 <var>from-by</var>, <var>by</var> or <var>values</var> animations to
dschulze@5921 2310 achieve any desired transform animation.
dschulze@5921 2311
dschulze@5921 2312 <p> The value ‘<code class=property>paced</code>’ is undefined for the
dschulze@5921 2313 attribute ‘<code class=property>calcMode</code>’ on ‘<code
dschulze@5921 2314 class=property>animate</code>’ for animations of the data type
dschulze@5921 2315 <var>&lt;transform-list&gt;</var>. If specified, UAs may choose the value
dschulze@5921 2316 ‘<code class=property>linear</code>’ instead. Future versions of this
dschulze@5921 2317 specification may define how paced animations can be performed on
dschulze@5921 2318 <var>&lt;transform-list&gt;</var>.
dschulze@5921 2319
dschulze@5921 2320 <p class=note>The following paragraphs extend <a
dschulze@5895 2321 href="http://www.w3.org/TR/SVG/animate.html#complexDistances">Elements,
dschulze@5895 2322 attributes and properties that can be animated</a> <a href="#SVG11"
dschulze@5895 2323 rel=biblioentry>[SVG11]<!--{{SVG11}}--></a>.
dschulze@5895 2324
dschulze@5895 2325 <p> The introduce presentation attributes ‘<a href="#effects"><code
dschulze@5895 2326 class=property>transform</code></a>’, ‘<a
dschulze@5895 2327 href="#transform-origin"><code
dschulze@5895 2328 class=property>transform-origin</code></a>’, ‘<a
dschulze@5895 2329 href="#perspective"><code class=property>perspective</code></a>’, ‘<a
dschulze@5895 2330 href="#perspective-origin"><code
dschulze@5895 2331 class=property>perspective-origin</code></a>’, ‘<a
dschulze@5895 2332 href="#transform-style"><code class=property>transform-style</code></a>’
dschulze@5895 2333 and ‘<a href="#backface-visibility"><code
dschulze@5895 2334 class=property>backface-visibility</code></a>’ are animatable. ‘<a
dschulze@5895 2335 href="#transform-style"><code class=property>transform-style</code></a>’
dschulze@5895 2336 and ‘<a href="#backface-visibility"><code
dschulze@5895 2337 class=property>backface-visibility</code></a>’ are non-additive.
dschulze@5895 2338
dschulze@5895 2339 <p> With this specification the SVG basic data type
dschulze@5895 2340 <var>&lt;transform-list&gt;</var> is equivalent to a list of
dschulze@5895 2341 <var>&lt;transform-function&gt;</var>s. <var>&lt;transform-list&gt;</var>
dschulze@5895 2342 is animatable and additive. The data type can be animated using the SVG
dschulze@5895 2343 ‘<code class=css><a
dschulze@5892 2344 href="http://www.w3.org/TR/SVG/animate.html#AnimateElement">animate</a></code>’
dschulze@5895 2345 element and the SVG ‘<code class=css><a
dschulze@5892 2346 href="http://www.w3.org/TR/SVG/animate.html#SetElement">set</a></code>’
dschulze@5895 2347 element. SVG animations must run the same animation steps as described in
dschulze@5892 2348 section <a href="#animation">Transitions and Animations between Transform
dschulze@5892 2349 Values</a>.
simon@5276 2350
dschulze@5895 2351 <p> The set of animatable data types gets extended by
dschulze@5895 2352 <em>&lt;translation-value&gt;</em>. The new data type is animatable and
dschulze@5895 2353 additive.
dschulze@5895 2354
dschulze@5895 2355 <table class=data>
dschulze@5895 2356 <caption>Animatable data types</caption>
dschulze@5895 2357
dschulze@5895 2358 <thead>
dschulze@5895 2359 <tr>
dschulze@5895 2360 <th>Data type
dschulze@5895 2361
dschulze@5895 2362 <th>Additive?
dschulze@5895 2363
dschulze@5895 2364 <th>‘<code class=property>animate</code>’
dschulze@5895 2365
dschulze@5895 2366 <th>‘<code class=property>set</code>’
dschulze@5895 2367
dschulze@5895 2368 <th>‘<code class=property>animateColor</code>’
dschulze@5895 2369
dschulze@5895 2370 <th>‘<code class=property>animateTransform</code>’
dschulze@5895 2371
dschulze@5895 2372 <th>Notes
dschulze@5895 2373
dschulze@5895 2374 <tbody>
dschulze@5895 2375 <tr>
dschulze@5902 2376 <th><var>&lt;transform-list&gt;</var>
dschulze@5895 2377
dschulze@5895 2378 <td>yes
dschulze@5895 2379
dschulze@5895 2380 <td>yes
dschulze@5895 2381
dschulze@5895 2382 <td>yes
dschulze@5895 2383
dschulze@5895 2384 <td>no
dschulze@5895 2385
dschulze@5895 2386 <td>yes
dschulze@5895 2387
dschulze@5902 2388 <td>Additive for ‘<code class=property>animateTransform</code>’
dschulze@5902 2389 means that a transformation is post-multiplied to the base set of
dschulze@5902 2390 transformations.
dschulze@5895 2391
dschulze@5895 2392 <tr>
dschulze@5902 2393 <th><var>&lt;translation-value&gt;</var>
dschulze@5895 2394
dschulze@5895 2395 <td>yes
dschulze@5895 2396
dschulze@5895 2397 <td>yes
dschulze@5895 2398
dschulze@5895 2399 <td>yes
dschulze@5895 2400
dschulze@5895 2401 <td>no
dschulze@5895 2402
dschulze@5895 2403 <td>no
dschulze@5895 2404
dschulze@5895 2405 <td> 
dschulze@5895 2406 </table>
dschulze@5895 2407
dschulze@5900 2408 <h3 id=neutral-element><span class=secno>14.2. </span> Neutral element for
dschulze@5900 2409 addition</h3>
dschulze@5900 2410
dschulze@5921 2411 <p> Some animations require a neutral element for addition. For transform
dschulze@5921 2412 functions this is a scalar or a list of scalars of 0. Examples of neutral
dschulze@5921 2413 elements for transform functions are ‘<code
dschulze@5921 2414 class=css>translate(0)</code>’, ‘<code class=css>translate3d(0, 0,
dschulze@5921 2415 0)</code>’, ‘<code class=css>translateX(0)</code>’, ‘<code
dschulze@5900 2416 class=css>translateY(0)</code>’, ‘<code
dschulze@5900 2417 class=css>translateZ(0)</code>’, ‘<code class=css>scale(0)</code>’,
dschulze@5900 2418 ‘<code class=css>scaleX(0)</code>’, ‘<code
dschulze@5900 2419 class=css>scaleY(0)</code>’, ‘<code class=css>scaleZ(0)</code>’,
dschulze@5921 2420 ‘<code class=css>rotate(0)</code>’, ‘<code
dschulze@5921 2421 class=css>rotate3d(v<sub>x</sub>, v<sub>y</sub>, v<sub>z</sub>,
dschulze@5921 2422 0)</code>’ (where <var>v</var> is a context dependent vector), ‘<code
dschulze@5921 2423 class=css>rotateX(0)</code>’, ‘<code class=css>rotateY(0)</code>’,
dschulze@6608 2424 ‘<code class=css>rotateZ(0)</code>’, ‘<code class=css>skew(0,
dschulze@6902 2425 0)</code>’, ‘<code class=css>skewX(0)</code>’, ‘<code
dschulze@6902 2426 class=css>skewY(0)</code>’, ‘<code class=css>matrix(0, 0, 0, 0, 0,
dschulze@6902 2427 0)</code>’, ‘<code class=css>matrix3d(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
dschulze@6902 2428 0, 0, 0, 0, 0)</code>’ and ‘<code class=css>perspective(0)</code>’.
dschulze@5921 2429
dschulze@5923 2430 <p class=note> Animations to or from the neutral element of additions
dschulze@6902 2431 ‘<code class=css>matrix</code>’, ‘<code class=css>matrix3d</code>’
dschulze@6902 2432 and ‘<a href="#perspective"><code class=css>perspective</code></a>’
dschulze@6902 2433 fall back to discrete animations (See <a
dschulze@6902 2434 href="#matrix-interpolation">Interpolation of Matrices</a>).
dschulze@5900 2435
dschulze@5900 2436 <div class=example>
dschulze@5900 2437 <p> A <var>by</var> animation with a by value v<sub>b</sub> is equivalent
dschulze@5900 2438 to the same animation with a values list with 2 values, the neutral
dschulze@5900 2439 element for addition for the domain of the target attribute (denoted 0)
dschulze@6902 2440 and v<sub>b</sub>, and ‘<code class=css>additive="sum"</code>’. <a
dschulze@6902 2441 href="#SMIL3" rel=biblioentry>[SMIL3]<!--{{SMIL3}}--></a>
dschulze@5900 2442
dschulze@5900 2443 <pre>
dschulze@5900 2444 &lt;rect width="100" height="100"&gt;
dschulze@5900 2445 &lt;animateTransform attributeName="transform" attributeType="XML"
dschulze@5900 2446 type="scale" by="1" dur="5s" fill="freeze"/&gt;
dschulze@5900 2447 &lt;/rect&gt;</pre>
dschulze@5900 2448
dschulze@5900 2449 <p> The neutral element for addition when performing a <var>by</var>
dschulze@6902 2450 animation with ‘<code class=css>type="scale"</code>’ is the value 0.
dschulze@6902 2451 Thus, performing the animation of the example above causes the rectangle
dschulze@6902 2452 to be invisible at time 0s (since the animated transform list value is
dschulze@6902 2453 ‘<code class=css>scale(0)</code>’), and be scaled back to its
dschulze@6902 2454 original size at time 5s (since the animated transform list value is
dschulze@6902 2455 ‘<code class=css>scale(1)</code>’).
dschulze@5900 2456 </div>
dschulze@5900 2457
dschulze@6902 2458 <h3 id=svg-attribute-name><span class=secno>14.3. </span> The SVG ‘<code
dschulze@6902 2459 class=property>attributeName</code>’ attribute</h3>
simon@5276 2460
simon@5276 2461 <p> <a href="http://www.w3.org/TR/SVG/animate.html">SVG 1.1 Animation</a>
dschulze@5892 2462 defines the ‘<code class=css><a
dschulze@5892 2463 href="http://www.w3.org/TR/SVG/animate.html#TargetAttributes">attributeName</a></code>’
dschulze@5751 2464 attribute to specify the name of the target attribute. For the
dschulze@5892 2465 presentation attributes ‘<code
dschulze@5892 2466 class=property>gradientTransform</code>’ and ‘<code
dschulze@5892 2467 class=property>patternTransform</code>’ it will also be possible to use
dschulze@5892 2468 the value ‘<a href="#effects"><code
dschulze@5892 2469 class=property>transform</code></a>’. The same ‘<a
dschulze@5892 2470 href="#effects"><code class=property>transform</code></a>’ property will
dschulze@5892 2471 get animated.
simon@5276 2472
simon@5276 2473 <div class=example>
simon@5276 2474 <p> In this example the gradient transformation of the linear gradient
bert@6706 2475 gets animated.
simon@5276 2476
simon@5276 2477 <pre>&lt;linearGradient gradientTransform="scale(2)"&gt;
simon@5276 2478 &lt;animate attributeName="gradientTransform" from="scale(2)" to="scale(4)"
simon@5276 2479 dur="3s" additive="sum"/&gt;
simon@5276 2480 &lt;animate attributeName="transform" from="translate(0, 0)" to="translate(100px, 100px)"
simon@5276 2481 dur="3s" additive="sum"/&gt;
simon@5276 2482 &lt;/linearGradient&gt;</pre>
simon@5276 2483
dschulze@5892 2484 <p>The ‘<code class=property>linearGradient</code>’ element specifies
dschulze@5892 2485 the ‘<code class=property>gradientTransform</code>’ presentation
dschulze@5892 2486 attribute. The two ‘<code class=property>animate</code>’ elements
dschulze@5892 2487 address the target attribute ‘<code
dschulze@5892 2488 class=property>gradientTransform</code>’ and ‘<a
dschulze@5892 2489 href="#effects"><code class=property>transform</code></a>’. Even so all
dschulze@5892 2490 animations apply to the same gradient transformation by taking the value
dschulze@5892 2491 of the ‘<code class=property>gradientTransform</code>’ presentation
simon@5276 2492 attribute, applying the scaling of the first animation and applying the
bert@6706 2493 translation of the second animation one after the other.
simon@5276 2494 </div>
simon@5276 2495 <!-- ======================================================================================================= -->
simon@5276 2496
dschulze@5895 2497 <h2 id=transform-functions><span class=secno>15. </span> The Transform
simon@5276 2498 Functions</h2>
simon@5276 2499
dschulze@5892 2500 <p> The value of the ‘<a href="#effects"><code
dschulze@5892 2501 class=property>transform</code></a>’ property is a list of
simon@5276 2502 <var>&lt;transform-functions&gt;</var>. The set of allowed transform
simon@5276 2503 functions is given below. For <var>&lt;transform-functions&gt;</var> the
simon@5276 2504 type <var>&lt;translation-value&gt;</var> is defined as a
simon@5276 2505 <var>&lt;length&gt;</var> or <var>&lt;percentage&gt;</var> value, and the
simon@5276 2506 <var>&lt;angle&gt;</var> type is defined by <a
simon@5276 2507 href="http://www.w3.org/TR/css3-values/">CSS Values and Units Module.</a>
simon@5276 2508 Wherever <var>&lt;angle&gt;</var> is used in this specification, a
simon@5276 2509 <var>&lt;number&gt;</var> that is equal to zero is also allowed, which is
simon@5276 2510 treated the same as an angle of zero degrees.
simon@5276 2511
dschulze@5895 2512 <h3 id=two-d-transform-functions><span class=secno>15.1. </span>2D
simon@5276 2513 Transform Functions</h3>
simon@5276 2514
simon@5276 2515 <dl>
dschulze@5743 2516 <dt id=matrix-function> <code class=css>matrix(&lt;number&gt;,
dschulze@5743 2517 &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;,
dschulze@5743 2518 &lt;number&gt;)</code>
simon@5276 2519
simon@5276 2520 <dd> specifies a 2D transformation in the form of a <a
simon@5276 2521 href="#MatrixDefined">transformation matrix</a> of the six values a-f.
simon@5276 2522
dschulze@5743 2523 <dt id=translate-function> <code
dschulze@5743 2524 class=css>translate(&lt;translation-value&gt;[,
simon@5276 2525 &lt;translation-value&gt;])</code>
simon@5276 2526
simon@5276 2527 <dd> specifies a <a href="#TranslateDefined">2D translation</a> by the
simon@5276 2528 vector [tx, ty], where tx is the first translation-value parameter and ty
simon@5276 2529 is the optional second translation-value parameter. If
simon@5276 2530 <em>&lt;ty&gt;</em> is not provided, ty has zero as a value.
simon@5276 2531
dschulze@5743 2532 <dt id=translateX-function> <code
dschulze@5743 2533 class=css>translateX(&lt;translation-value&gt;)</code>
simon@5276 2534
simon@5276 2535 <dd> specifies a <a href="#TranslateDefined">translation</a> by the given
simon@5276 2536 amount in the X direction.
simon@5276 2537
dschulze@5743 2538 <dt id=translateY-function> <code
dschulze@5743 2539 class=css>translateY(&lt;translation-value&gt;)</code>
simon@5276 2540
simon@5276 2541 <dd> specifies a <a href="#TranslateDefined">translation</a> by the given
simon@5276 2542 amount in the Y direction.
simon@5276 2543
dschulze@5743 2544 <dt id=scale-function> <code class=css>scale(&lt;number&gt;[,
dschulze@5743 2545 &lt;number&gt;])</code>
simon@5276 2546
simon@5276 2547 <dd> specifies a <a href="#ScaleDefined">2D scale</a> operation by the
simon@5276 2548 [sx,sy] scaling vector described by the 2 parameters. If the second
dschulze@6607 2549 parameter is not provided, it takes a value equal to the first. For
simon@5276 2550 example, scale(1, 1) would leave an element unchanged, while scale(2, 2)
simon@5276 2551 would cause it to appear twice as long in both the X and Y axes, or four
simon@5276 2552 times its typical geometric size.
simon@5276 2553
dschulze@5743 2554 <dt id=scaleX-function> <code class=css>scaleX(&lt;number&gt;)</code>
simon@5276 2555
simon@5276 2556 <dd> specifies a <a href="#ScaleDefined">2D scale</a> operation using the
simon@5276 2557 [sx,1] scaling vector, where sx is given as the parameter.
simon@5276 2558
dschulze@5743 2559 <dt id=scaleY-function> <code class=css>scaleY(&lt;number&gt;)</code>
simon@5276 2560
simon@5276 2561 <dd> specifies a <a href="#ScaleDefined">2D scale</a> operation using the
simon@5276 2562 [1,sy] scaling vector, where sy is given as the parameter.
simon@5276 2563
dschulze@5743 2564 <dt id=rotate-function> <code class=css>rotate(&lt;angle&gt;)</code>
simon@5276 2565
simon@5276 2566 <dd> specifies a <a href="#RotateDefined">2D rotation</a> by the angle
simon@5276 2567 specified in the parameter about the origin of the element, as defined by
dschulze@6608 2568 the ‘<a href="#transform-origin"><code
dschulze@6608 2569 class=property>transform-origin</code></a>’ property. For example,
dschulze@6608 2570 ‘<code class=css>rotate(90deg)</code>’ would cause elements to appear
dschulze@5892 2571 rotated one-quarter of a turn in the clockwise direction.
simon@5276 2572
dschulze@6608 2573 <dt> <code class=css>skew(&lt;angle&gt;[, &lt;angle&gt;])</code>
dschulze@6608 2574
dschulze@6608 2575 <dd> specifies a <a href="#SkewDefined">2D skew</a> by [ax,ay] for X and
dschulze@6608 2576 Y. If the second parameter is not provided, it has a zero value.
dschulze@6608 2577 <p class=note>Note that the behavior of ‘<code class=css>skew</code>’
dschulze@6608 2578 is different from mutliplying ‘<code class=css>skewX</code>’ with
dschulze@6608 2579 ‘<code class=css>skewY</code>’. Implementations must support this
bert@6706 2580 function for compatibility with legacy content.
dschulze@6608 2581
dschulze@5743 2582 <dt id=skewX-function> <code class=css>skewX(&lt;angle&gt;)</code>
simon@5276 2583
simon@5276 2584 <dd> specifies a <a href="#SkewXDefined">2D skew transformation along the
simon@5276 2585 X axis</a> by the given angle.
simon@5276 2586
dschulze@5743 2587 <dt id=skewY-function> <code class=css>skewY(&lt;angle&gt;)</code>
simon@5276 2588
simon@5276 2589 <dd> specifies a <a href="#SkewYDefined">2D skew transformation along the
simon@5276 2590 Y axis</a> by the given angle.
simon@5276 2591 </dl>
simon@5276 2592
dschulze@5895 2593 <h3 id=three-d-transform-functions><span class=secno>15.2. </span>3D
simon@5276 2594 Transform Functions</h3>
simon@5276 2595
simon@5276 2596 <dl>
dschulze@5743 2597 <dt id=matrix3d-function> <code class=css>matrix3d(&lt;number&gt;,
simon@5276 2598 &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;,
simon@5276 2599 &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;,
simon@5276 2600 &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;,
dschulze@5743 2601 &lt;number&gt;, &lt;number&gt;, &lt;number&gt;)</code>
simon@5276 2602
simon@5276 2603 <dd> specifies a 3D transformation as a 4x4 homogeneous matrix of 16
simon@5276 2604 values in column-major order.
simon@5276 2605
dschulze@5743 2606 <dt id=translate3d-function> <code
dschulze@5743 2607 class=css>translate3d(&lt;translation-value&gt;,
simon@5276 2608 &lt;translation-value&gt;, &lt;length&gt;)</code>
simon@5276 2609
simon@5276 2610 <dd> specifies a <a href="#Translate3dDefined">3D translation</a> by the
simon@5276 2611 vector [tx,ty,tz], with tx, ty and tz being the first, second and third
simon@5276 2612 translation-value parameters respectively.
simon@5276 2613
dschulze@5743 2614 <dt id=translateZ-function> <code
dschulze@5743 2615 class=css>translateZ(&lt;length&gt;)</code>
simon@5276 2616
simon@5276 2617 <dd> specifies a <a href="#Translate3dDefined">3D translation</a> by the
simon@5276 2618 vector [0,0,tz] with the given amount in the Z direction.
simon@5276 2619
dschulze@5743 2620 <dt id=scale3d-function> <code class=css>scale3d(&lt;number&gt;,
dschulze@5743 2621 &lt;number&gt;, &lt;number&gt;)</code>
simon@5276 2622
simon@5276 2623 <dd> specifies a <a href="#Scale3dDefined">3D scale</a> operation by the
simon@5276 2624 [sx,sy,sz] scaling vector described by the 3 parameters.
simon@5276 2625
dschulze@5743 2626 <dt id=scaleZ-function> <code class=css>scaleZ(&lt;number&gt;)</code>
simon@5276 2627
simon@5276 2628 <dd> specifies a <a href="#Scale3dDefined">3D scale</a> operation using
simon@5276 2629 the [1,1,sz] scaling vector, where sz is given as the parameter.
simon@5276 2630
dschulze@5743 2631 <dt id=rotate3d-function> <code class=css>rotate3d(&lt;number&gt;,
dschulze@5743 2632 &lt;number&gt;, &lt;number&gt;, &lt;angle&gt;)</code>
simon@5276 2633
simon@5276 2634 <dd> specifies a <a href="#Rotate3dDefined">3D rotation</a> by the angle
simon@5276 2635 specified in last parameter about the [x,y,z] direction vector described
dschulze@6607 2636 by the first three parameters. A direction vector that cannot be
simon@5276 2637 normalized, such as [0,0,0], will cause the rotation to not be applied.
dschulze@6402 2638 <p class=note>Note that the rotation is clockwise as one looks from the
bert@6706 2639 end of the vector toward the origin.
simon@5276 2640
dschulze@5743 2641 <dt id=rotateX-function> <code class=css>rotateX(&lt;angle&gt;)</code>
simon@5276 2642
simon@5276 2643 <dd> same as <code class=css>rotate3d(1, 0, 0, &lt;angle&gt;)</code>.
simon@5276 2644
dschulze@5743 2645 <dt id=rotateY-function> <code class=css>rotateY(&lt;angle&gt;)</code>
simon@5276 2646
simon@5276 2647 <dd> same as <code class=css>rotate3d(0, 1, 0, &lt;angle&gt;)</code>.
simon@5276 2648
dschulze@5743 2649 <dt id=rotateZ-function> <code class=css>rotateZ(&lt;angle&gt;)</code>
simon@5276 2650
simon@5276 2651 <dd> same as <code class=css>rotate3d(0, 0, 1, &lt;angle&gt;)</code>,
simon@5276 2652 which is also the same as <code class=css>rotate(&lt;angle&gt;)</code>.
simon@5276 2653
simon@5276 2654 <dt id=perspective-function> <code
simon@5276 2655 class=css>perspective(&lt;length&gt;)</code>
simon@5276 2656
simon@5276 2657 <dd> specifies a <a href="#PerspectiveDefined">perspective projection
simon@5276 2658 matrix</a>. This matrix scales points in X and Y based on their Z value,
simon@5276 2659 scaling points with positive Z values away from the origin, and those
simon@5276 2660 with negative Z values towards the origin. Points on the z=0 plane are
simon@5276 2661 unchanged. The parameter represents the distance of the z=0 plane from
simon@5276 2662 the viewer. Lower values give a more flattened pyramid and therefore a
simon@5276 2663 more pronounced perspective effect. For example, a value of 1000px gives
simon@5276 2664 a moderate amount of foreshortening and a value of 200px gives an extreme
simon@5276 2665 amount. The value for depth must be greater than zero, otherwise the
simon@5276 2666 function is invalid.
simon@5276 2667 </dl>
simon@5276 2668 <!-- ======================================================================================================= -->
simon@5276 2669
dschulze@5895 2670 <h2 id=transform-function-lists><span class=secno>16. </span> The Transform
simon@5276 2671 Function Lists</h2>
simon@5276 2672
simon@5276 2673 <p> If a list of <var>&lt;transform-functions&gt;</var> is provided, then
simon@5276 2674 the net effect is as if each transform function had been specified
simon@5276 2675 separately in the order provided. For example,
simon@5276 2676
simon@5276 2677 <pre>
simon@5276 2678 &lt;div style="transform:translate(-10px,-20px) scale(2) rotate(45deg) translate(5px,10px)"/&gt;
simon@5276 2679 </pre>
simon@5276 2680
simon@5276 2681 <p> is functionally equivalent to:
simon@5276 2682
simon@5276 2683 <pre>
simon@5276 2684 &lt;div style="transform:translate(-10px,-20px)"&gt;
simon@5276 2685 &lt;div style="transform:scale(2)"&gt;
simon@5276 2686 &lt;div style="transform:rotate(45deg)"&gt;
simon@5276 2687 &lt;div style="transform:translate(5px,10px)"&gt;
simon@5276 2688 &lt;/div&gt;
simon@5276 2689 &lt;/div&gt;
simon@5276 2690 &lt;/div&gt;
simon@5276 2691 &lt;/div&gt;
simon@5276 2692 </pre>
simon@5276 2693
simon@5276 2694 <p> That is, in the absence of other styling that affects position and
simon@5276 2695 dimensions, a nested set of transforms is equivalent to a single list of
simon@5276 2696 transform functions, applied from the outside in. The resulting transform
dschulze@5910 2697 is the matrix multiplication of the list of transforms.
dschulze@5910 2698
dschulze@5931 2699 <p> If a transform function causes the <a class=term
dschulze@5931 2700 href="#current-transformation-matrix-ctm">current transformation matrix
ayg@5989 2701 (CTM)</a> of an object to be non-invertible, the object and its content do
ayg@5989 2702 not get displayed.
dschulze@5910 2703
dschulze@5910 2704 <div class=example>
bert@6706 2705 <p> The object in the following example gets scaled by 0.
dschulze@5910 2706
dschulze@5910 2707 <pre>&lt;style&gt;
dschulze@5910 2708 .box {
dschulze@5910 2709 transform: scale(0);
dschulze@5910 2710 }
dschulze@5910 2711 &lt;/style&gt;
dschulze@5910 2712
dschulze@5910 2713 &lt;div class="box"&gt;
dschulze@5910 2714 Not visible
dschulze@5910 2715 &lt;/div&gt;</pre>
dschulze@5910 2716
dschulze@5910 2717 <p> The scaling causes a non-invertible CTM for the coordinate space of
dschulze@5910 2718 the div box. Therefore neither the div box, nor the text in it get
bert@6706 2719 displayed.
dschulze@5910 2720 </div>
simon@5276 2721 <!-- ======================================================================================================= -->
simon@5276 2722
dschulze@5895 2723 <h2 id=animation><span class=secno>17. </span> Interpolation of Transforms</h2>
dschulze@5690 2724
dschulze@5690 2725 <p> When animating or transitioning transforms, the transform function
dschulze@5690 2726 lists must be interpolated. For interpolation between one transform
dschulze@5690 2727 <em>from-transform</em> and a second transforms <em>to-transform</em>, the
dschulze@5690 2728 rules described below are applied.
simon@5276 2729
simon@5276 2730 <ul>
dschulze@5743 2731 <li id=none-none-animation> If both the <em>from-</em> and
dschulze@5892 2732 <em>to-transform</em> are ‘<code class=css>none</code>’:
simon@5276 2733 <ul>
dschulze@5690 2734 <li> There is no interpolation necessary. The computed value stays
dschulze@5892 2735 ‘<code class=css>none</code>’.
simon@5276 2736 </ul>
simon@5276 2737
dschulze@5743 2738 <li id=none-transform-animation> If one of the <em>from-</em> or
dschulze@5892 2739 <em>to-transforms</em> is ‘<code class=css>none</code>’.
simon@5276 2740 <ul>
dschulze@5892 2741 <li> The value ‘<code class=css>none</code>’ is replaced by an
dschulze@5892 2742 equivalent <a href="#TermIdentityTransformFunction"><i>identity
dschulze@5743 2743 transform function</i></a> list for the corresponding transform
dschulze@5743 2744 function list. Both transform function lists get interpolated following
dschulze@5743 2745 the next rule.
simon@5276 2746 </ul>
simon@5276 2747
dschulze@5690 2748 <div class=example>
dschulze@5892 2749 <p> For example, if <em>from-transform</em> is ‘<code
dschulze@5892 2750 class=css>scale(2)</code>’ and <em>to-transform</em> is ‘<code
dschulze@5892 2751 class=css>none</code>’ then the value ‘<code
dschulze@5892 2752 class=css>scale(1)</code>’ will be used for <em>to-transform</em> and
dschulze@5892 2753 animation will proceed using the next rule. Similarly, if
dschulze@5892 2754 <em>from-transform</em> is ‘<code class=css>none</code>’ and
dschulze@5892 2755 <em>to-transform</em> is ‘<code class=css>scale(2)
dschulze@5892 2756 rotate(50deg)</code>’ then the animation will execute as if
dschulze@5892 2757 <em>from-transform</em> is ‘<code class=css>scale(1)
bert@6706 2758 rotate(0)</code>’.
dschulze@5690 2759 </div>
dschulze@5690 2760
dschulze@5743 2761 <li id=transform-transform-animation> If <em>from-</em> and
dschulze@5743 2762 <em>to-transform</em> have the same number of transform functions, each
dschulze@6402 2763 transform function pair has either the same name, or is a derivative of
dschulze@6402 2764 the same <a href="#transform-primitives">primitive</a>.
simon@5276 2765 <ul>
dschulze@5690 2766 <li> Interpolate each transform function pair as described in <a
dschulze@5690 2767 href="#interpolation-of-transform-functions">Interpolation of transform
dschulze@5690 2768 functions</a>. The computed value is the resulting transform function
dschulze@5690 2769 list.
simon@5276 2770 </ul>
simon@5276 2771
dschulze@5690 2772 <div class=example>
dschulze@5892 2773 <p> For example, if <em>from-transform</em> is ‘<code
dschulze@5892 2774 class=css>scale(1) translate(0)</code>’ and <em>to-transform</em> is
dschulze@5892 2775 ‘<code class=css>translate(100px) scale(2)</code>’ then ‘<code
dschulze@5892 2776 class=css>scale(1)</code>’ and ‘<code
dschulze@5892 2777 class=css>translate(100px)</code>’ as well as ‘<code
dschulze@5892 2778 class=css>translate(0)</code>’ and ‘<code
dschulze@5892 2779 class=css>scale(2)</code>’ don't share a common primitive and
bert@6706 2780 therefore can not get interpolated following this rule.
dschulze@5690 2781 </div>
dschulze@5690 2782
dschulze@5743 2783 <li id=other-animation> In all other cases:
simon@5276 2784 <ul>
dschulze@5690 2785 <li> The transform functions of each transform function list on the
dschulze@5892 2786 <em>from-</em> and <em>to-transform</em> get post multiplied and
dschulze@5892 2787 converted into 4x4 matrices. Each of the matrices gets interpolated
dschulze@5892 2788 following the instructions in <a
dschulze@5892 2789 href="#matrix-interpolation">Interpolation of matrices</a>. The
dschulze@5892 2790 computed value is the transform function ‘<code
dschulze@5892 2791 class=css>matrix</code>’ if both initial matrices can be represented
dschulze@5892 2792 by a correlating 3x2 matrix and ‘<code class=css>matrix3d</code>’
dschulze@5892 2793 otherwise.
simon@5276 2794 </ul>
simon@5276 2795 </ul>
simon@5276 2796
simon@5276 2797 <p> In some cases, an animation might cause a transformation matrix to be
simon@5276 2798 singular or non-invertible. For example, an animation in which scale moves
simon@5276 2799 from 1 to -1. At the time when the matrix is in such a state, the
dschulze@5892 2800 transformed element is not rendered.</p>
dschulze@5892 2801 <!-- ======================================================================================================= -->
dschulze@5892 2802
dschulze@5895 2803 <h2 id=transform-primitives><span class=secno>18. </span> Transform
dschulze@5892 2804 function primitives and derivatives</h2>
dschulze@5690 2805
dschulze@5690 2806 <p> Some transform functions can be represented by more generic transform
dschulze@5690 2807 functions. These transform functions are called derived transform
dschulze@5690 2808 functions, the generic transform functions primitives. Primitives for
dschulze@5690 2809 two-dimensional and three-dimensional transform functions are listed
dschulze@5690 2810 below.
dschulze@5690 2811
dschulze@6299 2812 <p> Two-dimensional primitives with derived transform functions are:
dschulze@5690 2813
dschulze@5690 2814 <dl>
dschulze@5743 2815 <dt id=translate-primitive> <code
dschulze@5743 2816 class=css>translate(&lt;translation-value&gt;,
dschulze@5690 2817 &lt;translation-value&gt;)</code>
dschulze@5690 2818
dschulze@5690 2819 <dd> for <code class=css>translateX(&lt;translation-value&gt;)</code>,
dschulze@5690 2820 <code class=css>translateY(&lt;translation-value&gt;)</code> and <code
dschulze@5690 2821 class=css>translate(&lt;translation-value&gt;)</code>.
dschulze@5690 2822
dschulze@5743 2823 <dt id=rotate-three-primitive> <code class=css>rotate(&lt;angle&gt;,
dschulze@5743 2824 &lt;translation-value&gt;, &lt;translation-value&gt;)</code>
dschulze@5690 2825
dschulze@5690 2826 <dd> for <code class=css>rotate(&lt;angle&gt;)</code> if <a
dschulze@5690 2827 href="#svg-transform-functions">rotate with three arguments</a> is
dschulze@5690 2828 supported.
dschulze@5690 2829
dschulze@5743 2830 <dt id=scale-primitive> <code class=css>scale(&lt;number&gt;,
dschulze@5743 2831 &lt;number&gt;)</code>
dschulze@5690 2832
dschulze@5690 2833 <dd> for <code class=css>scaleX(&lt;number&gt;)</code>, <code
dschulze@5690 2834 class=css>scaleY(&lt;number&gt;)</code> and <code
dschulze@5690 2835 class=css>scale(&lt;number&gt;)</code>.
dschulze@5690 2836 </dl>
dschulze@5690 2837
dschulze@6299 2838 <p> Three-dimensional primitives with derived transform functions are:
dschulze@5690 2839
dschulze@5690 2840 <dl>
dschulze@5743 2841 <dt id=translate3d-primitive> <code
dschulze@5743 2842 class=css>translate3d(&lt;translation-value&gt;,
dschulze@5690 2843 &lt;translation-value&gt;, &lt;length&gt;)</code>
dschulze@5690 2844
dschulze@5690 2845 <dd> for <code class=css>translateX(&lt;translation-value&gt;)</code>,
dschulze@5690 2846 <code class=css>translateY(&lt;translation-value&gt;)</code>, <code
dschulze@5690 2847 class=css>translateZ(&lt;number&gt;)</code> and <code
dschulze@5690 2848 class=css>translate(&lt;translation-value&gt;[,
dschulze@5690 2849 &lt;translation-value&gt;])</code>.
dschulze@5690 2850
dschulze@5743 2851 <dt id=scale3d-primitive> <code class=css>scale3d(&lt;number&gt;,
dschulze@5743 2852 &lt;number&gt;, &lt;number&gt;)</code>
dschulze@5690 2853
dschulze@5690 2854 <dd> for <code class=css>scaleX(&lt;number&gt;)</code>, <code
dschulze@5690 2855 class=css>scaleY(&lt;number&gt;)</code>, <code
dschulze@5690 2856 class=css>scaleZ(&lt;number&gt;)</code> and <code
dschulze@6299 2857 class=css>scale(&lt;number&gt;[, &lt;number&gt;])</code>.
dschulze@6402 2858
dschulze@6402 2859 <dt id=rotate3d-primitive> <code class=css>rotate3d(&lt;number&gt;,
bert@6706 2860 &lt;number&gt;, &lt;number&gt;, &lt;angle&gt;)</code>
dschulze@6402 2861
dschulze@6402 2862 <dd> for <code class=css>rotate(&lt;number&gt;)</code>, <code
dschulze@6402 2863 class=css>rotateX(&lt;number&gt;)</code>, <code
dschulze@6402 2864 class=css>rotateY(&lt;number&gt;)</code> and <code
dschulze@6402 2865 class=css>rotateZ(&lt;number&gt;)</code>.
dschulze@5690 2866 </dl>
dschulze@5690 2867
dschulze@5743 2868 <p id=interpolation-two-three-dimensional-function> For derived transform
dschulze@5743 2869 functions that have a two-dimensional primitive and a three-dimensional
dschulze@5743 2870 primitive, the context decides about the used primitive. See <a
dschulze@5690 2871 href="#interpolation-of-transform-functions">Interpolation of primitives
dschulze@6402 2872 and derived transform functions</a>.</p>
dschulze@5892 2873 <!-- ======================================================================================================= -->
dschulze@5892 2874
dschulze@5895 2875 <h2 id=interpolation-of-transform-functions><span class=secno>19. </span>
dschulze@5892 2876 Interpolation of primitives and derived transform functions</h2>
dschulze@5690 2877
dschulze@6402 2878 <p> Two transform functions with the same name and the same number of
dschulze@6402 2879 arguments are interpolated numerically without a former conversion. The
dschulze@6402 2880 calculated value will be of the same transform function type with the same
dschulze@6402 2881 number of arguments. Special rules apply to ‘<code
dschulze@6402 2882 class=css>rotate3d</code>’, ‘<code class=css>matrix</code>’,
dschulze@6402 2883 ‘<code class=css>matrix3d</code>’ and ‘<a href="#perspective"><code
dschulze@6402 2884 class=css>perspective</code></a>’.
dschulze@5690 2885
dschulze@5690 2886 <div class=example>
dschulze@5892 2887 <p> The two transform functions ‘<code class=css>translate(0)</code>’
dschulze@5892 2888 and ‘<code class=css>translate(100px)</code>’ are of the same type,
dschulze@5892 2889 have the same number of arguments and therefore can get interpolated
dschulze@5892 2890 numerically. ‘<code class=css>translateX(100px)</code>’ is not of the
dschulze@5892 2891 same type and ‘<code class=css>translate(100px, 0)</code>’ does not
dschulze@5892 2892 have the same number of arguments, therefore these transform functions
bert@6706 2893 can not get interpolated without a former conversion step.
dschulze@5690 2894 </div>
dschulze@5690 2895
dschulze@5690 2896 <p> Two different types of transform functions that share the same
dschulze@5690 2897 primitive, or transform functions of the same type with different number
dschulze@5690 2898 of arguments can be interpolated. Both transform functions need a former
dschulze@5690 2899 conversion to the common primitive first and get interpolated numerically
dschulze@5690 2900 afterwards. The computed value will be the primitive with the resulting
dschulze@5690 2901 interpolated arguments.
dschulze@5690 2902
dschulze@5690 2903 <div class=example>
dschulze@5892 2904 <p> The following example describes a transition from ‘<code
dschulze@5892 2905 class=css>translateX(100px)</code>’ to ‘<code
dschulze@5892 2906 class=css>translateY(100px)</code>’ in 3 seconds on hovering over the
dschulze@5892 2907 div box. Both transform functions derive from the same primitive <code
dschulze@5892 2908 class=css>translate(&lt;translation-value&gt;,
bert@6706 2909 &lt;translation-value&gt;)</code> and therefore can be interpolated.
dschulze@5690 2910
dschulze@5690 2911 <pre>div {
dschulze@5690 2912 transform: translateX(100px);
dschulze@5690 2913 }
dschulze@5690 2914
dschulze@5690 2915 div:hover {
dschulze@5690 2916 transform: translateY(100px);
dschulze@5690 2917 transition: transform 3s;
dschulze@5690 2918 }</pre>
dschulze@5690 2919
dschulze@5690 2920 <p> For the time of the transition both transform functions get
dschulze@5892 2921 transformed to the common primitive. ‘<code
dschulze@5892 2922 class=css>translateX(100px)</code>’ gets converted to ‘<code
dschulze@5892 2923 class=css>translate(100px, 0)</code>’ and ‘<code
dschulze@5892 2924 class=css>translateY(100px)</code>’ gets converted to ‘<code
dschulze@5892 2925 class=css>translate(0, 100px)</code>’. Both transform functions can
bert@6706 2926 then get interpolated numerically.
dschulze@5690 2927 </div>
dschulze@5690 2928
dschulze@5690 2929 <p> If both transform functions share a primitive in the two-dimensional
dschulze@5690 2930 space, both transform functions get converted to the two-dimensional
dschulze@5690 2931 primitive. If one or both transform functions are three-dimensional
dschulze@5690 2932 transform functions, the common three-dimensional primitive is used.
dschulze@5690 2933
dschulze@5690 2934 <div class=example>
dschulze@5690 2935 <p> In this example a two-dimensional transform function gets animated to
dschulze@5690 2936 a three-dimensional transform function. The common primitive is <code
bert@6706 2937 class=css>translate3d</code>.
dschulze@5690 2938
dschulze@5690 2939 <pre>div {
dschulze@5690 2940 transform: translateX(100px);
dschulze@5690 2941 }
dschulze@5690 2942
dschulze@5690 2943 div:hover {
dschulze@5690 2944 transform: translateZ(100px);
dschulze@5690 2945 transition: transform 3s;
dschulze@5690 2946 }</pre>
dschulze@5690 2947
dschulze@5892 2948 <p> First ‘<code class=css><code
dschulze@5892 2949 class=css>translateX(100px)</code></code>’ gets converted to ‘<code
dschulze@5892 2950 class=css><code class=css>translate3d(100px, 0, 0)</code></code>’ and
dschulze@5892 2951 ‘<code class=css><code class=css>translateZ(100px)</code></code>’ to
dschulze@5892 2952 ‘<code class=css><code class=css>translate3d(0, 0,
dschulze@5892 2953 100px)</code></code>’ respectively. Then both converted transform
bert@6706 2954 functions get interpolated numerically.
dschulze@5690 2955 </div>
dschulze@6299 2956
dschulze@6607 2957 <p> The transform functions ‘<code class=css>matrix</code>’, ‘<code
dschulze@6607 2958 class=css>matrix3d</code>’ and ‘<a href="#perspective"><code
dschulze@6607 2959 class=css>perspective</code></a>’ get converted into 4x4 matrices first
dschulze@6607 2960 and interpolated as defined in section <a
dschulze@6607 2961 href="#matrix-interpolation">Interpolation of Matrices</a> afterwards.
dschulze@6607 2962
dschulze@6607 2963 <p> For interpolatations with the primitive ‘<code
dschulze@6607 2964 class=css>rotate3d</code>’, the direction vectors of the transform
dschulze@6607 2965 functions get normalized first. If the normalized vectors are equal, the
dschulze@6607 2966 rotation angle gets interpolated numerically. Otherwise the transform
dschulze@6607 2967 functions get converted into 4x4 matrices first and interpolated as
dschulze@6607 2968 defined in section <a href="#matrix-interpolation">Interpolation of
dschulze@6607 2969 Matrices</a> afterwards.</p>
dschulze@5690 2970 <!-- ======================================================================================================= -->
dschulze@5690 2971
dschulze@5895 2972 <h2 id=matrix-interpolation><span class=secno>20. </span> Interpolation of
dschulze@5892 2973 Matrices</h2>
dschulze@5892 2974
dschulze@5892 2975 <p> When interpolating between two matrices, each is decomposed into the
simon@5276 2976 corresponding translation, rotation, scale, skew and perspective values.
simon@5276 2977 Not all matrices can be accurately described by these values. Those that
simon@5276 2978 can't are decomposed into the most accurate representation possible, using
bert@6706 2979 the pseudocode in <a href="#matrix-decomposing">Decomposing the
bert@6706 2980 Matrix</a>. The resulting values get <a
bert@6706 2981 href="#matrix-values-interpolation">interpolated numerically</a> and <a
bert@6706 2982 href="#matrix-recomposing">recomposed back to a matrix</a> in a final
bert@6706 2983 step.
dschulze@5892 2984
dschulze@5902 2985 <div class=note>
dschulze@5902 2986 <p> In the following example the element gets translated by 100 pixel in
dschulze@5902 2987 both the X and Y directions and rotated by 1170 degree on hovering. The
dschulze@5902 2988 initial transformation is 45 degree. With the usage of transition, an
dschulze@5902 2989 author might expect a animated, clockwise rotation by three and a quarter
bert@6706 2990 turn (1170 degree).
dschulze@5902 2991
dschulze@5902 2992 <pre>
dschulze@5902 2993 &lt;style&gt;
dschulze@5902 2994 div {
dschulze@5902 2995 transform: rotate(45deg);
dschulze@5902 2996 }
dschulze@5902 2997 div:hover {
dschulze@5902 2998 transform: translate(100px, 100px) rotate(1215deg);
dschulze@5902 2999 transition: transform 3s;
dschulze@5902 3000 }
dschulze@5902 3001 &lt;/style&gt;
dschulze@5902 3002
dschulze@5902 3003 &lt;div&gt;&lt;/div&gt;</pre>
dschulze@5902 3004
dschulze@5902 3005 <p> The number of transform functions on the source transform ‘<code
dschulze@5902 3006 class=css>rotate(45deg)</code>’ differs from the number of transform
dschulze@5902 3007 functions on the destination transform ‘<code
dschulze@5902 3008 class=css>translate(100px, 100px) rotate(1125deg)</code>’. According to
dschulze@5902 3009 the last rule of <a href="#animation">Interpolation of Transforms</a>,
dschulze@5902 3010 both transforms must be interpolated by matrix interpolation. With
dschulze@5902 3011 converting the transformation functions to matrices, the information
dschulze@5902 3012 about the three turns gets lost and the element gets rotated by just a
bert@6706 3013 quarter turn (90 degree).
dschulze@5902 3014
dschulze@5902 3015 <p> To achieve the three and a quarter turns for the example above, source
dschulze@5902 3016 and destination transforms must fulfill the third rule of <a
dschulze@5902 3017 href="#animation">Interpolation of Transforms</a>. Source transform could
dschulze@5902 3018 look like ‘<code class=css>translate(0, 0) rotate(45deg)</code>’ for
bert@6706 3019 a linearly interpolation of the transform functions.
dschulze@5902 3020 </div>
dschulze@5902 3021
dschulze@5903 3022 <p> If one of the matrices for interpolation is non-invertible, the used
dschulze@5903 3023 animation function must fallback to a discrete animation according to the
dschulze@5903 3024 rules of the respective animation specification.
dschulze@5903 3025
dschulze@5895 3026 <h3 id=matrix-decomposing><span class=secno>20.1. </span>Decomposing the
dschulze@5892 3027 Matrix</h3>
dschulze@5892 3028
dschulze@5892 3029 <p> The pseudocode below is based upon the "unmatrix" method in "Graphics
dschulze@5892 3030 Gems II, edited by Jim Arvo", but modified to use Quaternions instead of
dschulze@5892 3031 Euler angles to avoid the problem of Gimbal Locks.
dschulze@5892 3032
dschulze@5892 3033 <p> The following pseudocode works on a 4x4 homogeneous matrix:
simon@5276 3034
simon@5276 3035 <pre>
dschulze@5892 3036 Input: matrix ; a 4x4 matrix
dschulze@5892 3037 Output: translation ; a 3 component vector
dschulze@5892 3038 scale ; a 3 component vector
dschulze@5892 3039 skew ; skew factors XY,XZ,YZ represented as a 3 component vector
dschulze@5892 3040 perspective ; a 4 component vector
dschulze@5892 3041 quaternion ; a 4 component vector
dschulze@5892 3042 Returns false if the matrix cannot be decomposed, true if it can
dschulze@5892 3043
dschulze@5892 3044 Supporting functions (point is a 3 component vector, matrix is a 4x4 matrix):
dschulze@5892 3045 double determinant(matrix) returns the 4x4 determinant of the matrix
dschulze@5892 3046 matrix inverse(matrix) returns the inverse of the passed matrix
dschulze@5892 3047 matrix transpose(matrix) returns the transpose of the passed matrix
dschulze@5892 3048 point multVecMatrix(point, matrix) multiplies the passed point by the passed matrix
dschulze@5892 3049 and returns the transformed point
dschulze@5892 3050 double length(point) returns the length of the passed vector
dschulze@5892 3051 point normalize(point) normalizes the length of the passed point to 1
dschulze@5892 3052 double dot(point, point) returns the dot product of the passed points
dschulze@5892 3053 double sqrt(double) returns the root square of passed value
dschulze@5892 3054 double max(double y, double x) returns the bigger value of the two passed values
dschulze@5892 3055
dschulze@5892 3056 Decomposition also makes use of the following function:
dschulze@5892 3057 point combine(point a, point b, double ascl, double bscl)
dschulze@5892 3058 result[0] = (ascl * a[0]) + (bscl * b[0])
dschulze@5892 3059 result[1] = (ascl * a[1]) + (bscl * b[1])
dschulze@5892 3060 result[2] = (ascl * a[2]) + (bscl * b[2])
dschulze@5892 3061 return result
dschulze@5892 3062
dschulze@5892 3063 // Normalize the matrix.
dschulze@5892 3064 if (matrix[3][3] == 0)
dschulze@5892 3065 return false
dschulze@5892 3066
dschulze@5892 3067 for (i = 0; i < 4; i++)
dschulze@5892 3068 for (j = 0; j < 4; j++)
dschulze@5892 3069 matrix[i][j] /= matrix[3][3]
dschulze@5892 3070
dschulze@5892 3071 // perspectiveMatrix is used to solve for perspective, but it also provides
dschulze@5892 3072 // an easy way to test for singularity of the upper 3x3 component.
dschulze@5892 3073 perspectiveMatrix = matrix
dschulze@5892 3074
dschulze@5892 3075 for (i = 0; i < 3; i++)
dschulze@5892 3076 perspectiveMatrix[i][3] = 0
dschulze@5892 3077
dschulze@5892 3078 perspectiveMatrix[3][3] = 1
dschulze@5892 3079
dschulze@5892 3080 if (determinant(perspectiveMatrix) == 0)
dschulze@5892 3081 return false
dschulze@5892 3082
dschulze@5892 3083 // First, isolate perspective.
dschulze@5892 3084 if (matrix[0][3] != 0 || matrix[1][3] != 0 || matrix[2][3] != 0)
dschulze@5892 3085 // rightHandSide is the right hand side of the equation.
dschulze@5892 3086 rightHandSide[0] = matrix[0][3];
dschulze@5892 3087 rightHandSide[1] = matrix[1][3];
dschulze@5892 3088 rightHandSide[2] = matrix[2][3];
dschulze@5892 3089 rightHandSide[3] = matrix[3][3];
dschulze@5892 3090
dschulze@5892 3091 // Solve the equation by inverting perspectiveMatrix and multiplying
dschulze@5892 3092 // rightHandSide by the inverse.
dschulze@5892 3093 inversePerspectiveMatrix = inverse(perspectiveMatrix)
dschulze@5892 3094 transposedInversePerspectiveMatrix = transposeMatrix4(inversePerspectiveMatrix)
dschulze@5892 3095 perspective = multVecMatrix(rightHandSide, transposedInversePerspectiveMatrix)
dschulze@5892 3096 else
dschulze@5892 3097 // No perspective.
dschulze@5892 3098 perspective[0] = perspective[1] = perspective[2] = 0
dschulze@5892 3099 perspective[3] = 1
dschulze@5892 3100
dschulze@5892 3101 // Next take care of translation
dschulze@5892 3102 for (i = 0; i < 3; i++)
dschulze@5892 3103 translate[i] = matrix[3][i]
dschulze@5892 3104
dschulze@5892 3105 // Now get scale and shear. 'row' is a 3 element array of 3 component vectors
dschulze@5892 3106 for (i = 0; i < 3; i++)
dschulze@5892 3107 row[i][0] = matrix[i][0]
dschulze@5892 3108 row[i][1] = matrix[i][1]
dschulze@5892 3109 row[i][2] = matrix[i][2]
dschulze@5892 3110
dschulze@5892 3111 // Compute X scale factor and normalize first row.
dschulze@5892 3112 scale[0] = length(row[0])
dschulze@5892 3113 row[0] = normalize(row[0])
dschulze@5892 3114
dschulze@5892 3115 // Compute XY shear factor and make 2nd row orthogonal to 1st.
dschulze@5892 3116 skew[0] = dot(row[0], row[1])
dschulze@5892 3117 row[1] = combine(row[1], row[0], 1.0, -skew[0])
dschulze@5892 3118
dschulze@5892 3119 // Now, compute Y scale and normalize 2nd row.
dschulze@5892 3120 scale[1] = length(row[1])
dschulze@5892 3121 row[1] = normalize(row[1])
dschulze@5892 3122 skew[0] /= scale[1];
dschulze@5892 3123
dschulze@5892 3124 // Compute XZ and YZ shears, orthogonalize 3rd row
dschulze@5892 3125 skew[1] = dot(row[0], row[2])
dschulze@5892 3126 row[2] = combine(row[2], row[0], 1.0, -skew[1])
dschulze@5892 3127 skew[2] = dot(row[1], row[2])
dschulze@5892 3128 row[2] = combine(row[2], row[1], 1.0, -skew[2])
dschulze@5892 3129
dschulze@5892 3130 // Next, get Z scale and normalize 3rd row.
dschulze@5892 3131 scale[2] = length(row[2])
dschulze@5892 3132 row[2] = normalize(row[2])
dschulze@5892 3133 skew[1] /= scale[2]
dschulze@5892 3134 skew[2] /= scale[2]
dschulze@5892 3135
dschulze@5892 3136 // At this point, the matrix (in rows) is orthonormal.
dschulze@5892 3137 // Check for a coordinate system flip. If the determinant
dschulze@5892 3138 // is -1, then negate the matrix and the scaling factors.
dschulze@5892 3139 pdum3 = cross(row[1], row[2])
dschulze@5892 3140 if (dot(row[0], pdum3) < 0)
dschulze@5892 3141 for (i = 0; i < 3; i++)
dschulze@6881 3142 scale[i] *= -1;
dschulze@5892 3143 row[i][0] *= -1
dschulze@5892 3144 row[i][1] *= -1
dschulze@5892 3145 row[i][2] *= -1
dschulze@5892 3146
dschulze@5892 3147 // Now, get the rotations out
dschulze@5892 3148 quaternion[0] = 0.5 * sqrt(max(1 + row[0][0] - row[1][1] - row[2][2], 0))
dschulze@5892 3149 quaternion[1] = 0.5 * sqrt(max(1 - row[0][0] + row[1][1] - row[2][2], 0))
dschulze@5892 3150 quaternion[2] = 0.5 * sqrt(max(1 - row[0][0] - row[1][1] + row[2][2], 0))
dschulze@5892 3151 quaternion[3] = 0.5 * sqrt(max(1 + row[0][0] + row[1][1] + row[2][2], 0))
dschulze@5892 3152
dschulze@5892 3153 if (row[2][1] > row[1][2])
dschulze@5892 3154 quaternion[0] = -quaternion[0]
dschulze@5892 3155 if (row[0][2] > row[2][0])
dschulze@5892 3156 quaternion[1] = -quaternion[1]
dschulze@5892 3157 if (row[1][0] > row[0][1])
dschulze@5892 3158 quaternion[2] = -quaternion[2]
dschulze@5892 3159
dschulze@5892 3160 return true</pre>
dschulze@5892 3161
dschulze@5895 3162 <h3 id=matrix-values-interpolation><span class=secno>20.2. </span>
dschulze@5892 3163 Interpolation of decomposed matrix values</h3>
dschulze@5892 3164
dschulze@5892 3165 <p> Each component of the decomposed values translation, scale, skew and
dschulze@5892 3166 perspective of the source matrix get linearly interpolated with each
dschulze@5892 3167 corresponding component of the destination matrix.
dschulze@5892 3168
dschulze@5892 3169 <p class=note> For instance, <code>translate[0]</code> of the source matrix
dschulze@5892 3170 and <code>translate[0]</code> of the destination matrix are interpolated
dschulze@5892 3171 numerically, and the result is used to set the translation of the
dschulze@5892 3172 animating element.
dschulze@5892 3173
dschulze@5892 3174 <p> Quaternions of the decomposed source matrix are interpolated with
dschulze@5892 3175 quaternions of the decomposed destination matrix using the spherical
dschulze@5892 3176 linear interpolation (Slerp) as described by the pseudocode below:
simon@5276 3177
simon@5276 3178 <pre>
dschulze@5892 3179 Input: quaternionA ; a 4 component vector
dschulze@5892 3180 quaternionB ; a 4 component vector
dschulze@5892 3181 t ; interpolation parameter with 0 <= t <= 1
dschulze@5892 3182 Output: quaternionDst ; a 4 component vector
dschulze@5892 3183
dschulze@5892 3184 Supporting functions (vector is a 4 component vector):
dschulze@5892 3185 double dot(vector, vector) returns the dot product of the passed vectors
dschulze@5892 3186 vector multVector(vector, vector) multiplies the passed vectors
dschulze@5892 3187 double sqrt(double) returns the root square of passed value
dschulze@5892 3188 double max(double y, double x) returns the bigger value of the two passed values
dschulze@5892 3189 double min(double y, double x) returns the smaller value of the two passed values
dschulze@5892 3190 double cos(double) returns the cosines of passed value
dschulze@5892 3191 double sin(double) returns the sine of passed value
dschulze@5895 3192 double acos(double) returns the inverse cosine of passed value
dschulze@5892 3193
dschulze@5892 3194
dschulze@5892 3195 product = dot(quaternionA, quaternionB)
dschulze@5892 3196
dschulze@5892 3197 // Clamp product to -1.0 <= product <= 1.0
dschulze@5892 3198 product = max(product, 1.0)
dschulze@5892 3199 product = min(product, -1.0)
dschulze@5892 3200
dschulze@5892 3201 if (product == 1.0)
dschulze@5892 3202 quaternionDst = quaternionA
dschulze@5892 3203 return
dschulze@5892 3204
dschulze@5892 3205 theta = acos(dot)
dschulze@5892 3206 w = sin(t * theta) * 1 / sqrt(1 - product * product)
dschulze@5892 3207
dschulze@5892 3208 for (i = 0; i < 4; i++)
dschulze@5892 3209 quaternionA[i] *= cos(t * theta) - product * w
dschulze@5892 3210 quaternionB[i] *= w
dschulze@5892 3211 quaternionDst[i] = quaternionA[i] + quaternionB[i]
dschulze@5892 3212
dschulze@5892 3213 return</pre>
dschulze@5892 3214
dschulze@5895 3215 <h3 id=matrix-recomposing><span class=secno>20.3. </span> Recomposing the
dschulze@5892 3216 Matrix</h3>
dschulze@5892 3217
dschulze@5892 3218 <p> After interpolation the resulting values are used to transform the
dschulze@5892 3219 elements user space. One way to use these values is to recompose them into
dschulze@5892 3220 a 4x4 matrix. This can be done following the pseudocode below:
dschulze@5892 3221
dschulze@5892 3222 <pre>
dschulze@5892 3223 Input: translation ; a 3 component vector
dschulze@5892 3224 scale ; a 3 component vector
dschulze@5892 3225 skew ; skew factors XY,XZ,YZ represented as a 3 component vector
dschulze@5892 3226 perspective ; a 4 component vector
dschulze@5892 3227 quaternion ; a 4 component vector
dschulze@5892 3228 Output: matrix ; a 4x4 matrix
dschulze@5892 3229
dschulze@5892 3230 Supporting functions (matrix is a 4x4 matrix):
dschulze@5892 3231 matrix multiply(matrix a, matrix b) returns the 4x4 matrix product of a * b
dschulze@5892 3232
dschulze@5892 3233 // apply perspective
dschulze@5892 3234 for (i = 0; i < 4; i++)
dschulze@5892 3235 matrix[i][3] = perspective[i]
dschulze@5892 3236
dschulze@5892 3237 // apply translation
dschulze@5892 3238 for (i = 0; i < 3; i++)
dschulze@5892 3239 for (j = 0; j < 3; j++)
dschulze@5892 3240 matrix[3][i] += translation[j] * matrix[j][i]
dschulze@5892 3241
dschulze@5892 3242 // apply rotation
dschulze@5892 3243 x = quaternion[0]
dschulze@5892 3244 y = quaternion[1]
dschulze@5892 3245 z = quaternion[2]
dschulze@5892 3246 w = quaternion[3]
dschulze@5892 3247
dschulze@5892 3248 // Construct a composite rotation matrix from the quaternion values
dschulze@5892 3249 // rotationMatrix is a identity 4x4 matrix initially
dschulze@5892 3250 rotationMatrix[0][0] = 1 - 2 * (y * y + z * z)
dschulze@5892 3251 rotationMatrix[0][1] = 2 * (x * y - z * w)
dschulze@5892 3252 rotationMatrix[0][2] = 2 * (x * z + y * w)
dschulze@5892 3253 rotationMatrix[1][0] = 2 * (x * y + z * w)
dschulze@5892 3254 rotationMatrix[1][1] = 1 - 2 * (x * x + z * z)
dschulze@5892 3255 rotationMatrix[1][2] = 2 * (y * z - x * w)
dschulze@5892 3256 rotationMatrix[2][0] = 2 * (x * z - y * w)
dschulze@5892 3257 rotationMatrix[2][1] = 2 * (y * z + x * w)
dschulze@5892 3258 rotationMatrix[2][2] = 1 - 2 * (x * x + y * y)
dschulze@5892 3259
dschulze@5892 3260 matrix = multiply(matrix, rotationMatrix)
dschulze@5892 3261
dschulze@5892 3262 // apply skew
dschulze@5892 3263 // temp is a identity 4x4 matrix initially
dschulze@5892 3264 if (skew[2])
dschulze@5892 3265 temp[2][1] = skew[2]
dschulze@5892 3266 matrix = multiply(matrix, temp)
dschulze@5892 3267
dschulze@5892 3268 if (skew[1])
dschulze@5892 3269 temp[2][1] = 0
dschulze@5892 3270 temp[2][0] = skew[1]
dschulze@5892 3271 matrix = multiply(matrix, temp)
dschulze@5892 3272
dschulze@5892 3273 if (skew[0])
dschulze@5892 3274 temp[2][0] = 0
dschulze@5892 3275 temp[1][0] = skew[0]
dschulze@5892 3276 matrix = multiply(matrix, temp)
dschulze@5892 3277
dschulze@5892 3278 // apply scale
dschulze@5892 3279 for (i = 0; i < 3; i++)
dschulze@5892 3280 for (j = 0; j < 3; j++)
dschulze@5892 3281 matrix[i][j] *= scale[i]
dschulze@5892 3282
dschulze@5892 3283 return</pre>
dschulze@5892 3284
dschulze@5895 3285 <h2 id=mathematical-description><span class=secno>21. </span> Mathematical
simon@5276 3286 Description of Transform Functions</h2>
simon@5276 3287
simon@5276 3288 <p> Mathematically, all transform functions can be represented as 4x4
simon@5276 3289 transformation matrices of the following form:
simon@5276 3290
bert@6706 3291 <p> <img
simon@5276 3292 alt="\begin{bmatrix} m11 & m21 & m31 & m41 \\ m12 & m22 & m32 & m42 \\ m13 & m23 & m33 & m43 \\ m14 & m24 & m34 & m44 \end{bmatrix}"
simon@5276 3293 height=106 src=4x4matrix.png width=222>
simon@5276 3294
dschulze@6929 3295 <p> One translation unit on a matrix is equivalent to 1 pixel in the local
dschulze@6921 3296 coordinate system of the element.
dschulze@6921 3297
simon@5276 3298 <ul>
simon@5276 3299 <li id=MatrixDefined>
simon@5276 3300 <p> A 2D 3x2 matrix with six parameters <em>a</em>, <em>b</em>,
dschulze@6607 3301 <em>c</em>, <em>d</em>, <em>e</em> and <em>f</em> is equivalent to the
dschulze@6607 3302 matrix:</p>
simon@5276 3303 <img
simon@5276 3304 alt="\begin{bmatrix} a & c & 0 & e \\ b & d & 0 & f \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}"
simon@5276 3305 height=106 src=matrix.png width=108>
simon@5276 3306
simon@5276 3307 <li id=TranslateDefined>
simon@5276 3308 <p> A 2D translation with the parameters <em>tx</em> and <em>ty</em> is
simon@5276 3309 equivalent to a <a href="#Translate3dDefined">3D translation</a> where
bert@6706 3310 <em>tz</em> has zero as a value.
simon@5276 3311
simon@5276 3312 <li id=ScaleDefined>
simon@5276 3313 <p> A 2D scaling with the parameters <em>sx</em> and <em>sy</em> is
simon@5276 3314 equivalent to a <a href="#Scale3dDefined">3D scale</a> where <em>sz</em>
bert@6706 3315 has one as a value.
simon@5276 3316
simon@5276 3317 <li id=RotateDefined>
simon@5276 3318 <p> A 2D rotation with the parameter <em>alpha</em> is equivalent to a <a
simon@5276 3319 href="#Rotate3dDefined">3D rotation</a> with vector [0,0,1] and
bert@6706 3320 parameter <em>alpha</em>.
simon@5276 3321
dschulze@6608 3322 <li id=SkewDefined>
dschulze@6608 3323 <p> A 2D skew like transformation with the parameters <em>alpha</em> and
dschulze@6608 3324 <em>beta</em> is equivalent to the matrix:</p>
dschulze@6608 3325 <img
dschulze@6608 3326 alt="\begin{bmatrix} 1 & \tan(\alpha) & 0 & 0 \\ \tan(\beta) & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}"
dschulze@6608 3327 height=106 src=skew.png width=205>
dschulze@6608 3328
simon@5276 3329 <li id=SkewXDefined>
simon@5276 3330 <p> A 2D skew transformation along the X axis with the parameter
simon@5276 3331 <em>alpha</em> is equivalent to the matrix:</p>
simon@5276 3332 <img
simon@5276 3333 alt="\begin{bmatrix} 1 & \tan(\alpha) & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}"
simon@5276 3334 height=106 src=skewX.png width=155>
simon@5276 3335
simon@5276 3336 <li id=SkewYDefined>
simon@5276 3337 <p> A 2D skew transformation along the Y axis with the parameter
simon@5276 3338 <em>beta</em> is equivalent to the matrix:</p>
simon@5276 3339 <img
simon@5276 3340 alt="\begin{bmatrix} 1 & 0 & 0 & 0 \\ \tan(\beta) & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}"
simon@5276 3341 height=106 src=skewY.png width=155>
simon@5276 3342
simon@5276 3343 <li id=Translate3dDefined>
simon@5276 3344 <p> A 3D translation with the parameters <em>tx</em>, <em>ty</em> and
simon@5276 3345 <em>tz</em> is equivalent to the matrix:</p>
simon@5276 3346 <img
simon@5276 3347 alt="\begin{bmatrix} 1 & 0 & 0 & tx \\ 0 & 1 & 0 & ty \\ 0 & 0 & 1 & tz \\ 0 & 0 & 0 & 1 \end{bmatrix}"
simon@5276 3348 height=106 src=translate3d.png width=114>
simon@5276 3349
simon@5276 3350 <li id=Scale3dDefined>
simon@5276 3351 <p> A 3D scaling with the parameters <em>sx</em>, <em>sy</em> and
simon@5276 3352 <em>sz</em> is equivalent to the matrix:</p>
simon@5276 3353 <img
simon@5276 3354 alt="\begin{bmatrix} sx & 0 & 0 & 0 \\ 0 & sy & 0 & 0 \\ 0 & 0 & sz & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}"
simon@5276 3355 height=106 src=scale3d.png width=137>
simon@5276 3356
simon@5276 3357 <li id=Rotate3dDefined>
simon@5276 3358 <p> A 3D rotation with the vector [x,y,z] and the parameter
simon@5276 3359 <em>alpha</em> is equivalent to the matrix:</p>
simon@5276 3360 <img
simon@5276 3361 alt="\begin{bmatrix} 1 - 2 \cdot (y^2 + z^2) \cdot sq & 2 \cdot (x \cdot y \cdot sq - z \cdot sc) & 2 \cdot (x \cdot z \cdot sq + y \cdot sc) & 0 \\ 2 \cdot (x \cdot y \cdot sq + z \cdot sc) & 1 - 2 \cdot (x^2 + z^2) \cdot sq & 2 \cdot (y \cdot z \cdot sq - x \cdot sc) & 0 \\ 2 \cdot (x \cdot z \cdot sq - y \cdot sc) & 2 \cdot (y \cdot z \cdot sq + x \cdot sc) & 1 - 2 \cdot (x^2 + y^2) \cdot sq & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}"
simon@5276 3362 height=106 src=rotate3dmatrix.png width=647>
simon@5276 3363 <p> where:</p>
simon@5276 3364 <img
simon@5276 3365 alt="\newline sc = \sin (\alpha/2) \cdot \cos (\alpha/2) \newline sq = \sin^2 (\alpha/2)"
simon@5276 3366 height=50 src=rotate3dvariables.png width=221>
simon@5276 3367
simon@5276 3368 <li id=PerspectiveDefined>
simon@5276 3369 <p> A perspective projection matrix with the parameter <em>d</em> is
simon@5276 3370 equivalent to the matrix:</p>
simon@5276 3371 <img
simon@5276 3372 alt="\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & -1/d & 1 \end{bmatrix}"
simon@5276 3373 height=106 src=perspective.png width=143>
simon@5276 3374 </ul>
simon@5276 3375
dschulze@5895 3376 <h2 id=references><span class=secno>22. </span>References</h2>
simon@5276 3377
simon@5276 3378 <h3 class=no-num id=normative-references>Normative references</h3>
simon@5276 3379 <!--begin-normative-->
simon@5276 3380 <!-- Sorted by label -->
simon@5276 3381
simon@5276 3382 <dl class=bibliography>
simon@5276 3383 <dt style="display: none"><!-- keeps the doc valid if the DL is empty -->
simon@5276 3384 <!---->
simon@5276 3385
simon@5276 3386 <dt id=CSS21>[CSS21]
simon@5276 3387
simon@5276 3388 <dd>Bert Bos; et al. <a
dbaron@7338 3389 href="http://www.w3.org/TR/2011/REC-CSS2-20110607/"><cite>Cascading Style
dschulze@5892 3390 Sheets Level 2 Revision 1 (CSS 2.1) Specification.</cite></a> 7 June
simon@5276 3391 2011. W3C Recommendation. URL: <a
dbaron@7338 3392 href="http://www.w3.org/TR/2011/REC-CSS2-20110607/">http://www.w3.org/TR/2011/REC-CSS2-20110607/</a>
bert@6706 3393 </dd>
simon@5276 3394 <!---->
simon@6214 3395
simon@6214 3396 <dt id=CSS3BG>[CSS3BG]
simon@6214 3397
simon@6214 3398 <dd>Bert Bos; Elika J. Etemad; Brad Kemper. <a
dschulze@6607 3399 href="http://www.w3.org/TR/2012/CR-css3-background-20120724/"><cite>CSS
dschulze@6607 3400 Backgrounds and Borders Module Level 3.</cite></a> 24 July 2012. W3C
simon@6214 3401 Candidate Recommendation. (Work in progress.) URL: <a
dschulze@6607 3402 href="http://www.w3.org/TR/2012/CR-css3-background-20120724/">http://www.w3.org/TR/2012/CR-css3-background-20120724/</a>
bert@6706 3403 </dd>
simon@6214 3404 <!---->
eoconnor@6894 3405
eoconnor@6894 3406 <dt id=SVG11>[SVG11]
eoconnor@6894 3407
eoconnor@6894 3408 <dd>Erik Dahlström; et al. <a
eoconnor@6894 3409 href="http://www.w3.org/TR/2011/REC-SVG11-20110816/"><cite>Scalable
eoconnor@6894 3410 Vector Graphics (SVG) 1.1 (Second Edition).</cite></a> 16 August 2011.
eoconnor@6894 3411 W3C Recommendation. URL: <a
eoconnor@6894 3412 href="http://www.w3.org/TR/2011/REC-SVG11-20110816/">http://www.w3.org/TR/2011/REC-SVG11-20110816/</a>
eoconnor@6894 3413 </dd>
eoconnor@6894 3414 <!---->
simon@5276 3415 </dl>
simon@5276 3416 <!--end-normative-->
simon@5276 3417
simon@5276 3418 <h3 class=no-num id=other-references>Other references</h3>
simon@5276 3419 <!--begin-informative-->
simon@5276 3420 <!-- Sorted by label -->
simon@5276 3421
simon@5276 3422 <dl class=bibliography>
simon@5276 3423 <dt style="display: none"><!-- keeps the doc valid if the DL is empty -->
simon@5276 3424 <!---->
simon@5276 3425
dschulze@5921 3426 <dt id=SMIL3>[SMIL3]
dschulze@5921 3427
dschulze@5921 3428 <dd>Dick Bulterman. <a
dschulze@5921 3429 href="http://www.w3.org/TR/2008/REC-SMIL3-20081201/"><cite>Synchronized
dschulze@5921 3430 Multimedia Integration Language (SMIL 3.0).</cite></a> 1 December 2008.
dschulze@5921 3431 W3C Recommendation. URL: <a
dschulze@5921 3432 href="http://www.w3.org/TR/2008/REC-SMIL3-20081201/">http://www.w3.org/TR/2008/REC-SMIL3-20081201/</a>
bert@6706 3433 </dd>
dschulze@5921 3434 <!---->
simon@5276 3435 </dl>
simon@5276 3436 <!--end-informative-->
simon@5276 3437
simon@5276 3438 <h2 class=no-num id=property-index>Property index</h2>
simon@5276 3439 <!--begin-properties-->
simon@5276 3440
simon@5276 3441 <table class=proptable>
simon@5276 3442 <thead>
simon@5276 3443 <tr>
dschulze@5580 3444 <th>Property
simon@5276 3445
simon@5276 3446 <th>Values
simon@5276 3447
simon@5276 3448 <th>Initial
simon@5276 3449
dschulze@5892 3450 <th>Applies to
simon@5276 3451
simon@5276 3452 <th>Inh.
simon@5276 3453
simon@5276 3454 <th>Percentages
simon@5276 3455
simon@5276 3456 <th>Media
simon@5276 3457
simon@5276 3458 <tbody>
simon@5276 3459 <tr>
simon@5276 3460 <th><a class=property
simon@5276 3461 href="#backface-visibility">backface-visibility</a>
simon@5276 3462
simon@5276 3463 <td>visible | hidden
simon@5276 3464
simon@5276 3465 <td>visible
simon@5276 3466
simon@5276 3467 <td>transformable elements
simon@5276 3468
simon@5276 3469 <td>no
simon@5276 3470
simon@5276 3471 <td>N/A
simon@5276 3472
simon@5276 3473 <td>visual
simon@5276 3474
simon@5276 3475 <tr>
dbaron@7338 3476 <th><a class=property href="#perspective">perspective</a>
dbaron@7338 3477
dbaron@7338 3478 <td>none | &lt;length&gt;
dbaron@7338 3479
dbaron@7338 3480 <td>none
dbaron@7338 3481
dbaron@7338 3482 <td>transformable elements
dbaron@7338 3483
dbaron@7338 3484 <td>no
dbaron@7338 3485
dbaron@7338 3486 <td>N/A
dbaron@7338 3487
dbaron@7338 3488 <td>visual
dbaron@7338 3489
dbaron@7338 3490 <tr>
simon@5276 3491 <th><a class=property href="#perspective-origin">perspective-origin</a>
simon@5276 3492
simon@5276 3493 <td>[ &lt;percentage> | &lt;length> | left | center | right | top |
dschulze@5892 3494 bottom] | [   [ &lt;percentage> | &lt;length&gt; | left | center |
dschulze@5892 3495 right ]   &amp;&amp;   [ &lt;percentage> | &lt;length&gt; | top |
dschulze@5892 3496 center | bottom ] ]
simon@5276 3497
simon@5276 3498 <td>50% 50%
simon@5276 3499
simon@5276 3500 <td>transformable elements
simon@5276 3501
simon@5276 3502 <td>no
simon@5276 3503
dschulze@7030 3504 <td>refer to the size of the bounding box
simon@5276 3505
simon@5276 3506 <td>visual
simon@5276 3507
simon@5276 3508 <tr>
dbaron@7338 3509 <th><a class=property href="#effects">transform</a>
dbaron@7338 3510
dbaron@7338 3511 <td>none | &lt;transform-function&gt; [ &lt;transform-function&gt; ]*
simon@5276 3512
simon@5276 3513 <td>none
simon@5276 3514
simon@5276 3515 <td>transformable elements
simon@5276 3516
simon@5276 3517 <td>no
simon@5276 3518
dbaron@7338 3519 <td>refer to the size of bounding box
simon@5276 3520
simon@5276 3521 <td>visual
simon@5276 3522
simon@5276 3523 <tr>
simon@5276 3524 <th><a class=property href="#transform-origin">transform-origin</a>
simon@5276 3525
simon@5276 3526 <td>[ &lt;percentage> | &lt;length> | left | center | right | top |
dschulze@5892 3527 bottom] | [   [ &lt;percentage> | &lt;length&gt; | left | center |
dschulze@5892 3528 right ]   &amp;&amp;   [ &lt;percentage> | &lt;length&gt; | top |
dschulze@5892 3529 center | bottom ] ] &lt;length&gt;?
simon@5276 3530
dschulze@5740 3531 <td>50% 50%
simon@5276 3532
simon@5276 3533 <td>transformable elements
simon@5276 3534
simon@5276 3535 <td>no
simon@5276 3536
dschulze@7030 3537 <td>refer to the size of bounding box
simon@5276 3538
simon@5276 3539 <td>visual
simon@5276 3540
simon@5276 3541 <tr>
simon@5276 3542 <th><a class=property href="#transform-style">transform-style</a>
simon@5276 3543
simon@5276 3544 <td>flat | preserve-3d
simon@5276 3545
simon@5276 3546 <td>flat
simon@5276 3547
simon@5276 3548 <td>transformable elements
simon@5276 3549
simon@5276 3550 <td>no
simon@5276 3551
simon@5276 3552 <td>N/A
simon@5276 3553
simon@5276 3554 <td>visual
simon@5276 3555 </table>
simon@5276 3556 <!--end-properties-->
simon@5276 3557
simon@5276 3558 <h2 class=no-num id=index>Index</h2>
simon@5276 3559 <!--begin-index-->
simon@5276 3560
simon@5276 3561 <ul class=indexlist>
simon@5276 3562 <li>3D rendering context, <a href="#d-rendering-context"
dbaron@7338 3563 title="section 4."><strong>4.</strong></a>
simon@5276 3564
simon@5276 3565 <li>accumulated 3D transformation matrix, <a
simon@5276 3566 href="#accumulated-3d-transformation-matrix"
dbaron@7338 3567 title="section 4."><strong>4.</strong></a>
simon@5276 3568
simon@5276 3569 <li>backface-visibility, <a href="#backface-visibility"
dbaron@7338 3570 title="section 12."><strong>12.</strong></a>
simon@5276 3571
dschulze@7030 3572 <li>‘<code class=css>bottom</code>’
dschulze@7030 3573 <ul>
dschulze@7030 3574 <li>‘<a href="#perspective-origin"><code
dschulze@7030 3575 class=property>perspective-origin</code></a>’ value, <a
dbaron@7338 3576 href="#bottom0" title="section 11."><strong>11.</strong></a>
dschulze@7030 3577
dschulze@7030 3578 <li>‘<a href="#transform-origin"><code
dschulze@7030 3579 class=property>transform-origin</code></a>’ value, <a href="#bottom"
dbaron@7338 3580 title="section 8."><strong>8.</strong></a>
dschulze@7030 3581 </ul>
dschulze@7030 3582
simon@5276 3583 <li>bounding box, <a href="#bounding-box"
dbaron@7338 3584 title="section 4."><strong>4.</strong></a>
simon@5276 3585
dschulze@7030 3586 <li>‘<code class=css>center</code>’
dschulze@7030 3587 <ul>
dschulze@7030 3588 <li>‘<a href="#perspective-origin"><code
dschulze@7030 3589 class=property>perspective-origin</code></a>’ value, <a
dbaron@7338 3590 href="#center0" title="section 11."><strong>11.</strong></a>
dschulze@7030 3591
dschulze@7030 3592 <li>‘<a href="#transform-origin"><code
dschulze@7030 3593 class=property>transform-origin</code></a>’ value, <a href="#center"
dbaron@7338 3594 title="section 8."><strong>8.</strong></a>
dschulze@7030 3595 </ul>
dschulze@7030 3596
dschulze@5931 3597 <li>current transformation matrix (CTM), <a
dschulze@5931 3598 href="#current-transformation-matrix-ctm"
dbaron@7338 3599 title="section 4."><strong>4.</strong></a>
dschulze@5931 3600
dschulze@5931 3601 <li>identity transform function, <a href="#identity-transform-function"
dbaron@7338 3602 title="section 4."><strong>4.</strong></a>
dschulze@5931 3603
dschulze@7030 3604 <li>‘<code class=css>left</code>’
dschulze@7030 3605 <ul>
dschulze@7030 3606 <li>‘<a href="#perspective-origin"><code
dschulze@7030 3607 class=property>perspective-origin</code></a>’ value, <a href="#left0"
dbaron@7338 3608 title="section 11."><strong>11.</strong></a>
dschulze@7030 3609
dschulze@7030 3610 <li>‘<a href="#transform-origin"><code
dschulze@7030 3611 class=property>transform-origin</code></a>’ value, <a href="#left"
dbaron@7338 3612 title="section 8."><strong>8.</strong></a>
dschulze@7030 3613 </ul>
dschulze@7030 3614
dschulze@5931 3615 <li>local coordinate system, <a href="#local-coordinate-system"
dbaron@7338 3616 title="section 4."><strong>4.</strong></a>
dschulze@5690 3617
simon@5276 3618 <li>perspective, <a href="#perspective"
dbaron@7338 3619 title="section 10."><strong>10.</strong></a>
simon@5276 3620
simon@5276 3621 <li>perspective matrix, <a href="#perspective-matrix"
dbaron@7338 3622 title="section 4."><strong>4.</strong></a>
simon@5276 3623
simon@5276 3624 <li>perspective-origin, <a href="#perspective-origin"
dbaron@7338 3625 title="section 11."><strong>11.</strong></a>
dschulze@5726 3626
dschulze@7030 3627 <li>‘<code class=css>right</code>’
dschulze@7030 3628 <ul>
dschulze@7030 3629 <li>‘<a href="#perspective-origin"><code
dschulze@7030 3630 class=property>perspective-origin</code></a>’ value, <a
dbaron@7338 3631 href="#right0" title="section 11."><strong>11.</strong></a>
dschulze@7030 3632
dschulze@7030 3633 <li>‘<a href="#transform-origin"><code
dschulze@7030 3634 class=property>transform-origin</code></a>’ value, <a href="#right"
dbaron@7338 3635 title="section 8."><strong>8.</strong></a>
dschulze@7030 3636 </ul>
dschulze@7030 3637
dschulze@7030 3638 <li>‘<code class=css>top</code>’
dschulze@7030 3639 <ul>
dschulze@7030 3640 <li>‘<a href="#perspective-origin"><code
dschulze@7030 3641 class=property>perspective-origin</code></a>’ value, <a href="#top0"
dbaron@7338 3642 title="section 11."><strong>11.</strong></a>
dschulze@7030 3643
dschulze@7030 3644 <li>‘<a href="#transform-origin"><code
dschulze@7030 3645 class=property>transform-origin</code></a>’ value, <a href="#top"
dbaron@7338 3646 title="section 8."><strong>8.</strong></a>
dschulze@7030 3647 </ul>
dschulze@7030 3648
dbaron@7338 3649 <li>transform, <a href="#effects"
dbaron@7338 3650 title="section 7."><strong>7.</strong></a>
simon@5276 3651
simon@5276 3652 <li>transformable element, <a href="#transformable-element"
dbaron@7338 3653 title="section 4."><strong>4.</strong></a>
simon@5276 3654
simon@5276 3655 <li>transformation matrix, <a href="#transformation-matrix"
dbaron@7338 3656 title="section 4."><strong>4.</strong></a>
simon@5276 3657
simon@5276 3658 <li>transform-origin, <a href="#transform-origin"
dbaron@7338 3659 title="section 8."><strong>8.</strong></a>
simon@5276 3660
simon@5276 3661 <li>transform-style, <a href="#transform-style"
dbaron@7338 3662 title="section 9."><strong>9.</strong></a>
dschulze@6300 3663
dschulze@6300 3664 <li>user coordinate system, <a href="#user-coordinate-system"
dbaron@7338 3665 title="section 4."><strong>4.</strong></a>
simon@5276 3666 </ul>
simon@5276 3667 <!--end-index-->
vhardy@3672 3668 </html>
simon@5276 3669 <!-- Keep this comment at the end of the file
simon@5276 3670 Local variables:
simon@5276 3671 mode: sgml
simon@5276 3672 sgml-declaration:"~/SGML/HTML4.decl"
simon@5276 3673 sgml-default-doctype-name:"html"
simon@5276 3674 sgml-minimize-attributes:t
simon@5276 3675 sgml-nofill-elements:("pre" "style" "br")
simon@5276 3676 sgml-live-element-indicator:t
simon@5276 3677 sgml-omittag:nil
simon@5276 3678 sgml-shorttag:nil
simon@5276 3679 sgml-namecase-general:t
simon@5276 3680 sgml-general-insert-case:lower
simon@5276 3681 sgml-always-quote-attributes:t
simon@5276 3682 sgml-indent-step:nil
simon@5276 3683 sgml-indent-data:t
simon@5276 3684 sgml-parent-document:nil
simon@5276 3685 sgml-exposed-tags:nil
simon@5276 3686 sgml-local-catalogs:nil
simon@5276 3687 sgml-local-ecat-files:nil
simon@5276 3688 End:
simon@5276 3689 -->

mercurial