Tue, 05 Feb 2013 13:50:38 -0700
[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 | <simon.fraser @apple.com> |
simon@5276 | 69 | |
simon@5276 | 70 | <dd>Dean Jackson (<a href="http://www.apple.com/">Apple Inc</a>) <dino |
dschulze@5892 | 71 | @apple.com> |
simon@5276 | 72 | |
simon@6214 | 73 | <dd>Edward O'Connor (<a href="http://www.apple.com/">Apple Inc</a>) |
simon@6214 | 74 | <eoconnor @apple.com> |
simon@6214 | 75 | |
simon@6214 | 76 | <dd>Dirk Schulze (<a href="http://www.adobe.com/">Adobe Systems, Inc</a>) |
simon@6214 | 77 | <dschulze @adobe.com> |
simon@6214 | 78 | |
simon@6214 | 79 | <dd>Aryeh Gregor (<a href="http://www.mozilla.org/">Mozilla</a>) <ayg |
simon@6214 | 80 | @aryeh.name> |
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>) <hyatt |
dschulze@5892 | 85 | @apple.com> |
simon@5276 | 86 | |
simon@5276 | 87 | <dd>Chris Marrin (<a href="http://www.apple.com/">Apple Inc</a>) |
dschulze@5892 | 88 | <cmarrin @apple.com> |
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&product=CSS&component=Transforms&resolution=---&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><translation-value></var> and |
dschulze@5751 | 246 | <var><length></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><angle></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><number></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 | <div style="transform: translate(80px, 80px)"> |
simon@5276 | 737 | <div style="transform: scale(1.5, 1.5)"> |
simon@5276 | 738 | <div style="transform: rotate(45deg)"></div> |
simon@5276 | 739 | </div> |
dschulze@5740 | 740 | </div></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 | <style> |
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 | </style> |
simon@5276 | 828 | |
simon@5276 | 829 | <div class="container"> |
simon@5276 | 830 | <div class="transformed"></div> |
simon@5276 | 831 | </div> |
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(<length>)</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 | <style> |
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 | </style> |
simon@5276 | 918 | |
simon@5276 | 919 | <div class="container"> |
simon@5276 | 920 | <div class="transformed"></div> |
simon@5276 | 921 | </div> |
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 | <style> |
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 | </style> |
simon@5276 | 980 | |
simon@5276 | 981 | <div class="container"> |
simon@5276 | 982 | <div class="transformed"> |
simon@5276 | 983 | <div class="child"></div> |
simon@5276 | 984 | </div> |
simon@5276 | 985 | </div> |
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 | <style> |
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 | </style> |
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 | <style> |
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 | </style> |
simon@5276 | 1132 | |
simon@5276 | 1133 | <div class="container"> |
simon@5276 | 1134 | <div></div> |
simon@5276 | 1135 | <div></div> |
simon@5276 | 1136 | </div> |
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> > 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> < 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> < 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 | < 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> > 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> < 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><style> |
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 | </style></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> < 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><style> |
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 | </style></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><style> |
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 | </style></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 < 0, so we need to slice away the part of the box with |
ayg@5901 | 1286 | <var>w</var> < 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> < 0. However, in that case the result of truncating the |
ayg@5901 | 1302 | <var>w</var> < 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 | <transform-function> [ <transform-function> ]* |
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> [ <percentage> | <length> | left | center | right | top | |
dschulze@5642 | 1390 | bottom]<br> |
dschulze@5642 | 1391 | |<br> |
dschulze@5642 | 1392 | [<br> |
dschulze@5892 | 1393 | [ <percentage> | <length> | left | center | right ]<br> |
dschulze@5892 | 1394 | &&<br> |
dschulze@5892 | 1395 | [ <percentage> | <length> | top | center | bottom ]<br> |
dschulze@5642 | 1396 | ] <length>?<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 <length> 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><length></var>. |
dschulze@5740 | 1459 | |
dschulze@7030 | 1460 | <dl> |
dschulze@7030 | 1461 | <dt><var><percentage></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><length></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 | <length> |
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> [ <percentage> | <length> | left | center | right | top | |
dschulze@5642 | 1696 | bottom]<br> |
dschulze@5642 | 1697 | |<br> |
dschulze@5642 | 1698 | [<br> |
dschulze@5892 | 1699 | [ <percentage> | <length> | left | center | right ]<br> |
dschulze@5892 | 1700 | &&<br> |
dschulze@5892 | 1701 | [ <percentage> | <length> | 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 <length> 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><percentage></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><length></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><svg xmlns="http://www.w3.org/2000/svg"> |
simon@5276 | 1973 | <style> |
simon@5276 | 1974 | .container { |
simon@5276 | 1975 | transform: translate(100px, 100px); |
simon@5276 | 1976 | } |
simon@5276 | 1977 | </style> |
simon@5276 | 1978 | |
simon@5276 | 1979 | <g class="container" transform="translate(200 200)"> |
simon@5276 | 1980 | <rect width="100" height="100" fill="blue" /> |
simon@5276 | 1981 | </g> |
simon@5276 | 1982 | </svg></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><translation-value></var> and <var><length></var> type</h5> |
simon@5276 | 2048 | |
simon@5276 | 2049 | <p> A translation-value or length can be a <var><number></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><angle></var> type</h5> |
simon@5276 | 2059 | |
simon@5276 | 2060 | <p> An angle can be a <var><number></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><number></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(<angle>)</code>’ is extended as follows: |
simon@5276 | 2098 | |
simon@5276 | 2099 | <dl> |
dschulze@5743 | 2100 | <dt id=rotate-three-function> <code class=css>rotate(<angle>[, |
dschulze@5743 | 2101 | <translation-value>, <translation-value>])</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><svg xmlns="http://www.w3.org/2000/svg"> |
simon@5276 | 2201 | <style> |
simon@5276 | 2202 | pattern { |
dschulze@5751 | 2203 | transform: rotate(45deg); |
simon@5276 | 2204 | transform-origin: 50% 50%; |
simon@5276 | 2205 | } |
simon@5276 | 2206 | </style> |
simon@5276 | 2207 | |
simon@5276 | 2208 | <defs> |
simon@5276 | 2209 | <pattern id="pattern-1"> |
simon@5276 | 2210 | <rect id="rect1" width="100" height="100" fill="blue" /> |
simon@5276 | 2211 | </pattern> |
simon@5276 | 2212 | </defs> |
simon@5276 | 2213 | |
dschulze@6929 | 2214 | <rect width="200" height="200" fill="url(#pattern-1)" /> |
simon@5276 | 2215 | </svg></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><transform-list></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><transform-list></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><transform-list></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><transform-list></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><transform-list></var> is equivalent to a list of |
dschulze@5895 | 2341 | <var><transform-function></var>s. <var><transform-list></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><translation-value></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><transform-list></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><translation-value></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 | <rect width="100" height="100"> |
dschulze@5900 | 2445 | <animateTransform attributeName="transform" attributeType="XML" |
dschulze@5900 | 2446 | type="scale" by="1" dur="5s" fill="freeze"/> |
dschulze@5900 | 2447 | </rect></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><linearGradient gradientTransform="scale(2)"> |
simon@5276 | 2478 | <animate attributeName="gradientTransform" from="scale(2)" to="scale(4)" |
simon@5276 | 2479 | dur="3s" additive="sum"/> |
simon@5276 | 2480 | <animate attributeName="transform" from="translate(0, 0)" to="translate(100px, 100px)" |
simon@5276 | 2481 | dur="3s" additive="sum"/> |
simon@5276 | 2482 | </linearGradient></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><transform-functions></var>. The set of allowed transform |
simon@5276 | 2503 | functions is given below. For <var><transform-functions></var> the |
simon@5276 | 2504 | type <var><translation-value></var> is defined as a |
simon@5276 | 2505 | <var><length></var> or <var><percentage></var> value, and the |
simon@5276 | 2506 | <var><angle></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><angle></var> is used in this specification, a |
simon@5276 | 2509 | <var><number></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(<number>, |
dschulze@5743 | 2517 | <number>, <number>, <number>, <number>, |
dschulze@5743 | 2518 | <number>)</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(<translation-value>[, |
simon@5276 | 2525 | <translation-value>])</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><ty></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(<translation-value>)</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(<translation-value>)</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(<number>[, |
dschulze@5743 | 2545 | <number>])</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(<number>)</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(<number>)</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(<angle>)</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(<angle>[, <angle>])</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(<angle>)</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(<angle>)</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(<number>, |
simon@5276 | 2598 | <number>, <number>, <number>, <number>, |
simon@5276 | 2599 | <number>, <number>, <number>, <number>, |
simon@5276 | 2600 | <number>, <number>, <number>, <number>, |
dschulze@5743 | 2601 | <number>, <number>, <number>)</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(<translation-value>, |
simon@5276 | 2608 | <translation-value>, <length>)</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(<length>)</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(<number>, |
dschulze@5743 | 2621 | <number>, <number>)</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(<number>)</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(<number>, |
dschulze@5743 | 2632 | <number>, <number>, <angle>)</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(<angle>)</code> |
simon@5276 | 2642 | |
simon@5276 | 2643 | <dd> same as <code class=css>rotate3d(1, 0, 0, <angle>)</code>. |
simon@5276 | 2644 | |
dschulze@5743 | 2645 | <dt id=rotateY-function> <code class=css>rotateY(<angle>)</code> |
simon@5276 | 2646 | |
simon@5276 | 2647 | <dd> same as <code class=css>rotate3d(0, 1, 0, <angle>)</code>. |
simon@5276 | 2648 | |
dschulze@5743 | 2649 | <dt id=rotateZ-function> <code class=css>rotateZ(<angle>)</code> |
simon@5276 | 2650 | |
simon@5276 | 2651 | <dd> same as <code class=css>rotate3d(0, 0, 1, <angle>)</code>, |
simon@5276 | 2652 | which is also the same as <code class=css>rotate(<angle>)</code>. |
simon@5276 | 2653 | |
simon@5276 | 2654 | <dt id=perspective-function> <code |
simon@5276 | 2655 | class=css>perspective(<length>)</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><transform-functions></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 | <div style="transform:translate(-10px,-20px) scale(2) rotate(45deg) translate(5px,10px)"/> |
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 | <div style="transform:translate(-10px,-20px)"> |
simon@5276 | 2685 | <div style="transform:scale(2)"> |
simon@5276 | 2686 | <div style="transform:rotate(45deg)"> |
simon@5276 | 2687 | <div style="transform:translate(5px,10px)"> |
simon@5276 | 2688 | </div> |
simon@5276 | 2689 | </div> |
simon@5276 | 2690 | </div> |
simon@5276 | 2691 | </div> |
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><style> |
dschulze@5910 | 2708 | .box { |
dschulze@5910 | 2709 | transform: scale(0); |
dschulze@5910 | 2710 | } |
dschulze@5910 | 2711 | </style> |
dschulze@5910 | 2712 | |
dschulze@5910 | 2713 | <div class="box"> |
dschulze@5910 | 2714 | Not visible |
dschulze@5910 | 2715 | </div></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(<translation-value>, |
dschulze@5690 | 2817 | <translation-value>)</code> |
dschulze@5690 | 2818 | |
dschulze@5690 | 2819 | <dd> for <code class=css>translateX(<translation-value>)</code>, |
dschulze@5690 | 2820 | <code class=css>translateY(<translation-value>)</code> and <code |
dschulze@5690 | 2821 | class=css>translate(<translation-value>)</code>. |
dschulze@5690 | 2822 | |
dschulze@5743 | 2823 | <dt id=rotate-three-primitive> <code class=css>rotate(<angle>, |
dschulze@5743 | 2824 | <translation-value>, <translation-value>)</code> |
dschulze@5690 | 2825 | |
dschulze@5690 | 2826 | <dd> for <code class=css>rotate(<angle>)</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(<number>, |
dschulze@5743 | 2831 | <number>)</code> |
dschulze@5690 | 2832 | |
dschulze@5690 | 2833 | <dd> for <code class=css>scaleX(<number>)</code>, <code |
dschulze@5690 | 2834 | class=css>scaleY(<number>)</code> and <code |
dschulze@5690 | 2835 | class=css>scale(<number>)</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(<translation-value>, |
dschulze@5690 | 2843 | <translation-value>, <length>)</code> |
dschulze@5690 | 2844 | |
dschulze@5690 | 2845 | <dd> for <code class=css>translateX(<translation-value>)</code>, |
dschulze@5690 | 2846 | <code class=css>translateY(<translation-value>)</code>, <code |
dschulze@5690 | 2847 | class=css>translateZ(<number>)</code> and <code |
dschulze@5690 | 2848 | class=css>translate(<translation-value>[, |
dschulze@5690 | 2849 | <translation-value>])</code>. |
dschulze@5690 | 2850 | |
dschulze@5743 | 2851 | <dt id=scale3d-primitive> <code class=css>scale3d(<number>, |
dschulze@5743 | 2852 | <number>, <number>)</code> |
dschulze@5690 | 2853 | |
dschulze@5690 | 2854 | <dd> for <code class=css>scaleX(<number>)</code>, <code |
dschulze@5690 | 2855 | class=css>scaleY(<number>)</code>, <code |
dschulze@5690 | 2856 | class=css>scaleZ(<number>)</code> and <code |
dschulze@6299 | 2857 | class=css>scale(<number>[, <number>])</code>. |
dschulze@6402 | 2858 | |
dschulze@6402 | 2859 | <dt id=rotate3d-primitive> <code class=css>rotate3d(<number>, |
bert@6706 | 2860 | <number>, <number>, <angle>)</code> |
dschulze@6402 | 2861 | |
dschulze@6402 | 2862 | <dd> for <code class=css>rotate(<number>)</code>, <code |
dschulze@6402 | 2863 | class=css>rotateX(<number>)</code>, <code |
dschulze@6402 | 2864 | class=css>rotateY(<number>)</code> and <code |
dschulze@6402 | 2865 | class=css>rotateZ(<number>)</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(<translation-value>, |
bert@6706 | 2909 | <translation-value>)</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 | <style> |
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 | </style> |
dschulze@5902 | 3002 | |
dschulze@5902 | 3003 | <div></div></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 | <length> |
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>[ <percentage> | <length> | left | center | right | top | |
dschulze@5892 | 3494 | bottom] | [ [ <percentage> | <length> | left | center | |
dschulze@5892 | 3495 | right ] && [ <percentage> | <length> | 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 | <transform-function> [ <transform-function> ]* |
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>[ <percentage> | <length> | left | center | right | top | |
dschulze@5892 | 3527 | bottom] | [ [ <percentage> | <length> | left | center | |
dschulze@5892 | 3528 | right ] && [ <percentage> | <length> | top | |
dschulze@5892 | 3529 | center | bottom ] ] <length>? |
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 | --> |