css3-transforms/Transforms.src.html

Mon, 12 Mar 2012 11:30:19 -0600

author
Aryeh Gregor <ayg@aryeh.name>
date
Mon, 12 Mar 2012 11:30:19 -0600
changeset 4736
3c173d4d4749
parent 4703
16db95fda02f
child 4737
9338e35c5058
permissions
-rw-r--r--

Hyperlink two CSS2.1 definitions

vhardy@3672 1 <!DOCTYPE html public '-//W3C//DTD HTML 4.01//EN' 'http://www.w3.org/TR/html4/strict.dtd'>
vhardy@3672 2 <html lang="en">
vhardy@3672 3 <head profile="http://www.w3.org/2006/03/hcard">
vhardy@3672 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
vhardy@3719 5 <title>CSS Transforms</title>
simon@4357 6 <link rel="stylesheet" type="text/css" href="../default.css" />
simon@4357 7 <link rel="stylesheet" type="text/css" href="http://www.w3.org/StyleSheets/TR/W3C-ED.css" />
vhardy@3672 8
vhardy@3732 9 <style type="text/css">
simon@4376 10 .term {
simon@4376 11 font-style: italic;
simon@4376 12 }
simon@4363 13
dschulze@4321 14 .todo {
dschulze@4321 15 font-weight: bold;
dschulze@4321 16 border-left: 0.5em solid #f44;
dschulze@4321 17 padding-left: 1em;
dschulze@4321 18 margin-top: 0.5em;
dschulze@4321 19 color: #a0a0a0;
dschulze@4321 20 }
dschulze@4321 21
dschulze@4321 22 .todo:before {
dschulze@4321 23 content: "TO DO : ";
dschulze@4321 24 color: #f44;
dschulze@4321 25 }
vhardy@3672 26 </style>
vhardy@3672 27
vhardy@3672 28 </head>
vhardy@3672 29 <body>
vhardy@3672 30 <div id="div-head" class="head">
vhardy@3672 31 <!--logo-->
vhardy@3672 32
simon@4357 33 <h1>CSS Transforms</h1>
vhardy@3672 34
vhardy@3672 35 <h2 class="no-num no-toc">[LONGSTATUS] [DATE]</h2>
vhardy@3672 36 <dl>
vhardy@3672 37 <dt>This version:
vhardy@3672 38 <dd>
simon@4357 39 <a href="[VERSION]">http://dev.w3.org/csswg/css3-transforms/</a>
vhardy@3672 40 <!--http://www.w3.org/TR/[YEAR]/WD-[SHORTNAME]-[CDATE]-->
vhardy@3672 41 <dt>Latest version:
vhardy@3672 42 <dd><a
simon@4357 43 href="http://www.w3.org/TR/css3-transforms">[LATEST]</a>
simon@4583 44 <dt>Editor's draft:
simon@4583 45 <dd><a href="http://dev.w3.org/csswg/[SHORTNAME]/">http://dev.w3.org/csswg/[SHORTNAME]/</a>
vhardy@3672 46 <dt>Previous version:
simon@4357 47 <dd>None
vhardy@3672 48 <dt id="editors-list">Editors:
vhardy@3672 49 <dd>Simon Fraser (<a href="http://www.apple.com/">Apple Inc</a>) &lt;simon.fraser &#64;apple.com&gt;
vhardy@3672 50 <dd>Dean Jackson (<a href="http://www.apple.com/">Apple Inc</a>) &lt;dino &#64;apple.com&gt;
vhardy@3672 51 <dd>David Hyatt (<a href="http://www.apple.com/">Apple Inc</a>) &lt;hyatt &#64;apple.com&gt;
vhardy@3672 52 <dd>Chris Marrin (<a href="http://www.apple.com/">Apple Inc</a>) &lt;cmarrin &#64;apple.com&gt;
vhardy@3672 53 <dd>Edward O'Connor (<a href="http://www.apple.com/">Apple Inc</a>) &lt;eoconnor &#64;apple.com&gt;
dschulze@4323 54 <dd>Dirk Schulze (<a href="http://www.adobe.com/">Adobe Systems, Inc</a>) &lt;dschulze &#64;adobe.com&gt;
simon@4581 55 <dd>Aryeh Gregor (<a href="http://www.mozilla.org/">Mozilla</a>) &lt;ayg &#64;aryeh.name&gt;
simon@4581 56
simon@4581 57 <dt>Issues list:
simon@4581 58 <dd><a href="https://www.w3.org/Bugs/Public/buglist.cgi?query_format=advanced&amp;product=CSS&amp;component=Transforms&amp;resolution=---&amp;cmdtype=doit">in Bugzilla</a>
simon@4581 59
simon@4581 60 <dt>Test suite:
simon@4581 61 <dd>none yet
simon@4581 62 </dl>
vhardy@3672 63
vhardy@3672 64 <!--copyright-->
vhardy@3672 65
vhardy@3672 66 <hr title="Separator for header">
vhardy@3672 67 </div>
vhardy@3672 68
vhardy@3672 69 <h2 class="no-num no-toc" id="abstract">Abstract</h2>
vhardy@3672 70
vhardy@3672 71 <p>CSS transforms allows elements styled with CSS to be transformed
dschulze@4321 72 in two-dimensional or three-dimensional space. This specification is the convergence of the
vhardy@3672 73 <a href="http://www.w3.org/TR/css3-2d-transforms/">CSS 2D transforms</a>,
vhardy@3672 74 <a href="http://www.w3.org/TR/css3-3d-transforms/">CSS 3D transforms</a>
vhardy@3672 75 and <a href="http://www.w3.org/TR/2009/WD-SVG-Transforms-20090320/">SVG transforms</a>
vhardy@3672 76 specifications.</p>
vhardy@3672 77
vhardy@3672 78 <h2 class="no-num no-toc" id="status">Status of this document</h2>
vhardy@4360 79
vhardy@4360 80 <p class="note">
vhardy@4360 81 This specification merges the former CSS 2D Transforms and CSS 3D Transforms specifications and
vhardy@4360 82 will also merge CSS Transforms and SVG Transforms. The merge is in progress and the specification
vhardy@4360 83 is not yet ready for review.
vhardy@4360 84 </p>
vhardy@4360 85
vhardy@3672 86 <!--status-->
vhardy@3672 87
vhardy@3672 88 <p>
vhardy@3672 89 The <a href="ChangeLog">list of changes made to this specification</a> is
vhardy@3672 90 available.
vhardy@3672 91 </p>
vhardy@3672 92
vhardy@3672 93 <h2 class="no-num no-toc" id="contents">Table of contents</h2>
vhardy@3672 94 <!--toc-->
vhardy@3672 95
vhardy@3672 96
vhardy@3672 97 <h2>Introduction</h2>
vhardy@3672 98
simon@4345 99 <p><em>This section is not normative.</em></p>
simon@4345 100 <p>
simon@4345 101 The CSS <a href="http://www.w3.org/TR/REC-CSS2/visuren.html">visual
dschulze@4511 102 formatting model</a> describes a coordinate system within each
simon@4345 103 element is positioned. Positions and sizes in this coordinate space can
dschulze@4511 104 be thought of as being expressed in pixels, starting in the origin of point
dschulze@4511 105 with positive values proceeding to the right and down.
simon@4345 106 </p>
simon@4345 107 <p>
dschulze@4602 108 This coordinate space can be modified with the '<code
dschulze@4602 109 class="property">transform</code>' property. Using transform, elements
simon@4345 110 can be translated, rotated and scaled in two or three dimensional space.
simon@4345 111 </p>
simon@4345 112 <p>
simon@4345 113 Additional properties make working with transforms easier, and allow the
simon@4345 114 author to control how nested three-dimensional transforms interact.
simon@4345 115 </p>
simon@4345 116 <ul>
simon@4345 117 <li>
dschulze@4602 118 The '<code class="property">transform-origin</code>' property
simon@4345 119 provides a convenient way to control the origin about which transforms on
simon@4345 120 an element are applied.
simon@4345 121 </li>
simon@4345 122 <li>
dschulze@4602 123 The '<code class="property">perspective</code>' property allows the author
simon@4345 124 to make child elements with three-dimensional transforms appear as if they live in a common
simon@4345 125 three-dimensional space.
dschulze@4602 126 The '<code class="property">perspective-origin</code>' property provides control
simon@4345 127 over the origin at which perspective is applied, effectively changing the location of
simon@4345 128 the "vanishing point".
simon@4345 129 </li>
simon@4345 130 <li>
dschulze@4602 131 The '<code class="property">transform-style</code>' property allows 3D-transformed
simon@4345 132 elements and their 3D-transformed descendants to share a common three-dimensional
simon@4345 133 space, allowing the construction of hierarchies of three-dimensional objects.
simon@4345 134 </li>
simon@4345 135 <li>
dschulze@4602 136 The '<code class="property">backface-visibility</code>' property comes into play
simon@4345 137 when an element is flipped around via three-dimensional transforms such that its
simon@4345 138 reverse side is visible to the viewer. In some situations it is desirable to
simon@4345 139 hide the element in this situation, which is possible using the value of 'hidden'
simon@4345 140 for this property.
simon@4345 141 </li>
simon@4345 142 </ul>
simon@4345 143 <p>
dschulze@4602 144 Note that while some values of the '<code class="property">transform</code>' property
simon@4345 145 allow an element to be transformed in a three-dimensional coordinate system, the elements
simon@4345 146 themselves are not three-dimensional objects. Instead, they exist on a two-dimensional
simon@4345 147 plane (a flat surface) and have no depth.
simon@4345 148 </p>
vhardy@3672 149
simon@4345 150 <div class="issue">
simon@4345 151 There are two roles for transformations in layout: (1) transformations
simon@4345 152 that adjust the position of the affected content without changing the
simon@4345 153 normal layout of that content (much like relative positioning) and (2)
simon@4345 154 transformation of the content prior to layout that affects the layout
simon@4345 155 of that content. See <a
simon@4345 156 href="http://lists.w3.org/Archives/Public/www-style/2007Oct/0209">http://lists.w3.org/Archives/Public/www-style/2007Oct/0209</a>
simon@4345 157 for examples of both cases. The "transform" property (as defined in
simon@4345 158 this document) is equally useful for both roles. This document is
simon@4345 159 focused on satisfying the first role. There is, however, an
simon@4345 160 architectural question that arises because there needs to be a way to
simon@4345 161 distinguish which role an author of a stylesheet wants. The key
simon@4345 162 question is which is the default behavior/role for the "transform"
simon@4345 163 property and how is the other behavior/role indicated by a stylesheet
simon@4345 164 author. If you have an opinion on this topic, please send feedback.
simon@4345 165 </div>
simon@4345 166 <div class="issue">
simon@4345 167 What do fixed backgrounds do in transforms? They should probably ignore
simon@4345 168 the transform completely, since - even transformed - the object should
simon@4345 169 be acting as "porthole" through which the fixed background can be viewed
simon@4345 170 in its original form.
simon@4345 171 </div>
simon@4345 172
simon@4345 173 <!-- ======================================================================================================= -->
vhardy@3672 174
simon@4345 175 <h2 id="module-interactions">Module Interactions</h2>
simon@4345 176 <p>Write me</p>
simon@4345 177
simon@4365 178 <h2 id="css-values">CSS Values</h2>
simon@4345 179 <p>Write me</p>
simon@4345 180
simon@4345 181
simon@4345 182 <h2 id="definitions">Definitions</h2>
simon@4345 183 <p> When used in this specification, terms have the meanings assigned in
simon@4345 184 this section.
simon@4345 185 </p>
simon@4345 186 <dl>
dschulze@4483 187 <dt id="TermBoundingBox"><dfn>bounding box</dfn></dt>
dschulze@4483 188 <dd>
dschulze@4483 189 <p>
dschulze@4483 190 A bounding box is the object bounding box for all SVG elements without an associated CSS layout box and
dschulze@4483 191 the border box for all other elements.
dschulze@4483 192 </p>
dschulze@4483 193 </dd>
dschulze@4483 194
simon@4365 195 <dt id="TermTransformableElement"><dfn>transformable element</dfn></dt>
simon@4345 196 <dd>
vhardy@3672 197 <p>
ayg@4736 198 A transformable element in the HTML namespace which is either a
ayg@4736 199 <a href="http://www.w3.org/TR/CSS2/visuren.html#block-level">block-level</a>
ayg@4736 200 or <a href="http://www.w3.org/TR/CSS2/visuren.html#x13">atomic
ayg@4736 201 inline-level element</a>, or an element in the SVG namespace
ayg@4736 202 (see [[SVG11]]) which has the attributes '<code
ayg@4736 203 class="property">transform</code>',
simon@4345 204 'patternTransform' or 'gradientTransform'.
vhardy@3672 205 </p>
simon@4345 206 </dd>
simon@4345 207
simon@4365 208 <dt id="TermPerspectiveMatrix"><dfn>perpsective matrix</dfn></dt>
simon@4345 209 <dd>
simon@4345 210 <p>
dschulze@4602 211 A matrix computed from the values of the '<code class="property">perspective</code>' and '<code class="property">perspective-origin</code>' properties as described <a href="#perspective-matrix-computation">below</a>.
simon@4365 212 </p>
simon@4365 213 </dd>
simon@4365 214
simon@4366 215 <dt id="TermTransformationMatrix"><dfn>transformation matrix</dfn></dt>
simon@4365 216 <dd>
simon@4365 217 <p>
dschulze@4602 218 A matrix computed from the values of the '<code class="property">transform</code>' and '<code class="property">transform-origin</code>' properties as described <a href="#transformation-matrix-computation">below</a>.
simon@4365 219 </p>
simon@4365 220 </dd>
simon@4365 221
simon@4365 222 <dt id="Term3DRenderingContext"><dfn>3D rendering context</dfn></dt>
simon@4365 223 <dd>
simon@4365 224 <p>
simon@4365 225 A containing block hierarchy of one or more levels, instantiated by elements with a computed value for
dschulze@4602 226 the '<code class="property">transform-style</code>' property of '<code class="css">preserve-3d</code>',
simon@4365 227 whose elements share a common three-dimensional coordinate system.
dschulze@4321 228 </p>
simon@4345 229 </dd>
simon@4345 230 <!-- Define "three-dimensional transform" ? -->
simon@4345 231 </dl>
simon@4345 232
simon@4345 233 <!-- ======================================================================================================= -->
simon@4345 234
simon@4345 235 <h2 id="transform-rendering">The Transform Rendering Model</h2>
simon@4345 236 <!-- This section is normative -->
vhardy@3672 237 <p>
dschulze@4602 238 Specifying a value other than '<code class="css">none</code>' for the '<code class="property">transform</code>'
vhardy@3672 239 property establishes a new <em>local coordinate system</em> at the element that it is
simon@4366 240 applied to. The mapping from where the element would have rendered into that local coordinate system
simon@4366 241 is given by the element's <a href="#TermTransformationMatrix"><i>transformation matrix</i></a>.
simon@4366 242 Transformations are cumulative. That is, elements establish their local
vhardy@3672 243 coordinate system within the coordinate system of their parent. From the perspective of the
dschulze@4602 244 user, an element effectively accumulates all the '<code class="property">transform</code>'
vhardy@3672 245 properties of its ancestors as well as any local transform applied to it. The accumulation
vhardy@3672 246 of these transforms defines a <em>current transformation matrix (CTM)</em> for the element.
vhardy@3672 247 </p>
vhardy@3672 248 <p>
simon@4345 249 The coordinate space behaves as described in the <a
simon@4345 250 href="http://www.w3.org/TR/SVG/coords.html#EstablishingANewUserSpace">coordinate
simon@4345 251 system transformations</a> section of the SVG 1.1 specification. This is
simon@4345 252 a coordinate system with two axes: the X axis increases horizontally to
simon@4345 253 the right; the Y axis increases vertically downwards. Three-dimensional
simon@4345 254 transform functions extent this coordinate space into three dimensions,
simon@4345 255 adding a Z axis perpendicular to the plane of the screen, that increases towards the viewer.
simon@4345 256 </p>
simon@4453 257 <p id="transformation-matrix-computation">
simon@4366 258 The <a href="#TermTransformationMatrix"><i>transformation matrix</i></a> is computed
dschulze@4602 259 from the '<code class="property">transform</code>' and '<code class="property">transform-origin</code>' properties
simon@4366 260 as follows:
simon@4366 261 <ol>
simon@4366 262 <li>Start with the identity matrix.</li>
dschulze@4602 263 <li>Translate by the computed X, Y and Z values of '<code class="property">transform-origin</code>'</li>
dschulze@4602 264 <li>Multiply by each of the transform functions in '<code class="property">transform</code>' property in turn</li>
dschulze@4602 265 <li>Translate by the negated computed X, Y and Z values of '<code class="property">transform-origin</code>'</li>
simon@4366 266 </ol>
simon@4366 267 </p>
simon@4366 268 <p>
dschulze@4602 269 Transforms apply to <span class="term">transformable elements</span>.
simon@4345 270 </p>
simon@4358 271
simon@4358 272 <div class="example">
simon@4358 273 <pre>
simon@4358 274 div {
simon@4358 275 transform: translate(100px, 100px);
simon@4358 276 }
simon@4358 277 </pre>
simon@4358 278 <p>This transform moves the element by 100 pixels in both the X and Y directions.</p>
simon@4358 279 <div class="figure">
simon@4358 280 <img src="transform1.png" alt="The 100px translation in X and Y">
simon@4358 281 </div>
simon@4358 282 </div>
simon@4358 283
simon@4358 284 <div class="example">
simon@4358 285 <pre>
simon@4358 286 div {
simon@4358 287 height: 100px; width: 100px;
simon@4358 288 transform: translate(80px, 80px) scale(1.5, 1.5) rotate(45deg);
simon@4358 289 }
simon@4358 290 </pre>
dschulze@4602 291 <p>This transform moves the element by 80 pixels in both the X and Y directions, then scales the element by 150%, then rotates it 45&deg; clockwise about the Z axis. Note that the scale and rotation operate about the center of the element, since the element has the default transform-origin of '<code class="css">50% 50%</code>'.</p>
simon@4358 292 <div class="figure">
simon@4358 293 <img src="compound_transform.png" alt="The transform specified above">
simon@4358 294 </div>
simon@4358 295
simon@4358 296 <p>Note that an identical rendering can be obtained by nesting elements with the equivalent transforms:
simon@4358 297 <pre>
simon@4358 298 &lt;div style="transform: translate(80px, 80px)"&gt;
dschulze@4602 299 &lt;div style="transform: scale(1.5, 1.5)"&gt;
dschulze@4602 300 &lt;div style="transform: rotate(45deg)"&gt;&lt;/div&gt;
dschulze@4602 301 &lt;/div&gt;
simon@4358 302 &lt;/div&gt;
simon@4358 303 </pre>
simon@4358 304 </div>
simon@4358 305
simon@4345 306 <!-- This "in the HTML namespace" is awkward. Is there a better way? -->
simon@4345 307 <p>
simon@4345 308 In the HTML namespace, the transform property does not affect the flow of the content
simon@4363 309 surrounding the transformed element. However, the extent of the overflow
vhardy@3672 310 area takes into account transformed elements. This behavior is similar
simon@4363 311 to what happens when elements are offset via relative positioning.
dschulze@4602 312 Therefore, if the value of the '<code class="property">overflow</code>'
dschulze@4602 313 property is '<code class="css">scroll</code>' or '<code class="css">auto</code>',
simon@4365 314 scrollbars will appear as needed to see content that is transformed outside the visible area.
vhardy@3672 315 </p>
vhardy@3672 316 <p>
dschulze@4602 317 In the HTML namespace, any value other than '<code class="css">none</code>' for the transform results in the creation of
vhardy@3672 318 both a stacking context and a containing block. The object acts as a
vhardy@3672 319 containing block for fixed positioned descendants.
vhardy@3672 320 </p>
simon@4345 321 <p class="issue">
simon@4345 322 Is this affect on position:fixed necessary? If so, need to go into more detail here
simon@4345 323 about why fixed positioned objects should do this, i.e., that it's much harder to implement otherwise.
dschulze@4321 324 </p>
simon@4345 325
simon@4345 326 <h3 id="transform-3d-rendering">3D Transform Rendering</h3>
simon@4345 327
simon@4345 328 <!-- Maybe define "tranform container" in the definitions, and use it everywhere
simon@4345 329 in place of "containing block"? I'm not sure if "containing block" is exactly right. -->
simon@4345 330 <p>
simon@4345 331 Normally, elements render as flat planes, and are rendered into the same plane
simon@4345 332 as their containing block. Often this is the plane shared by the rest of the page.
simon@4345 333 Two-dimensional transform functions can alter the appearance of an element, but
simon@4363 334 that element is still rendered into the same plane as its containing block.
simon@4345 335 </p>
simon@4345 336 <p>
simon@4345 337 Three-dimensional transforms can result in transformation matrices with a non-zero
simon@4345 338 Z component<!-- clarify -->, potentially lifting them off the plane of their
simon@4345 339 containing block. Because of this, elements with three-dimensional transformations
simon@4345 340 could potentially render in an front-to-back order that different from the normal CSS rendering order,
simon@4345 341 and intersect with each other. Whether they do so depends on whether the element is a member
simon@4363 342 of a <span class="term">3D rendering context</span>, as described below.
simon@4345 343 </p>
simon@4366 344 <div class="issue">
simon@4345 345 <p class="desc">This description does not exactly match what WebKit implements. Perhaps
simon@4345 346 it should be changed to match current implementations?</p>
vhardy@3672 347 </div>
simon@4366 348
simon@4345 349 <div class="example">
simon@4356 350 <p>This example shows the effect of three-dimensional transform applied to an element.
simon@4356 351 </p>
simon@4345 352 <pre>
simon@4364 353 &lt;style&gt;
dschulze@4602 354 div {
dschulze@4602 355 height: 150px;
dschulze@4602 356 width: 150px;
dschulze@4602 357 }
dschulze@4602 358 .container {
dschulze@4602 359 border: 1px solid black;
dschulze@4602 360 }
dschulze@4602 361 .transformed {
dschulze@4602 362 transform: rotateY(50deg);
dschulze@4602 363 }
simon@4364 364 &lt;/style&gt;
simon@4366 365
simon@4356 366 &lt;div class="container"&gt;
simon@4356 367 &lt;div class="transformed"&gt;&lt;/div&gt;
simon@4356 368 &lt;/div&gt;
simon@4356 369 </pre>
simon@4366 370 <div class="figure">
simon@4366 371 <img src="examples/simple-3d-example.png" width="210" height="190" alt="Div with a rotateY transform.">
simon@4366 372 </div>
simon@4358 373 <p>The transform is a 50&deg; rotation about the vertical, Y axis. Note how this makes the blue box appear
simon@4356 374 narrower, but not three-dimensional.
simon@4345 375 </p>
simon@4345 376 </div>
simon@4366 377
simon@4366 378 <p>
dschulze@4602 379 The '<code class="property">perspective</code>' and '<code class="property">perspective-origin</code>'
simon@4366 380 properties can be used to add a feeling of depth to a scene by making elements higher on the Z axis
dschulze@4602 381 (closer to the viewer) appear larger, and those further away to appear smaller.
simon@4366 382 </p>
simon@4453 383 <p id="perspective-matrix-computation">
simon@4366 384 The <a href="#TermPerspectiveMatrix"><i>perspective matrix</i></a> is computed as follows:
simon@4366 385 <!-- Make this more mathy, with matrices? -->
simon@4366 386 <ol>
simon@4366 387 <li>Start with the identity matrix.</li>
dschulze@4602 388 <li>Translate by the computed X and Y values of '<code class="property">perspective-origin</code>'</li>
dschulze@4602 389 <li>Multiply by the matrix that would be obtained from the '<a href="#perspective-function"><code class="css">perspective(&lt;length&gt;)</code></a>' transform function, where the length is provided by the value of the '<code class="property">perspective</code>' property</li>
dschulze@4602 390 <li>Translate by the negated computed X and Y values of '<code class="property">perspective-origin</code>'</li>
simon@4366 391 </ol>
simon@4366 392 </p>
simon@4345 393
simon@4356 394 <div class="example">
simon@4356 395 <p>This example shows how perspective can be used to cause three-dimensional transforms to appear more realistic.
simon@4356 396 </p>
simon@4356 397 <pre>
simon@4364 398 &lt;style&gt;
dschulze@4602 399 div {
dschulze@4602 400 height: 150px;
dschulze@4602 401 width: 150px;
dschulze@4602 402 }
dschulze@4602 403 .container {
dschulze@4602 404 perspective: 500px;
dschulze@4602 405 border: 1px solid black;
dschulze@4602 406 }
dschulze@4602 407 .transformed {
dschulze@4602 408 transform: rotateY(50deg);
dschulze@4602 409 }
simon@4364 410 &lt;/style&gt;
simon@4366 411
simon@4356 412 &lt;div class="container"&gt;
simon@4356 413 &lt;div class="transformed"&gt;&lt;/div&gt;
simon@4356 414 &lt;/div&gt;
simon@4356 415 </pre>
simon@4366 416 <div class="figure">
simon@4366 417 <img src="examples/simple-perspective-example.png" width="210" height="190" alt="Div with a rotateY transform,
simon@4366 418 and perspective on its container">
simon@4366 419 </div>
simon@4366 420 <p>The inner element has the same transform as in the previous example, but its rendering is now influenced by the perspective
simon@4356 421 property on its parent element. Perspective causes vertices that have positive Z coordinates (closer to the viewer)
dschulze@4602 422 to be scaled up in X and Y, and those further away (negative Z coordinates) to be scaled down, giving an appearance of depth.
simon@4356 423 </p>
simon@4356 424 </div>
simon@4356 425
simon@4345 426 <p>
simon@4366 427 An element with a three-dimensional transform that is not contained in a
simon@4366 428 <span class="term">3D rendering context</span> renders with the appropriate
simon@4366 429 transform applied, but does not intersect with any other elements. The three-dimensional
simon@4366 430 transform in this case can be considered just as a painting effect, like two-dimensional
simon@4366 431 transforms. Similarly, the transform does not affect painting order. For example, a transform with a
simon@4366 432 positive Z translation may make an element look larger, but does not cause that element
simon@4366 433 to render in front of elements with no translation in Z.
simon@4366 434 </p>
simon@4366 435 <p>
simon@4345 436 An element with a three-dimensional transform that is contained in a
simon@4345 437 <span class="term">3D rendering context</span> can visibly interact with other elements
simon@4345 438 in that same 3D rendering context; the set of elements participating in the same
simon@4345 439 <span class="term">3D rendering context</span> may obscure each other or intersect,
simon@4345 440 based on their computed transforms. They are rendered as if they are all siblings,
simon@4345 441 positioned in a common 3D coordinate space. The position of each element in that three-dimensional
simon@4345 442 space is determined by accumulating the transformation matrices
simon@4345 443 up from the element that establishes the <span class="term">3D rendering context</span>
simon@4345 444 through each element that is a containing block for the given element, as described below.
simon@4345 445 <!-- More detail required, probably with matrices -->
simon@4345 446 </p>
simon@4345 447
simon@4366 448 <div class="example">
simon@4366 449 <pre>
simon@4366 450 &lt;style&gt;
dschulze@4602 451 div {
dschulze@4602 452 height: 150px;
dschulze@4602 453 width: 150px;
dschulze@4602 454 }
dschulze@4602 455 .container {
dschulze@4602 456 perspective: 500px;
dschulze@4602 457 border: 1px solid black;
dschulze@4602 458 }
dschulze@4602 459 .transformed {
dschulze@4602 460 transform: rotateY(50deg);
dschulze@4602 461 background-color: blue;
dschulze@4602 462 }
dschulze@4602 463 .child {
dschulze@4602 464 transform-origin: top left;
dschulze@4602 465 transform: rotateX(40deg);
dschulze@4602 466 background-color: lime;
dschulze@4602 467 }
simon@4366 468 &lt;/style&gt;
simon@4366 469
simon@4366 470 &lt;div class="container"&gt;
dschulze@4602 471 &lt;div class="transformed"&gt;
dschulze@4602 472 &lt;div class="child"&gt;&lt;/div&gt;
dschulze@4602 473 &lt;/div&gt;
simon@4366 474 &lt;/div&gt;
simon@4366 475 </pre>
dschulze@4602 476 <p>This example shows how nested 3D transforms are rendered in the absence of '<code class="css">transform-style: preserve-3d</code>'. The blue div is transformed as in the previous example, with its rendering influenced by the perspective on its parent element. The lime element also has a 3D transform, which is a rotation about the X axis (anchored at the top, by virtue of the transform-origin). However, the lime element is being rendered into the plane of its parent because it is not a member of a 3D rendering context; the parent is "flattening".
simon@4366 477 </p>
simon@4366 478 <div class="figure">
simon@4366 479 <img src="examples/3d-rendering-context-flat.png" width="240" height="200" alt="Nested 3D transforms, with flattening">
simon@4366 480 </div>
simon@4366 481 </div>
simon@4366 482
simon@4365 483 <p>Elements establish and participate in 3D rendering contexts as follows:</p>
simon@4365 484 <ul>
simon@4365 485 <li>
simon@4365 486 A <span class="term">3D rendering context</span> is established by a
dschulze@4602 487 a <span class="term">transformable element</span> whose computed value for '<code class="property">transform-style</code>' is
dschulze@4602 488 '<code class="css">preserve-3d</code>', and which itself is not part of a 3D rendering context.
simon@4365 489 Note that such an element is always a containing block. An element that establishes a 3D rendering context
simon@4365 490 also participates in that context.
simon@4365 491 </li>
simon@4365 492 <li>
dschulze@4602 493 An element whose computed value for '<code class="property">transform-style</code>' is
dschulze@4602 494 '<code class="css">preserve-3d</code>', and which itself participates in a
simon@4365 495 <span class="term">3D rendering context</span>, extends that 3D rendering context rather than establishing
simon@4365 496 a new one.
simon@4365 497 </li>
simon@4365 498 <li>
simon@4365 499 An element participates in a <span class="term">3D rendering context</span> if its containing block
simon@4365 500 establishes or extends a <span class="term">3D rendering context</span>.
simon@4365 501 </li>
simon@4365 502 </ul>
simon@4345 503 <p>
simon@4345 504 The final value of the transform used to render an element in a <span class="term">3D rendering context</span>
simon@4366 505 is computed by accumulating a matrix as follows:
simon@4345 506 </p>
simon@4345 507 <ol>
simon@4366 508 <li>Start with the identity matrix</li>
simon@4366 509 <li>For each containing block between the root of the <span class="term">3D rendering context</span>
simon@4366 510 and the element in question:
simon@4365 511 <ol>
simon@4366 512 <li>multiply the accumulated matrix with the <a href="#TermPerspectiveMatrix"><i>perspective matrix</i></a>
simon@4366 513 on the element's containing block (if any). That contining block is not necessarily a member
simon@4366 514 of the 3D rendering context.</li>
simon@4366 515 <li>apply to the accumulated matrix a translation equivalent to the horizontal and vertical offset of the element relative to
simon@4366 516 its containing block as specified by the CSS visual formatting model. <!-- (tighten this!) --></li>
simon@4366 517 <li>multiply the accumulated matrix with the <a href="#TermTransformationMatrix"><i>transformation matrix</i></a>.</li>
simon@4365 518 </ol>
simon@4345 519 </li>
simon@4345 520 </ol>
simon@4366 521
simon@4345 522 <div class="example">
simon@4345 523 <pre>
simon@4364 524 &lt;style&gt;
dschulze@4602 525 div {
dschulze@4602 526 height: 150px;
dschulze@4602 527 width: 150px;
dschulze@4602 528 }
dschulze@4602 529 .container {
dschulze@4602 530 perspective: 500px;
dschulze@4602 531 border: 1px solid black;
dschulze@4602 532 }
dschulze@4602 533 .transformed {
dschulze@4602 534 <b>transform-style: preserve-3d</b>;
dschulze@4602 535 transform: rotateY(50deg);
dschulze@4602 536 background-color: blue;
dschulze@4602 537 }
dschulze@4602 538 .child {
dschulze@4602 539 transform-origin: top left;
dschulze@4602 540 transform: rotateX(40deg);
dschulze@4602 541 background-color: lime;
dschulze@4602 542 }
simon@4364 543 &lt;/style&gt;
simon@4345 544 </pre>
dschulze@4602 545 <p>This example is identical to the previous example, with the addition of '<code class="css">transform-style: preserve-3d</code>' on the blue element. The blue element now establishes a 3D rendering context, of which the lime element is a member. Now both blue and lime elements share a common three-dimensional space, so the lime element renders as tilting out from its parent, influenced by the perspective on the container.
simon@4345 546 </p>
simon@4345 547 <div class="figure">
simon@4364 548 <img src="examples/3d-rendering-context-3d.png" width="240" height="200" alt="Nested 3D transforms, with preserve-3d.">
simon@4345 549 </div>
simon@4345 550 </div>
simon@4345 551
simon@4366 552 <p>
simon@4701 553 Elements in the same <span class="term">3D rendering context</span> may intersect with each other. User agents must
simon@4702 554 render intersection by subdividing the planes of intersecting elements as described by
simon@4701 555 <a href="http://en.wikipedia.org/wiki/Newell's_algorithm">Newell's algorithm</a>.
simon@4366 556 </p>
simon@4366 557 <p>
simon@4366 558 Untransformed elements in a <span class="term">3D rendering context</span> render on the Z=0 plane, yet may still
simon@4366 559 intersect with transformed elements.
simon@4366 560 </p>
simon@4366 561 <p>
simon@4366 562 Within a <span class="term">3D rendering context</span>, the rendering order of non-intersecting elements is
simon@4366 563 based on their position on the Z axis after the application of the accumulated transform. Elements at the same
simon@4366 564 Z position render in <a href="http://www.w3.org/TR/CSS2/zindex.html#painting-order">stacking context order</a>.
simon@4366 565 </p>
simon@4366 566
simon@4364 567 <div class="example">
simon@4345 568 <pre>
simon@4364 569 &lt;style&gt;
simon@4364 570 .container {
simon@4364 571 background-color: rgba(0, 0, 0, 0.3);
simon@4364 572 transform-style: preserve-3d;
simon@4364 573 perspective: 500px;
simon@4364 574 }
simon@4364 575 .container > div {
simon@4364 576 position: absolute;
simon@4364 577 left: 0;
simon@4364 578 }
simon@4364 579 .container > :first-child {
simon@4364 580 transform: rotateY(45deg);
simon@4364 581 background-color: orange;
simon@4364 582 top: 10px;
simon@4364 583 height: 135px;
simon@4364 584 }
simon@4364 585 .container > :last-child {
simon@4364 586 transform: translateZ(40px);
simon@4364 587 background-color: rgba(0, 0, 255, 0.75);
simon@4364 588 top: 50px;
simon@4364 589 height: 100px;
simon@4364 590 }
simon@4364 591 &lt;/style&gt;
simon@4364 592
simon@4364 593 &lt;div class="container"&gt;
simon@4364 594 &lt;div&gt;&lt;/div&gt;
simon@4364 595 &lt;div&gt;&lt;/div&gt;
simon@4364 596 &lt;/div&gt;
simon@4345 597 </pre>
simon@4364 598 <p>
simon@4364 599 This example shows show elements in a 3D rendering context can intersect. The container element establishes
simon@4364 600 a 3D rendering context for itself and its two children. The children intersect with eachother, and
simon@4364 601 the orange element also intersects with the container.
simon@4364 602 </p>
simon@4364 603 <div class="figure">
simon@4364 604 <img src="examples/3d-intersection.png" width="200" height="200" alt="Intersecting sibling elements.">
simon@4364 605 </div>
simon@4345 606 </div>
simon@4367 607
simon@4367 608 <p>
simon@4367 609 Using three-dimensional transforms, it's possible to transform an element such that its reverse side
simon@4367 610 is towards the viewer. 3D-tranformed elements show the same content on both sides, so the reverse side
simon@4701 611 looks like a mirror-image of the front side (as if the element were projected onto a sheet of glass).
simon@4367 612 Normally, elements whose reverse side is towards the viewer remain visible. However, the
dschulze@4602 613 '<code class="property">backface-visibility</code>' property allows the author to make an element invisible
simon@4367 614 when its reverse side is towards the viewer. This behavior is "live"; if an element with
dschulze@4602 615 '<code class="css">backface-visibility: hidden</code>' were animating,
simon@4367 616 such that its front and reverse sides were alternately visible, then it would only be visible when the
simon@4367 617 front side were towards the viewer.
simon@4367 618 </p>
simon@4364 619
simon@4345 620 <!-- ======================================================================================================= -->
dschulze@4321 621
vhardy@3672 622 <h2 id="transform-property">
dschulze@4602 623 The '<code class="property">transform</code>' Property
vhardy@3672 624 </h2>
vhardy@3672 625 <p>
simon@4345 626 A transformation is applied to the coordinate system an element
dschulze@4602 627 renders in through the '<code class="property">transform</code>' property. This property contains a
vhardy@3672 628 list of <a href="#transform-functions">transform functions</a>. The
vhardy@3672 629 final transformation value for a coordinate system is obtained by converting
dschulze@4511 630 each function in the list to its corresponding matrix like defined in <a href="#mathematical-description">Mathematical
dschulze@4511 631 Description of Transformation Functions</a>, then multiplying the matrices.
vhardy@3672 632 </p>
vhardy@3672 633 <table class="propdef">
vhardy@3672 634 <tbody>
vhardy@3672 635 <tr>
vhardy@3672 636 <td>
vhardy@3672 637 <em>Name:</em>
vhardy@3672 638 </td>
vhardy@3672 639 <td>
vhardy@3672 640 <dfn id="effects">transform</dfn>
vhardy@3672 641 </td>
vhardy@3672 642 </tr>
vhardy@3672 643 <tr>
vhardy@3672 644 <td>
vhardy@3672 645 <em>Value:</em>
vhardy@3672 646 </td>
vhardy@3672 647 <td>
vhardy@3672 648 none | &lt;transform-function&gt; [ &lt;transform-function&gt; ]*
vhardy@3672 649 </td>
vhardy@3672 650 </tr>
vhardy@3672 651 <tr>
vhardy@3672 652 <td>
vhardy@3672 653 <em>Initial:</em>
vhardy@3672 654 </td>
vhardy@3672 655 <td>
vhardy@3672 656 none
vhardy@3672 657 </td>
vhardy@3672 658 </tr>
vhardy@3672 659 <tr>
vhardy@3672 660 <td>
vhardy@3672 661 <em>Applies&nbsp;to:</em>
vhardy@3672 662 </td>
vhardy@3672 663 <td>
dschulze@4321 664 <a href="#TermTransformableElement">transformable elements</a>
vhardy@3672 665 </td>
vhardy@3672 666 </tr>
vhardy@3672 667 <tr>
vhardy@3672 668 <td>
vhardy@3672 669 <em>Inherited:</em>
vhardy@3672 670 </td>
vhardy@3672 671 <td>
vhardy@3672 672 no
vhardy@3672 673 </td>
vhardy@3672 674 </tr>
vhardy@3672 675 <tr>
vhardy@3672 676 <td>
vhardy@3672 677 <em>Percentages:</em>
vhardy@3672 678 </td>
vhardy@3672 679 <td>
dschulze@4483 680 refer to the size of the element's bounding box
vhardy@3672 681 </td>
vhardy@3672 682 </tr>
vhardy@3672 683 <tr>
vhardy@3672 684 <td>
vhardy@3672 685 <em>Media:</em>
vhardy@3672 686 </td>
vhardy@3672 687 <td>
vhardy@3672 688 visual
vhardy@3672 689 </td>
vhardy@3672 690 </tr>
vhardy@3672 691 <tr>
vhardy@3672 692 <td>
vhardy@3672 693 <em>Computed value:</em>
vhardy@3672 694 </td>
vhardy@3672 695 <td>
simon@4334 696 See below.
vhardy@3672 697 </td>
vhardy@3672 698 </tr>
vhardy@3672 699 </tbody>
simon@4334 700 </table>
simon@4334 701
simon@4366 702 <div class="issue">
simon@4345 703 <p class="desc">We need to resolve whether the computed value is the same as the specified value, or matrix().</p>
simon@4345 704 </div>
simon@4334 705 <p>The computed value of the transform property is a matrix() or matrix3d() value that describes the matrix that results from concatenating the individual transform functions. If the resulting matrix can be represented as a two-dimensional matrix with no loss of information, then a matrix() value is returned, otherwise a matrix3d() value. For elements with no transform applied, the computed value is 'none'.</p>
simon@4345 706
dschulze@4602 707 <p>Any value other than '<code class="css">none</code>' for the transform results in the creation of both a stacking context and a containing block. The object acts as a containing block for fixed positioned descendants.</p>
simon@4363 708
simon@4334 709 <!-- ======================================================================================================= -->
vhardy@3672 710
dschulze@4598 711 <h2 id="svg-transform">
dschulze@4602 712 The SVG '<code class="property">transform</code>' Attribute
dschulze@4598 713 </h2>
vhardy@3672 714
dschulze@4598 715 <p>
dschulze@4598 716 The <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/">SVG 1.1 specification</a> did not
dschulze@4602 717 specify the attributes '<code class="property">transform</code>', 'gradientTransform' or 'patternTransform' as
dschulze@4602 718 <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/styling.html#UsingPresentationAttributes"><em>presentation attributes</em></a>.
dschulze@4598 719 In order to improve the integration of SVG and HTML, this specification makes these SVG attributes to
dschulze@4602 720 'presentation attributes' and makes the '<code class="property">transform</code>' property one that applies to <span class="term">transformable elements</span> in the SVG namespace.
dschulze@4598 721 </p>
vhardy@3672 722
dschulze@4598 723 <p>
dschulze@4602 724 This specification will also introduce the new presentation attributes '<code class="property">transform-origin</code>',
dschulze@4602 725 '<code class="property">perspective</code>', '<code class="property">perspective-origin</code>',
dschulze@4602 726 '<code class="property">transform-style</code>' and '<code class="property">backface-visibility</code>'
dschulze@4598 727 in the SVG namespace. All new introduced presentation attributes are animateable.
dschulze@4598 728 </p>
dschulze@4598 729
dschulze@4602 730 <h3 id="transform-attribute-specificity">SVG '<code class="property">transform</code>' attribute specificity</h3>
dschulze@4598 731
dschulze@4598 732 <p>Since the previously named SVG attributes become presentation attributes, their participation to the CSS
vhardy@3672 733 cascade is determined by the specificity of presentation attributes, as
vhardy@3672 734 <a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/styling.html#UsingPresentationAttributes">explained</a>
dschulze@4598 735 in the SVG specification.
dschulze@4598 736 </p>
dschulze@4598 737
dschulze@4598 738 <div class="example">
dschulze@4598 739 <p>
dschulze@4602 740 This example shows the combination of the '<code class="property">transform</code>' style property and the '<code class="property">transform</code>' presentation attribute.
dschulze@4598 741 </p>
dschulze@4598 742
dschulze@4598 743 <pre>&lt;svg&gt;
dschulze@4598 744 &lt;style&gt;
dschulze@4598 745 .container {
dschulze@4598 746 transform: translate(100px, 100px);
dschulze@4598 747 }
dschulze@4598 748 &lt;/style&gt;
dschulze@4598 749
dschulze@4598 750 &lt;g class="container" transform="translate (200 200)"&gt;
dschulze@4598 751 &lt;rect width="100" height="100" fill="blue" /&gt;
dschulze@4598 752 &lt;/g&gt;
dschulze@4598 753 &lt;/svg&gt;</pre>
dschulze@4598 754
dschulze@4598 755 <div class="figure">
dschulze@4598 756 <img src="examples/svg-translate.png" width="200" height="200" alt="Translated SVG container element.">
dschulze@4598 757 </div>
dschulze@4598 758
dschulze@4598 759 <p>
dschulze@4602 760 Because of the participation to the CSS cascade, the '<code class="property">transform</code>' style property overrides the
dschulze@4602 761 '<code class="property">transform</code>' presentation attribute. Therefore the container gets translated by '<code class="css">100px</code>' in horizontal and vertical direction, instead of '<code class="css">200px</code>'.
dschulze@4598 762 </p>
dschulze@4598 763 </div>
dschulze@4598 764
dschulze@4602 765 <h3 id="svg-syntax">Syntax of the SVG '<code class="property">transform</code>' attribute</h3>
dschulze@4598 766
dschulze@4598 767 <p>
dschulze@4602 768 To provide backward compatibility, the syntax of the '<code class="property">transform</code>' presentation attribute differs from
dschulze@4602 769 the syntax of the '<code class="property">transform</code>' style property like shown in the example above. However, the syntax
dschulze@4602 770 used for the '<code class="property">transform</code>' style property can be used for a '<code class="property">transform</code>' presentation attribute value.
dschulze@4598 771 Authors are advised to follow the rules of <a href="http://www.w3.org/TR/css3-values/#functional-notation">CSS Values and Units Module</a>.
dschulze@4602 772 Therefore an author should write '<code class="css">transform="translate(200px, 200px)"</code>' instead of
dschulze@4602 773 '<code class="css">transform="translate (200 200)"</code>' because the second example with the spaces before the '<code class="css">(</code>',
dschulze@4598 774 the missing comma between the arguments and the values without the explicit unit notation would be valid for
dschulze@4598 775 the attribute only.
dschulze@4598 776 </p>
dschulze@4598 777
dschulze@4598 778 <h4 id="svg-transform-list">Transform List</h4>
dschulze@4598 779
dschulze@4598 780 <p>
dschulze@4602 781 The value for the '<code class="property">transform</code>' attribute consists of a transform list with zero or more transform functions
dschulze@4598 782 in the <a href="#svg-functional-notation">functional notation</a>. If the transform list consists of more than one
dschulze@4602 783 transform function, these functions are separated by either a comma (‘<code class="css">,</code>’) with optional whitespace
dschulze@4598 784 before and after the comma or one or more whitespaces. The transform list can have
dschulze@4598 785 optional whitespaces before and after the list.
dschulze@4598 786 </p>
dschulze@4598 787
dschulze@4598 788 <h4 id="svg-functional-notation">Functional Notations</h4>
dschulze@4598 789
dschulze@4598 790 <p>
dschulze@4598 791 The syntax starts with the name of the function followed by optional whitespaces followed by a left
dschulze@4598 792 parenthesis followed by optional whitespace followed by the argument(s) to the notation followed by
dschulze@4598 793 optional whitespace followed by a right parenthesis. If a function takes more than one argument, the
dschulze@4602 794 arguments are either separated by a comma (‘<code class="css">,</code>’) with optional whitespace before and after the comma
dschulze@4598 795 or one or more whitespaces.
dschulze@4598 796 </p>
dschulze@4598 797
dschulze@4598 798 <h4 id="svg-data-types">SVG Data Types</h4>
dschulze@4598 799
dschulze@4598 800 <p>
dschulze@4601 801 Arguments of transform functions consists of data types in the sense of
dschulze@4598 802 <a href="http://www.w3.org/TR/css3-values/#functional-notation">CSS Values and Units Module</a>. The definitions of
dschulze@4598 803 data types in CSS Values and Units Module gets enhanced as follows:
dschulze@4598 804 </p>
dschulze@4598 805
dschulze@4602 806 <h5 id="svg-transform-value">The <var>&lt;translation-value&gt;</var> and <var>&lt;length&gt;</var> type</h5>
dschulze@4598 807
dschulze@4598 808 <p>
dschulze@4602 809 A translation-value or length can be a <var>&lt;number&gt;</var> without an unit identifier. In this case
dschulze@4602 810 the <a href="#svg-number"><var>number</var></a> gets interpreted as "user unit". A user unit in the the
dschulze@4598 811 <a href="http://www.w3.org/TR/2003/REC-SVG11-20030114/coords.html#InitialCoordinateSystem">initial
dschulze@4602 812 coordinate system</a> is equivalenced to the parent environment's notion of a pixel unit.
dschulze@4598 813 </p>
dschulze@4598 814
dschulze@4602 815 <h5 id="svg-angle">The <var>&lt;angle&gt;</var> type</h5>
dschulze@4598 816
dschulze@4598 817 <p>
dschulze@4602 818 An angle can be a <var>&lt;number&gt;</var> without an unit identifier. In this case the <a href="#svg-number"><i>number</i></a>
dschulze@4598 819 gets interpreted as a value in degrees.
dschulze@4598 820 </p>
dschulze@4598 821
dschulze@4602 822 <h5 id="svg-number">The <var>&lt;number&gt;</var> type</h5>
dschulze@4598 823
dschulze@4598 824 <p>
dschulze@4602 825 SVG supports scientific notations for numbers. Therefore a <var>number</var> gets parsed like described in SVG
dschulze@4598 826 <a href="http://www.w3.org/TR/SVG/types.html#DataTypeNumber">Basic data types</a> for SVG attributes.
dschulze@4598 827 </p>
dschulze@4598 828
dschulze@4598 829 <h3 id="svg-gradient-transform-pattern-transform">The SVG 'gradientTransform' and 'patternTransform' attributes</h3>
dschulze@4598 830
dschulze@4598 831 <p>
dschulze@4598 832 SVG specifies the attributes 'gradientTransform' and 'patternTransform'. This specification
dschulze@4598 833 makes both attributes to presentation attributes. Both attributes use the same <a href="#svg-syntax">syntax</a> as
dschulze@4602 834 the SVG '<code class="property">transform</code>' attribute. This specification won't introduce corresponding CSS style properties. Instead the
dschulze@4602 835 style can be set by the '<code class="property">transform</code>' style property.
dschulze@4598 836 </p>
dschulze@4598 837
dschulze@4598 838 <h3 id="svg-transformation-functions">SVG transformation functions</h3>
dschulze@4598 839
dschulze@4598 840 <p>
dschulze@4601 841 For backward compatibility to existing SVG content, this specification must support all transform functions
dschulze@4602 842 defined by <a href="http://www.w3.org/TR/SVG/coords.html#TransformAttribute">The '<code class="property">transform</code>' attribute</a> in SVG 1.1.
dschulze@4602 843 Therefore the two-dimensional transform function '<code class="css">rotate(&lt;angle&gt;)</code>' gets extended as follows:
dschulze@4598 844 </p>
dschulze@4598 845
dschulze@4598 846 <dl>
dschulze@4598 847 <dt>
dschulze@4598 848 <code class="css">rotate(&lt;angle&gt;[, &lt;translation-value&gt;, &lt;translation-value&gt;])</code>
dschulze@4598 849 </dt>
dschulze@4598 850 <dd>
dschulze@4598 851 specifies a <a href="#RotateDefined">2D rotation</a> by the angle specified in the parameter about the origin of the element, as defined
dschulze@4602 852 by the '<code class="property">transform-origin</code>' property. If the optional translation values are specified, the transform origin is translated by that amount
dschulze@4598 853 (using the current transformation matrix) for the duration of the rotate operation.
dschulze@4602 854 For example '<code class="css">rotate(90deg, 100px, 100px)</code>' would elements cause to appear rotated one-quarter of a turn in the clockwise direction after a translation
dschulze@4602 855 of 100 pixel in the vertical and horizontal direction.
dschulze@4598 856 </dd>
dschulze@4598 857 </dl>
dschulze@4598 858
dschulze@4598 859 <p>
dschulze@4598 860 User agents are just required to support the two optional arguments for translation on elements in the SVG namespace.
dschulze@4598 861 </p>
dschulze@4601 862
dschulze@4601 863 <h3 id="svg-three-dimensional-functions">SVG and 3D transformation functions</h3>
dschulze@4601 864
dschulze@4601 865 <p>
dschulze@4601 866 This specification explicitly allows to apply three-dimensional transform functions to the
dschulze@4602 867 <a href="http://www.w3.org/TR/SVG/intro.html#TermContainerElement"><em>container elements</em></a>:
dschulze@4602 868 'a', 'g', 'svg', all <a href="http://www.w3.org/TR/SVG/intro.html#TermGraphicsElement"><em>graphics elements</em></a>, all
dschulze@4602 869 <a href="http://www.w3.org/TR/SVG/intro.html#TermGraphicsReferencingElement"><em>graphics referencing elements</em></a>
dschulze@4601 870 and the SVG <a href="http://www.w3.org/TR/SVG/extend.html#ForeignObjectElement">'foreignObject'</a> element.
dschulze@4601 871 </p>
dschulze@4601 872
dschulze@4601 873 <p>
dschulze@4602 874 Three-dimensional transform functions and the properties '<code class="property">perspective</code>',
dschulze@4602 875 '<code class="property">perspective-origin</code>', '<code class="property">transform-style</code>'
dschulze@4602 876 and '<code class="property">backface-visibility</code>' can not be used for the elements: 'clipPath', 'mask', 'linearGradient',
dschulze@4601 877 'radialGradient' and 'pattern'. If a transform list includes a three-dimensional transform function, the complete
dschulze@4601 878 transform list must be ignored. The values of every previously named property must be ignored.
dschulze@4602 879 <span class="term">Transformable elements</span> that are contained by one of these elements can have three-dimensional transform functions.
dschulze@4601 880 Before a 'clipPath', 'mask' or 'pattern' element can get applied to a target element, user agents must take the drawn results as static
dschulze@4601 881 images in analogue of "flattening" the elements and taking the rendered content as a two-dimensional canvas.
dschulze@4601 882 </p>
dschulze@4598 883
dschulze@4598 884 <h3 id="svg-object-bounding-box">Object bounding box units</h3>
dschulze@4598 885
dschulze@4598 886 <p>
dschulze@4598 887 Percentage or fractional values in SVG are either relative to the elements viewport units or to the elements
dschulze@4598 888 <a href="http://www.w3.org/TR/SVG/coords.html#ObjectBoundingBoxUnits">object bounding box units</a> like
dschulze@4598 889 specified in SVG 1.1. To align with HTML, all percentage values for all properties defined in this specification
dschulze@4598 890 are relative to the object bounding box units.
dschulze@4598 891 </p>
dschulze@4598 892
dschulze@4598 893 <p>
dschulze@4598 894 If an SVG element does not provide an object bounding box (like for the 'pattern', 'mask' or 'clipPath' elements), the bounding box
dschulze@4598 895 is the same like if the position x, y and the dimensions width and height are zero. Percentage values or keywords won't affect the
dschulze@4601 896 rendering and are treated as if zero was specified.
dschulze@4598 897 </p>
dschulze@4598 898
dschulze@4598 899 <div class="example">
dschulze@4598 900 <p>
dschulze@4602 901 The '<code class="property">transform-origin</code>' property on the pattern in the following example specifies a '<code class="css">50%</code>' translation of the origin in the horizontal and vertical dimension.
dschulze@4602 902 The '<code class="property">transform</code>' property specifies a translation as well, but in absolute lengths.
dschulze@4598 903 </p>
dschulze@4598 904
dschulze@4598 905 <pre>&lt;svg&gt;
dschulze@4598 906 &lt;style&gt;
dschulze@4598 907 pattern {
dschulze@4598 908 transform: translate(50px, 50px) rotate(45deg);
dschulze@4598 909 transform-origin: 50% 50%;
dschulze@4598 910 }
dschulze@4598 911 &lt;/style&gt;
dschulze@4598 912
dschulze@4598 913 &lt;defs&gt;
dschulze@4598 914 &lt;pattern id="pattern-1"&gt;
dschulze@4598 915 &lt;rect id="rect1" width="100" height="100" fill="blue" /&gt;
dschulze@4598 916 &lt;/pattern&gt;
dschulze@4598 917 &lt;/defs&gt;
dschulze@4598 918
dschulze@4598 919 &lt;rect width="100" height="100" fill="url(#pattern-1)" /&gt;
dschulze@4598 920 &lt;/svg&gt;</pre>
dschulze@4598 921
dschulze@4598 922 <p>
dschulze@4601 923 A SVG 'pattern' element doesn't have an object bounding box. Therefore the relative values of the
dschulze@4602 924 '<code class="property">transform-origin</code>' property don't affect the rendering and are treated
dschulze@4602 925 as if zero was specified. The translation on the '<code class="property">transform</code>' property is in
dschulze@4598 926 absolute coordinates and translate the coordinate system by 50 pixel in each direction.
dschulze@4598 927 </p>
dschulze@4598 928 </div>
dschulze@4598 929
dschulze@4602 930 <h3 id="transform-attribute-dom">SVG DOM interface for the '<code class="property">transform</code>' attribute</h3>
dschulze@4598 931
dschulze@4598 932 <p>
dschulze@4601 933 The SVG specification defines the
dschulze@4602 934 '<a href="http://www.w3.org/TR/2011/REC-SVG11-20110816/coords.html#InterfaceSVGAnimatedTransformList"><code class="property">SVGAnimatedTransformList</code></a>'
dschulze@4601 935 interface in SVG DOM to access the animated and the base value of the SVG transform attribute. To ensure backwards compatibility,
dschulze@4601 936 this API must still be supported by user agents.
dschulze@4598 937 </p>
dschulze@4598 938
dschulze@4601 939 <p>
dschulze@4602 940 The '<code class="property">transform</code>' property contributes to the CSS cascade. According to SVG 1.1 user agents conceptually insert a
dschulze@4601 941 <a href="http://www.w3.org/TR/SVG/styling.html#UsingPresentationAttributes">new author
dschulze@4601 942 style sheet</a> for presentation attributes, which is the first in the author style sheet collection.
dschulze@4602 943 '<code class="property">baseVal</code>' gives the author the possibility to access and modify the values of the SVG '<code class="property">transform</code>' attribute.
dschulze@4602 944 To provide the necessary backward compatibility to SVG DOM, '<code class="property">baseVal</code>' must reflect the values of this author style sheet.
dschulze@4602 945 All modifications to SVG DOM objects of '<code class="property">baseVal</code>' must affect this author style sheet immediately.
dschulze@4601 946 </p>
dschulze@4601 947
dschulze@4601 948 <p>
dschulze@4602 949 '<code class="property">animVal</code>' represents the computed style of the '<code class="property">transform</code>' property. Therefore it includes all applied
dschulze@4601 950 <a href="http://www.w3.org/TR/css3-transitions/">CSS3 Transitions</a>, <a href="http://www.w3.org/TR/css3-animations/">CSS3
dschulze@4601 951 Animations</a> or <a href="#svg-animation">SVG Animations</a> if any of those are underway. The computed style and SVG DOM
dschulze@4602 952 objects of '<code class="property">animVal</code>' can not be modified.
dschulze@4601 953 </p>
dschulze@4601 954
dschulze@4601 955 <p>
dschulze@4602 956 The attribute '<a href="http://www.w3.org/TR/SVG/coords.html#__svg__SVGTransform__type"><code class="property">type</code></a>' of
dschulze@4602 957 <a href="http://www.w3.org/TR/SVG/coords.html#InterfaceSVGTransform">'SVGTransform'</a>
dschulze@4602 958 must return '<a href="http://www.w3.org/TR/SVG/coords.html#__svg__SVGTransform__SVG_TRANSFORM_UNKNOWN">
dschulze@4602 959 <code class="css">SVG_TRANSFORM_UNKNOWN</code></a>' for <a href="#transformation-functions">Transformation Functions</a> or unit types that
dschulze@4601 960 are not supported by this interface. It might still be possible to get the
dschulze@4602 961 '<a href="http://www.w3.org/TR/SVG/coords.html#InterfaceSVGMatrix"><code class="property">SVGMatrix</code></a>' by the attribute
dschulze@4602 962 '<a href="http://www.w3.org/TR/SVG/coords.html#__svg__SVGTransform__matrix"><code class="property">matrix</code></a>'.
dschulze@4601 963 </p>
vhardy@3672 964
dschulze@4598 965 <h3 id="svg-animation">SVG Animation</h3>
vhardy@3672 966
dschulze@4598 967 <h4 id="svg-animate-element">The SVG 'animate' and 'set' element</h4>
dschulze@4598 968
dschulze@4598 969 <p>
dschulze@4602 970 The SVG 1.1 specification did not define animations of the '<code class="property">transform</code>' attribute for the SVG
dschulze@4601 971 <a href="http://www.w3.org/TR/SVG/animate.html#AnimateElement">'animate'</a> element or the SVG
dschulze@4601 972 <a href="http://www.w3.org/TR/SVG/animate.html#SetElement">'set'</a> element.
dschulze@4602 973 This specification explicitly allows the animation of the presentation attributes '<code class="property">transform</code>', 'gradientTransform' and 'patternTransform'
dschulze@4598 974 for the 'animate' and 'set' elements. SVG animation must run the same animation steps as described in section
dschulze@4598 975 <a href="#animation">Transitions and Animations between Transform Values</a>.
dschulze@4598 976 </p>
dschulze@4598 977
dschulze@4598 978 <h4 id="svg-attribute-name">The SVG 'attributeName' attribute</h4>
dschulze@4598 979
dschulze@4598 980 <p>
dschulze@4598 981 <a href="http://www.w3.org/TR/SVG/animate.html">SVG 1.1 Animation</a> defines the <a href="http://www.w3.org/TR/SVG/animate.html#TargetAttributes">'attributeName'</a> attribute to specify the
dschulze@4598 982 name of the target attribute. For the presentation attributes 'gradientTransform' and 'patternTransform' it will also be possible to use
dschulze@4602 983 the value '<code class="property">transform</code>'. The same presentation attribute style will get animated.
dschulze@4598 984 </p>
dschulze@4598 985
dschulze@4598 986 <div class="example">
dschulze@4598 987 <p>
dschulze@4598 988 In this example the gradient transformation of the linear gradient gets animated.
dschulze@4598 989 </p>
dschulze@4598 990
dschulze@4598 991 <pre>&lt;linearGradient gradientTransform="scale(2)"&gt;
dschulze@4598 992 &lt;animate attributeName="gradientTransform" from="scale(2)" to="scale(4)"
dschulze@4598 993 dur="3s" additive="sum"/&gt;
dschulze@4598 994 &lt;animate attributeName="transform" from="translate(0, 0)" to="translate(100px, 100px)"
dschulze@4598 995 dur="3s" additive="sum"/&gt;
dschulze@4598 996 &lt;/linearGradient&gt;</pre>
dschulze@4598 997
dschulze@4598 998 <p>The 'linearGradient' element specifies the 'gradientTransform' presentation attribute. The two 'animate' elements address the target attribute
dschulze@4602 999 'gradientTransform' and '<code class="property">transform</code>'. Even so all animations apply to the same gradient transformation by taking the value of the 'gradientTransform'
dschulze@4598 1000 presentation attribute, applying the scaling of the first animation and applying the translation of the second animation one after the other.</p>
vhardy@3672 1001 </div>
vhardy@3672 1002
dschulze@4598 1003 <h4 id="svg-attribute-type">The SVG 'attributeType' attribute</h4>
dschulze@4598 1004
dschulze@4598 1005 <p>
dschulze@4598 1006 <a href="http://www.w3.org/TR/SVG/animate.html">SVG 1.1 Animation</a> defines the <a href="http://www.w3.org/TR/SVG/animate.html#TargetAttributes">'attributeType'</a> attribute to specify the
dschulze@4602 1007 namespace in which the target attribute and its associated values are defined. The attribute can have the values '<code class="css">CSS</code>', '<code class="css">XML</code>' or
dschulze@4602 1008 '<code class="css">auto</code>', where '<code class="css">auto</code>' is the default value.
dschulze@4598 1009 </p>
dschulze@4598 1010
dschulze@4598 1011 <p>
dschulze@4602 1012 However, in the combination with the '<code class="property">transform</code>', 'patternTransform' and 'gradientTransform' presentation attributes, 'attributeType'
dschulze@4602 1013 can just be used to indicate the syntax rules used for the transform attribute values. A value of '<code class="css">CSS</code>' indicates that the transform values should
dschulze@4602 1014 be parsed according to the CSS syntax. A value of '<code class="css">XML</code>' indicates that the transform values should be parsed according to the
dschulze@4602 1015 SVG '<code class="property">transform</code>' <a href="#svg-syntax">syntax</a>.
dschulze@4598 1016 </p>
dschulze@4598 1017
dschulze@4598 1018 <p>
dschulze@4602 1019 User agents are recommended to use the more tolerant SVG '<code class="property">transform</code>' <a href="#svg-syntax">syntax</a> for a value of '<code class="css">auto</code>' to parse transform values.
dschulze@4598 1020 </p>
dschulze@4598 1021
dschulze@4598 1022 <h4 id="svg-animateTransform-extension">The SVG 'animateTransform' element</h4>
dschulze@4598 1023
dschulze@4598 1024 <p>
dschulze@4601 1025 This specification introduces new transform functions that are not supported by <a href="http://www.w3.org/TR/SVG/animate.html">SVG 1.1 Animation</a>. The
dschulze@4602 1026 SVG '<a href="http://www.w3.org/TR/SVG/animate.html#AnimateTransformElement"><code class="property">type</code></a>' attribute gets extended by all
dschulze@4601 1027 transform functions listed in <a href="#two-d-transform-functions">2D Transformation Functions</a>,
dschulze@4598 1028 <a href="#three-d-transform-functions">3D Transformation Functions</a> and <a href="#svg-transformation-functions">SVG
dschulze@4598 1029 Transformation Functions</a>.
dschulze@4598 1030 </p>
dschulze@4598 1031
simon@4345 1032 <!-- ======================================================================================================= -->
simon@4345 1033
vhardy@3672 1034 <h2 id="transform-origin-property">
dschulze@4602 1035 The '<code class="property">transform-origin</code>' Property
vhardy@3672 1036 </h2>
vhardy@3672 1037 <table class="propdef">
vhardy@3672 1038 <tbody>
vhardy@3672 1039 <tr>
vhardy@3672 1040 <td>
vhardy@3672 1041 <em>Name:</em>
vhardy@3672 1042 </td>
vhardy@3672 1043 <td>
vhardy@3672 1044 <dfn id="transform-origin">transform-origin</dfn>
vhardy@3672 1045 </td>
vhardy@3672 1046 </tr>
vhardy@3672 1047 <tr>
vhardy@3672 1048 <td>
vhardy@3672 1049 <em>Value:</em>
vhardy@3672 1050 </td>
vhardy@3672 1051 <td>
ayg@4703 1052 [ &lt;percentage> | &lt;length> | left | center | right | top | bottom]<br>
ayg@4703 1053 |<br>
ayg@4703 1054 [<br>
ayg@4703 1055 &nbsp;&nbsp;[ &lt;percentage> | &lt;length&gt; | left | center | right ]<br>
ayg@4703 1056 &nbsp;&nbsp;&amp;&amp;<br>
ayg@4703 1057 &nbsp;&nbsp;[ &lt;percentage> | &lt;length&gt; | top | center | bottom ]<br>
ayg@4703 1058 ] &lt;length&gt;?<br>
vhardy@3672 1059 </td>
vhardy@3672 1060 </tr>
vhardy@3672 1061 <tr>
vhardy@3672 1062 <td>
vhardy@3672 1063 <em>Initial:</em>
vhardy@3672 1064 </td>
vhardy@3672 1065 <td>
dschulze@4483 1066 0 0 for SVG elements without associated CSS layout box, 50% 50% for all other elements
vhardy@3672 1067 </td>
vhardy@3672 1068 </tr>
vhardy@3672 1069 <tr>
vhardy@3672 1070 <td>
vhardy@3672 1071 <em>Applies&nbsp;to:</em>
vhardy@3672 1072 </td>
vhardy@3672 1073 <td>
simon@4366 1074 <a href="#TermTransformableElement">transformable elements</a>
vhardy@3672 1075 </td>
vhardy@3672 1076 </tr>
vhardy@3672 1077 <tr>
vhardy@3672 1078 <td>
vhardy@3672 1079 <em>Inherited:</em>
vhardy@3672 1080 </td>
vhardy@3672 1081 <td>
vhardy@3672 1082 no
vhardy@3672 1083 </td>
vhardy@3672 1084 </tr>
vhardy@3672 1085 <tr>
vhardy@3672 1086 <td>
vhardy@3672 1087 <em>Percentages:</em>
vhardy@3672 1088 </td>
vhardy@3672 1089 <td>
dschulze@4483 1090 refer to the size of the element's bounding box
vhardy@3672 1091 </td>
vhardy@3672 1092 </tr>
vhardy@3672 1093 <tr>
vhardy@3672 1094 <td>
vhardy@3672 1095 <em>Media:</em>
vhardy@3672 1096 </td>
vhardy@3672 1097 <td>
vhardy@3672 1098 visual
vhardy@3672 1099 </td>
vhardy@3672 1100 </tr>
vhardy@3672 1101 <tr>
vhardy@3672 1102 <td>
vhardy@3672 1103 <em>Computed value:</em>
vhardy@3672 1104 </td>
vhardy@3672 1105 <td>
vhardy@3672 1106 For &lt;length&gt; the absolute value, otherwise a percentage
vhardy@3672 1107 </td>
vhardy@3672 1108 </tr>
vhardy@3672 1109 </tbody>
vhardy@3672 1110 </table>
simon@4366 1111
simon@4366 1112 <p>
dschulze@4602 1113 The values of the '<code class="property">transform</code>' and
dschulze@4602 1114 '<code class="property">transform-origin</code>' properties are used to compute the
simon@4366 1115 <a href="#TermTransformationMatrix"><i>transformation matrix</i></a>, as described above.
simon@4366 1116 </p>
simon@4366 1117
simon@4366 1118 <p>If only one value is specified, the second value is assumed to be
ayg@4703 1119 'center'. If one or two values are specified, the third value is
ayg@4703 1120 assumed to be '0px'.
dschulze@4483 1121 </p>
dschulze@4483 1122
ayg@4703 1123 <p>If at least one of the first two values is not a keyword, then
ayg@4703 1124 the first value represents the horizontal position (or offset)
ayg@4703 1125 and the second represents the vertical position (or offset). The
ayg@4703 1126 third value always represents the Z position (or offset).
ayg@4703 1127 </p>
ayg@4703 1128
ayg@4703 1129 <p><var>&lt;percentage&gt;</var> and <var>&lt;length&gt;</var>
ayg@4703 1130 for the first two values represent an offset of the transform
ayg@4703 1131 origin from the top left corner of the element's bounding box.
ayg@4703 1132 </p>
ayg@4703 1133
dschulze@4483 1134 <p>For SVG elements without an associated CSS layout box the <var>&lt;length&gt;</var>
dschulze@4483 1135 values represent an offset from the point of origin of the element's local coordinate space.
dschulze@4483 1136 </p>
simon@4366 1137
simon@4345 1138 <!-- ======================================================================================================= -->
simon@4345 1139
simon@4345 1140 <h2 id="transform-style-property">
dschulze@4602 1141 The '<code class="property">transform-style</code>' Property
simon@4345 1142 </h2>
simon@4345 1143 <table class="propdef">
simon@4345 1144 <tbody>
simon@4345 1145 <tr>
simon@4345 1146 <td>
simon@4345 1147 <em>Name:</em>
simon@4345 1148 </td>
simon@4345 1149 <td>
simon@4345 1150 <dfn id="transform-style">transform-style</dfn>
simon@4345 1151 </td>
simon@4345 1152 </tr>
simon@4345 1153 <tr>
simon@4345 1154 <td>
simon@4345 1155 <em>Value:</em>
simon@4345 1156 </td>
simon@4345 1157 <td>
simon@4345 1158 flat | preserve-3d
simon@4345 1159 </td>
simon@4345 1160 </tr>
simon@4345 1161 <tr>
simon@4345 1162 <td>
simon@4345 1163 <em>Initial:</em>
simon@4345 1164 </td>
simon@4345 1165 <td>
simon@4345 1166 flat
simon@4345 1167 </td>
simon@4345 1168 </tr>
simon@4345 1169 <tr>
simon@4345 1170 <td>
simon@4345 1171 <em>Applies&nbsp;to:</em>
simon@4345 1172 </td>
simon@4345 1173 <td>
simon@4345 1174 <a href="#TermTransformableElement">transformable elements</a>
simon@4345 1175 </td>
simon@4345 1176 </tr>
simon@4345 1177 <tr>
simon@4345 1178 <td>
simon@4345 1179 <em>Inherited:</em>
simon@4345 1180 </td>
simon@4345 1181 <td>
simon@4345 1182 no
simon@4345 1183 </td>
simon@4345 1184 </tr>
simon@4345 1185 <tr>
simon@4345 1186 <td>
simon@4345 1187 <em>Percentages:</em>
simon@4345 1188 </td>
simon@4345 1189 <td>
simon@4345 1190 N/A
simon@4345 1191 </td>
simon@4345 1192 </tr>
simon@4345 1193 <tr>
simon@4345 1194 <td>
simon@4345 1195 <em>Media:</em>
simon@4345 1196 </td>
simon@4345 1197 <td>
simon@4345 1198 visual
simon@4345 1199 </td>
simon@4345 1200 </tr>
simon@4345 1201 <tr>
simon@4345 1202 <td>
simon@4345 1203 <em>Computed value:</em>
simon@4345 1204 </td>
simon@4345 1205 <td>
simon@4345 1206 Same as specified value.
simon@4345 1207 </td>
simon@4345 1208 </tr>
simon@4345 1209 </tbody>
simon@4345 1210 </table>
simon@4345 1211
simon@4345 1212 <p>
dschulze@4602 1213 A value of '<code class="css">preserve-3d</code>' for '<code class="property">transform-style</code>'
simon@4345 1214 establishes a stacking context.
simon@4345 1215 </p>
simon@4345 1216
simon@4345 1217 <p>
simon@4345 1218 The following CSS property values require the user agent to create a flattened representation of
simon@4345 1219 the descendant elements before they can be applied, and therefore override the behavior of
dschulze@4602 1220 '<code class="property">transform-style</code>': '<code class="css">preserve-3d</code>':
simon@4345 1221 <ul>
dschulze@4602 1222 <li>'<code class="property">overflow</code>': any value other than '<code class="property">visible</code>'.</li>
dschulze@4602 1223 <li>'<code class="property">opacity</code>': any value other than 1.</li>
dschulze@4602 1224 <li>'<code class="property">filter</code>': any value other than '<code class="property">none</code>'.</li>
simon@4345 1225 <!-- Others? -->
simon@4345 1226 </ul>
simon@4345 1227 </p>
simon@4366 1228 <div class="issue">
simon@4366 1229 <p class="desc">Should this affect the computed value of transform-style?</p>
simon@4366 1230 </div>
simon@4366 1231 <p>
dschulze@4602 1232 The values of the '<code class="property">transform</code>' and
dschulze@4602 1233 '<code class="property">transform-origin</code>' properties are used to compute the
simon@4366 1234 <a href="#TermTransformationMatrix"><i>transformation matrix</i></a>, as described above.
simon@4366 1235 </p>
simon@4345 1236
simon@4345 1237 <!-- ======================================================================================================= -->
simon@4345 1238
simon@4345 1239 <h2 id="perspective-property">
dschulze@4602 1240 The '<code class="property">perspective</code>' Property
simon@4345 1241 </h2>
simon@4345 1242 <table class="propdef">
simon@4345 1243 <tbody>
simon@4345 1244 <tr>
simon@4345 1245 <td>
simon@4345 1246 <em>Name:</em>
simon@4345 1247 </td>
simon@4345 1248 <td>
simon@4345 1249 <dfn id="perspective">perspective</dfn>
simon@4345 1250 </td>
simon@4345 1251 </tr>
simon@4345 1252 <tr>
simon@4345 1253 <td>
simon@4345 1254 <em>Value:</em>
simon@4345 1255 </td>
simon@4345 1256 <td>
simon@4345 1257 none | &lt;length&gt;
simon@4345 1258 </td>
simon@4345 1259 </tr>
simon@4345 1260 <tr>
simon@4345 1261 <td>
simon@4345 1262 <em>Initial:</em>
simon@4345 1263 </td>
simon@4345 1264 <td>
simon@4345 1265 none
simon@4345 1266 </td>
simon@4345 1267 </tr>
simon@4345 1268 <tr>
simon@4345 1269 <td>
simon@4345 1270 <em>Applies&nbsp;to:</em>
simon@4345 1271 </td>
simon@4345 1272 <td>
simon@4345 1273 <a href="#TermTransformableElement">transformable elements</a>
simon@4345 1274 </td>
simon@4345 1275 </tr>
simon@4345 1276 <tr>
simon@4345 1277 <td>
simon@4345 1278 <em>Inherited:</em>
simon@4345 1279 </td>
simon@4345 1280 <td>
simon@4345 1281 no
simon@4345 1282 </td>
simon@4345 1283 </tr>
simon@4345 1284 <tr>
simon@4345 1285 <td>
simon@4345 1286 <em>Percentages:</em>
simon@4345 1287 </td>
simon@4345 1288 <td>
simon@4345 1289 N/A
simon@4345 1290 </td>
simon@4345 1291 </tr>
simon@4345 1292 <tr>
simon@4345 1293 <td>
simon@4345 1294 <em>Media:</em>
simon@4345 1295 </td>
simon@4345 1296 <td>
simon@4345 1297 visual
simon@4345 1298 </td>
simon@4345 1299 </tr>
simon@4345 1300 <tr>
simon@4345 1301 <td>
simon@4345 1302 <em>Computed value:</em>
simon@4345 1303 </td>
simon@4345 1304 <td>
simon@4345 1305 Same as specified value.
simon@4345 1306 </td>
simon@4345 1307 </tr>
simon@4345 1308 </tbody>
simon@4345 1309 </table>
simon@4345 1310
simon@4345 1311 <p>
dschulze@4602 1312 If the value is '<code class="css">none</code>', less than or equal to 0 no
simon@4365 1313 perspective transform is applied.
simon@4345 1314 </p>
simon@4345 1315 <p>
dschulze@4602 1316 The use of this property with any value other than '<code class="css">none</code>' establishes a
simon@4345 1317 stacking context. It also establishes a containing block (somewhat
dschulze@4602 1318 similar to '<code class="css">position: relative</code>'), just like the '<code class="property">transform</code>' property does.
simon@4345 1319 </p>
simon@4366 1320 <p>
dschulze@4602 1321 The values of the '<code class="property">perspective</code>' and '<code class="property">perspective-origin</code>'
simon@4366 1322 properties are used to compute the <a href="#TermPerspectiveMatrix"><i>perspective matrix</i></a>, as described above.
simon@4366 1323 </p>
simon@4345 1324
simon@4345 1325 <!-- ======================================================================================================= -->
simon@4345 1326
simon@4345 1327 <h2 id="perspective-origin-property">
dschulze@4602 1328 The '<code class="property">perspective-origin</code>' Property
simon@4345 1329 </h2>
simon@4345 1330 <p>
dschulze@4602 1331 The '<code class="property">perspective-origin</code>' property
simon@4345 1332 establishes the origin for the <em>perspective</em> property. It
simon@4345 1333 effectively sets the X and Y position at which the viewer appears to be
simon@4345 1334 looking at the children of the element.
simon@4345 1335 </p>
simon@4345 1336 <table class="propdef">
simon@4345 1337 <tbody>
simon@4345 1338 <tr>
simon@4345 1339 <td>
simon@4345 1340 <em>Name:</em>
simon@4345 1341 </td>
simon@4345 1342 <td>
simon@4345 1343 <dfn id="perspective-origin">perspective-origin</dfn>
simon@4345 1344 </td>
simon@4345 1345 </tr>
simon@4345 1346 <tr>
simon@4345 1347 <td>
simon@4345 1348 <em>Value:</em>
simon@4345 1349 </td>
simon@4345 1350 <td>
simon@4345 1351 [ [ &lt;percentage&gt; | &lt;length&gt; | left | center | right ] [
simon@4345 1352 &lt;percentage&gt; | &lt;length&gt; | top | center | bottom ]? ] | [ [ left |
simon@4345 1353 center | right ] || [ top | center | bottom ] ]
simon@4345 1354 </td>
simon@4345 1355 </tr>
simon@4345 1356 <tr>
simon@4345 1357 <td>
simon@4345 1358 <em>Initial:</em>
simon@4345 1359 </td>
simon@4345 1360 <td>
simon@4345 1361 50% 50%
simon@4345 1362 </td>
simon@4345 1363 </tr>
simon@4345 1364 <tr>
simon@4345 1365 <td>
simon@4345 1366 <em>Applies&nbsp;to:</em>
simon@4345 1367 </td>
simon@4345 1368 <td>
simon@4345 1369 <a href="#TermTransformableElement">transformable elements</a>
simon@4345 1370 </td>
simon@4345 1371 </tr>
simon@4345 1372 <tr>
simon@4345 1373 <td>
simon@4345 1374 <em>Inherited:</em>
simon@4345 1375 </td>
simon@4345 1376 <td>
simon@4345 1377 no
simon@4345 1378 </td>
simon@4345 1379 </tr>
simon@4345 1380 <tr>
simon@4345 1381 <td>
simon@4345 1382 <em>Percentages:</em>
simon@4345 1383 </td>
simon@4345 1384 <td>
dschulze@4483 1385 refer to the size of the element's bounding box
simon@4345 1386 </td>
simon@4345 1387 </tr>
simon@4345 1388 <tr>
simon@4345 1389 <td>
simon@4345 1390 <em>Media:</em>
simon@4345 1391 </td>
simon@4345 1392 <td>
simon@4345 1393 visual
simon@4345 1394 </td>
simon@4345 1395 </tr>
simon@4345 1396 <tr>
simon@4345 1397 <td>
simon@4345 1398 <em>Computed value:</em>
simon@4345 1399 </td>
simon@4345 1400 <td>
simon@4345 1401 Same as specified value.
simon@4345 1402 </td>
simon@4345 1403 </tr>
simon@4345 1404 </tbody>
simon@4345 1405 </table>
simon@4365 1406 <p>
dschulze@4602 1407 The values of the '<code class="property">perspective</code>' and '<code class="property">perspective-origin</code>'
simon@4366 1408 properties are used to compute the <a href="#TermPerspectiveMatrix"><i>perspective matrix</i></a>, as described above.
simon@4365 1409 </p>
simon@4345 1410
simon@4345 1411 <!-- ======================================================================================================= -->
simon@4345 1412
simon@4345 1413 <h2 id="backface-visibility-property">
dschulze@4602 1414 The '<code class="property">backface-visibility</code>' Property
simon@4345 1415 </h2>
simon@4345 1416 <p>
dschulze@4602 1417 The '<code class="property">backface-visibility</code>' property
simon@4345 1418 determines whether or not the "back" side of a transformed element is
simon@4345 1419 visible when facing the viewer. With an identity transform, the front
simon@4345 1420 side of an element faces the viewer. Applying a rotation about Y of 180
simon@4345 1421 degrees (for instance) would cause the back side of the element to face
simon@4345 1422 the viewer.
simon@4345 1423 </p>
simon@4345 1424 <!-- This should not be in a normative section. -->
simon@4345 1425 <p>
simon@4345 1426 This property is useful when you place two elements back-to-back, as you
simon@4345 1427 would to create a playing card. Without this property, the front and
simon@4345 1428 back elements could switch places at times during an animation to flip
simon@4345 1429 the card. Another example is creating a box out of 6 elements, but where
simon@4345 1430 you want to see the inside faces of the box. This is useful when
simon@4345 1431 creating the backdrop for a 3 dimensional stage.
simon@4345 1432 </p>
simon@4345 1433 <table class="propdef">
simon@4345 1434 <tbody>
simon@4345 1435 <tr>
simon@4345 1436 <td>
simon@4345 1437 <em>Name:</em>
simon@4345 1438 </td>
simon@4345 1439 <td>
simon@4345 1440 <dfn id="backface-visibility">backface-visibility</dfn>
simon@4345 1441 </td>
simon@4345 1442 </tr>
simon@4345 1443 <tr>
simon@4345 1444 <td>
simon@4345 1445 <em>Value:</em>
simon@4345 1446 </td>
simon@4345 1447 <td>
simon@4345 1448 visible | hidden
simon@4345 1449 </td>
simon@4345 1450 </tr>
simon@4345 1451 <tr>
simon@4345 1452 <td>
simon@4345 1453 <em>Initial:</em>
simon@4345 1454 </td>
simon@4345 1455 <td>
simon@4345 1456 visible
simon@4345 1457 </td>
simon@4345 1458 </tr>
simon@4345 1459 <tr>
simon@4345 1460 <td>
simon@4345 1461 <em>Applies&nbsp;to:</em>
simon@4345 1462 </td>
simon@4345 1463 <td>
simon@4366 1464 <a href="#TermTransformableElement">transformable elements</a>
simon@4345 1465 </td>
simon@4345 1466 </tr>
simon@4345 1467 <tr>
simon@4345 1468 <td>
simon@4345 1469 <em>Inherited:</em>
simon@4345 1470 </td>
simon@4345 1471 <td>
simon@4345 1472 no
simon@4345 1473 </td>
simon@4345 1474 </tr>
simon@4345 1475 <tr>
simon@4345 1476 <td>
simon@4345 1477 <em>Percentages:</em>
simon@4345 1478 </td>
simon@4345 1479 <td>
simon@4345 1480 N/A
simon@4345 1481 </td>
simon@4345 1482 </tr>
simon@4345 1483 <tr>
simon@4345 1484 <td>
simon@4345 1485 <em>Media:</em>
simon@4345 1486 </td>
simon@4345 1487 <td>
simon@4345 1488 visual
simon@4345 1489 </td>
simon@4345 1490 </tr>
simon@4345 1491 <tr>
simon@4345 1492 <td>
simon@4345 1493 <em>Computed value:</em>
simon@4345 1494 </td>
simon@4345 1495 <td>
simon@4345 1496 Same as specified value.
simon@4345 1497 </td>
simon@4345 1498 </tr>
simon@4345 1499 </tbody>
simon@4345 1500 </table>
simon@4367 1501 <p>
dschulze@4602 1502 The visibility of an element with '<code class="css">backface-visibility: hidden</code>' is determined
simon@4367 1503 as follows:
simon@4367 1504 <ol>
simon@4367 1505 <li>Compute a matrix representing the accumulated transform from the viewport, taking the translations
simon@4376 1506 due to the CSS visual formatting mode, the perpsective and transformation matrices into account,
simon@4367 1507 in a similar manner to the computation of the accumulated transform for an element in a
simon@4367 1508 3D rendering context.
simon@4367 1509 </li>
simon@4367 1510 <li>
simon@4367 1511 If the component of the matrix in row 3, column 3 is negative, then the element should be hidden,
simon@4367 1512 otherwise it is visible.
simon@4367 1513 </li>
simon@4367 1514 </ol>
simon@4367 1515 <div class="issue">
simon@4367 1516 Is the relevant matrix here really relative to the viewport, or to the root of the 3D rendering context?
simon@4367 1517 </div>
simon@4367 1518 </p>
vhardy@3672 1519
vhardy@3672 1520 <!-- ======================================================================================================= -->
vhardy@3672 1521
vhardy@3672 1522 <h2 id="transform-functions">
vhardy@3672 1523 The Transformation Functions
vhardy@3672 1524 </h2>
vhardy@3672 1525 <p>
simon@4365 1526 The value of the <code class="property">transform</code> property is a
dschulze@4602 1527 list of <var>&lt;transform-functions&gt;</var> applied in the order provided. The
vhardy@3672 1528 individual transform functions are separated by whitespace. The
vhardy@3672 1529 set of allowed transform functions is given below. In this list the
dschulze@4602 1530 type <var>&lt;translation-value&gt;</var> is defined as a <var>&lt;length&gt;</var> or
dschulze@4602 1531 <var>&lt;percentage&gt;</var> value, and the <var>&lt;angle&gt;</var> type is defined by <a
dschulze@4598 1532 href="http://www.w3.org/TR/css3-values/">CSS Values and Units Module.</a>
dschulze@4602 1533 Wherever <var>&lt;angle&gt;</var> is used in this specification, a <var>&lt;number&gt;</var> that is equal to
simon@4334 1534 zero is also allowed, which is treated the same as an angle of zero degrees.
vhardy@3672 1535 </p>
simon@4358 1536
simon@4358 1537 <h3 id="two-d-transform-functions">2D Transformation Functions</h3>
vhardy@3672 1538 <dl>
vhardy@3672 1539 <dt>
simon@4365 1540 <code class="css">matrix(&lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;)</code>
vhardy@3672 1541 </dt>
vhardy@3672 1542 <dd>
dschulze@4491 1543 specifies a 2D transformation in the form of a <a href="#MatrixDefined">transformation matrix</a> of the six values a-f.
vhardy@3672 1544 </dd>
vhardy@3672 1545 <dt>
simon@4365 1546 <code class="css">translate(&lt;translation-value&gt;[, &lt;translation-value&gt;])</code>
vhardy@3672 1547 </dt>
vhardy@3672 1548 <dd>
dschulze@4491 1549 specifies a <a href="#TranslateDefined">2D translation</a> by the vector [tx, ty], where tx is the first translation-value parameter and ty is the optional second translation-value parameter. If <em>&lt;ty&gt;</em> is not provided, ty has zero as a value.
vhardy@3672 1550 </dd>
vhardy@3672 1551 <dt>
simon@4365 1552 <code class="css">translateX(&lt;translation-value&gt;)</code>
vhardy@3672 1553 </dt>
vhardy@3672 1554 <dd>
dschulze@4491 1555 specifies a <a href="#TranslateDefined">translation</a> by the given amount in the X direction.
vhardy@3672 1556 </dd>
vhardy@3672 1557 <dt>
simon@4365 1558 <code class="css">translateY(&lt;translation-value&gt;)</code>
vhardy@3672 1559 </dt>
vhardy@3672 1560 <dd>
dschulze@4491 1561 specifies a <a href="#TranslateDefined">translation</a> by the given amount in the Y direction.
vhardy@3672 1562 </dd>
vhardy@3672 1563 <dt>
simon@4365 1564 <code class="css">scale(&lt;number&gt;[, &lt;number&gt;])</code>
vhardy@3672 1565 </dt>
vhardy@3672 1566 <dd>
dschulze@4491 1567 specifies a <a href="#ScaleDefined">2D scale</a> operation by the [sx,sy] scaling vector described by the 2 parameters. If the second parameter is not provided, it is takes a value equal to the first. For example, scale(1, 1) would leave an element unchanged, while scale(2, 2) would cause it to appear twice as long in both the X
vhardy@3672 1568 and Y axes, or four times its typical geometric size.
vhardy@3672 1569 </dd>
vhardy@3672 1570 <dt>
simon@4365 1571 <code class="css">scaleX(&lt;number&gt;)</code>
vhardy@3672 1572 </dt>
vhardy@3672 1573 <dd>
dschulze@4491 1574 specifies a <a href="#ScaleDefined">2D scale</a> operation using the [sx,1] scaling vector, where sx is given as the parameter.
vhardy@3672 1575 </dd>
vhardy@3672 1576 <dt>
simon@4365 1577 <code class="css">scaleY(&lt;number&gt;)</code>
vhardy@3672 1578 </dt>
vhardy@3672 1579 <dd>
dschulze@4491 1580 specifies a <a href="#ScaleDefined">2D scale</a> operation using the [1,sy] scaling vector, where sy is given as the parameter.
vhardy@3672 1581 </dd>
vhardy@3672 1582 <dt>
dschulze@4598 1583 <code class="css">rotate(&lt;angle&gt;)</code>
vhardy@3672 1584 </dt>
vhardy@3672 1585 <dd>
dschulze@4598 1586 specifies a <a href="#RotateDefined">2D rotation</a> by the angle specified in the parameter about the origin of the element, as
dschulze@4602 1587 defined by the '<code class="property">transform-origin</code>' property. For example, '<code class="css">rotate(90deg)</code>'
dschulze@4602 1588 would cause elements to appear rotated one-quarter of a turn in the clockwise direction.
vhardy@3672 1589 </dd>
vhardy@3672 1590 <dt>
dschulze@4491 1591 <code class="css">skew(&lt;angle&gt;[, &lt;angle&gt;])</code>
simon@4399 1592 </dt>
simon@4399 1593 <dd>
dschulze@4491 1594 specifies a <a href="#SkewDefined">2D skew</a> by [ax,ay] for X and Y. If the second parameter is not provided, it is has a zero value.
simon@4399 1595 </dd>
simon@4399 1596 <dt>
simon@4365 1597 <code class="css">skewX(&lt;angle&gt;)</code>
vhardy@3672 1598 </dt>
vhardy@3672 1599 <dd>
dschulze@4491 1600 specifies a <a href="#SkewDefined">2D skew transformation along the X axis</a> by the given angle. The skew vector is [ax,0].
vhardy@3672 1601 </dd>
vhardy@3672 1602 <dt>
simon@4365 1603 <code class="css">skewY(&lt;angle&gt;)</code>
vhardy@3672 1604 </dt>
vhardy@3672 1605 <dd>
dschulze@4491 1606 specifies a <a href="#SkewDefined">2D skew transformation along the Y axis</a> by the given angle. The skew vector is [0,ay].
vhardy@3672 1607 </dd>
vhardy@3672 1608 </dl>
simon@4358 1609
simon@4358 1610
simon@4358 1611 <h3 id="three-d-transform-functions">3D Transformation Functions</h3>
simon@4358 1612 <dl>
simon@4358 1613 <dt>
simon@4365 1614 <code class="css">matrix3d(&lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;number&gt;)</code>
simon@4358 1615 </dt>
simon@4358 1616 <dd>
simon@4358 1617 specifies a 3D transformation as a 4x4 homogeneous matrix of 16 values in column-major order.
simon@4358 1618 </dd>
simon@4358 1619 <dt>
dschulze@4483 1620 <code class="css">translate3d(&lt;translation-value&gt;, &lt;translation-value&gt;, &lt;length&gt;)</code>
simon@4358 1621 </dt>
simon@4358 1622 <dd>
dschulze@4491 1623 specifies a <a href="#Translate3dDefined">3D translation</a> by the vector [tx,ty,tz], with tx, ty and tz being the first, second and third translation-value parameters respectively.
simon@4358 1624 </dd>
simon@4358 1625 <dt>
dschulze@4483 1626 <code class="css">translateZ(&lt;length&gt;)</code>
simon@4358 1627 </dt>
simon@4358 1628 <dd>
dschulze@4491 1629 specifies a <a href="#Translate3dDefined">3D translation</a> by the vector [0,0,tz] with the given amount in the Z direction.
simon@4358 1630 </dd>
simon@4358 1631 <dt>
simon@4365 1632 <code class="css">scale3d(&lt;number&gt;, &lt;number&gt;, &lt;number&gt;)</code>
simon@4358 1633 </dt>
simon@4358 1634 <dd>
dschulze@4491 1635 specifies a <a href="#Scale3dDefined">3D scale</a> operation by the [sx,sy,sz] scaling vector described by the 3 parameters.
simon@4358 1636 </dd>
simon@4358 1637 <dt>
simon@4365 1638 <code class="css">scaleZ(&lt;number&gt;)</code>
simon@4358 1639 </dt>
simon@4358 1640 <dd>
dschulze@4491 1641 specifies a <a href="#Scale3dDefined">3D scale</a> operation using the [1,1,sz] scaling vector, where sz is given as the parameter.
simon@4358 1642 </dd>
simon@4358 1643 <dt>
simon@4365 1644 <code class="css">rotate3d(&lt;number&gt;, &lt;number&gt;, &lt;number&gt;, &lt;angle&gt;)</code>
simon@4358 1645 </dt>
simon@4358 1646 <div class="todo">Clarify "clockwise". Describe in terms of right-hand rule?</div>
simon@4358 1647 <dd>
dschulze@4491 1648 specifies a clockwise <a href="#Rotate3dDefined">3D rotation</a> by the angle specified in last
simon@4358 1649 parameter about the [x,y,z] direction vector described by the first 3
simon@4358 1650 parameters. If the direction vector is not of unit length, it will be
dschulze@4491 1651 normalized. A direction vector that cannot be normalized, such as [0,0,0], will cause the rotation to not be applied.
dschulze@4491 1652 </dd>
simon@4358 1653 <dt>
simon@4365 1654 <code class="css">rotateX(&lt;angle&gt;)</code>
simon@4358 1655 </dt>
simon@4358 1656 <dd>
dschulze@4491 1657 specifies a clockwise <a href="#RotateXDefined">3D rotation</a> by the given angle about the X axis.
simon@4358 1658 </dd>
simon@4358 1659 <dt>
simon@4365 1660 <code class="css">rotateY(&lt;angle&gt;)</code>
simon@4358 1661 </dt>
simon@4358 1662 <dd>
dschulze@4491 1663 specifies a clockwise <a href="#RotateYDefined">3D rotation</a> by the given angle about the Y axis.
simon@4358 1664 </dd>
simon@4358 1665 <dt>
simon@4365 1666 <code class="css">rotateZ(&lt;angle&gt;)</code>
simon@4358 1667 </dt>
simon@4358 1668 <dd>
dschulze@4491 1669 specifies a clockwise <a href="#RotateZDefined">3D rotation</a> by the given angle about the Z axis. This is a synonym for <code class="css">rotate(&lt;angle&gt;)</code>.
simon@4358 1670 </dd>
simon@4577 1671 <dt id="perspective-function">
simon@4365 1672 <code class="css">perspective(&lt;length&gt;)</code>
simon@4358 1673 </dt>
simon@4358 1674 <dd>
simon@4700 1675 specifies a <a href="#PerspectiveDefined">perspective projection matrix</a>. This matrix scales points in
simon@4700 1676 X and Y based on their Z value, scaling points with positive Z values away from the origin, and those with
simon@4700 1677 negative Z values towards the origin. Points on the z=0 plane are unchanged. The parameter represents the
simon@4700 1678 distance of the z=0 plane from the viewer. Lower values give a more flattened pyramid and therefore a more
simon@4700 1679 pronounced perspective effect. For example, a value of 1000px gives a moderate amount of foreshortening
simon@4700 1680 and a value of 200px gives an extreme amount. The value for depth must be greater than zero, otherwise the
simon@4700 1681 function is invalid.
simon@4358 1682 </dd>
simon@4358 1683 </dl>
simon@4358 1684
simon@4358 1685 <!-- ======================================================================================================= -->
simon@4358 1686
vhardy@3672 1687 <h2 id="transform-values">
vhardy@3672 1688 Transform Values and Lists
vhardy@3672 1689 </h2>
vhardy@3672 1690 <p>
vhardy@3672 1691 The &lt;translation-value&gt; values are defined as [&lt;percentage&gt; | &lt;length&gt;]. All other value types are described <a href="http://www.w3.org/TR/REC-CSS2/syndata.html#values">as CSS types</a>. If a list of transforms is provided, then the net effect is as if each transform had been specified separately in the order provided. For example,
vhardy@3672 1692 </p>
simon@4358 1693 <pre>
simon@4358 1694 &lt;div style="transform:translate(-10px,-20px) scale(2) rotate(45deg) translate(5px,10px)"/&gt;
simon@4358 1695 </pre>
vhardy@3672 1696 <p>
vhardy@3672 1697 is functionally equivalent to:
vhardy@3672 1698 </p>
simon@4358 1699 <pre>
simon@4358 1700 &lt;div style="transform:translate(-10px,-20px)"&gt;
simon@4358 1701 &lt;div style="transform:scale(2)"&gt;
simon@4358 1702 &lt;div style="transform:rotate(45deg)"&gt;
simon@4358 1703 &lt;div style="transform:translate(5px,10px)"&gt;
simon@4358 1704 &lt;/div&gt;
simon@4358 1705 &lt;/div&gt;
simon@4358 1706 &lt;/div&gt;
simon@4358 1707 &lt;/div&gt;
simon@4358 1708 </pre>
vhardy@3672 1709 <p>
vhardy@3672 1710 That is, in the absence of other styling that affects position and dimensions, a nested set of transforms is equivalent to a single list of transform functions, applied from the outside in. The resulting transform is the matrix multiplication of the list of transforms.
vhardy@3672 1711 </p>
vhardy@3672 1712 <!-- ======================================================================================================= -->
vhardy@3672 1713
vhardy@3672 1714 <h2 id="animation">
dschulze@4511 1715 Transitions and Animations between Transform Values
vhardy@3672 1716 </h2>
vhardy@3672 1717
vhardy@3672 1718 <p>
vhardy@3672 1719 When animating or transitioning the value of a transform property
vhardy@3672 1720 the rules described below are applied. The 'from' transform is
vhardy@3672 1721 the transform at the start of the transition or current keyframe. The
vhardy@3672 1722 'end' transform is the transform at the end of the transition or
vhardy@3672 1723 current keyframe.
vhardy@3672 1724 </p>
vhardy@3672 1725
vhardy@3672 1726 <ul>
vhardy@3672 1727 <li>
vhardy@3672 1728 If the 'from' and 'to' transforms are both single functions
vhardy@3672 1729 of the same type:
vhardy@3672 1730 <ul>
vhardy@3672 1731 <li>
dschulze@4484 1732 For translate, translate3d, translateX, translateY, translateZ, scale,
dschulze@4484 1733 scale3d, scaleX, scaleY, scaleZ, rotate, rotateX, rotateY, rotateZ, skew, skewX
dschulze@4484 1734 and skewY functions:
vhardy@3672 1735 <ul>
vhardy@3672 1736 <li>
vhardy@3672 1737 the individual components of the function are
vhardy@3672 1738 interpolated numerically.
vhardy@3672 1739 </li>
vhardy@3672 1740 </ul>
vhardy@3672 1741 </li>
vhardy@3672 1742 <li>
dschulze@4484 1743 For perspective, matrix, matrix3d and rotate3d:
vhardy@3672 1744 <ul>
vhardy@3672 1745 <li>
dschulze@4484 1746 the values are first converted to a 4x4 matrix, then
vhardy@3672 1747 decomposed using <a
dschulze@4484 1748 href="#unmatrix">the
vhardy@3672 1749 method described by unmatrix</a> into separate translation,
dschulze@4484 1750 scale, rotation, skew and perspective matrices, then each
vhardy@3672 1751 decomposed matrix is interpolated numerically, and finally
dschulze@4484 1752 combined in order to produce a resulting 4x4 matrix.
vhardy@3672 1753 </li>
vhardy@3672 1754 </ul>
vhardy@3672 1755 </li>
vhardy@3672 1756 </ul>
vhardy@3672 1757 </li>
vhardy@3672 1758 <li>
vhardy@3672 1759 If both the 'from' and 'to' transforms are "none":
vhardy@3672 1760 <ul>
vhardy@3672 1761 <li>
vhardy@3672 1762 There is no interpolation necessary
vhardy@3672 1763 </li>
vhardy@3672 1764 </ul>
vhardy@3672 1765 </li>
vhardy@3672 1766 <li>
vhardy@3672 1767 If one of the 'from' or 'to' transforms is "none":
vhardy@3672 1768 <ul>
vhardy@3672 1769 <li>
vhardy@3672 1770 The 'none' is replaced by an equivalent identity function list for
vhardy@3672 1771 the corresponding transform function list.
vhardy@3672 1772 <p>
vhardy@3672 1773 For example, if the 'from' transform is "scale(2)" and the 'to'
vhardy@3672 1774 transform is "none" then the value "scale(1)" will be used as the
vhardy@3672 1775 'to' value, and animation will proceed using the rule above.
vhardy@3672 1776 Similarly, if the 'from' transform is "none" and the 'to' transform
vhardy@3672 1777 is "scale(2) rotate(50deg)" then the animation will execute as
vhardy@3672 1778 if the 'from' value is "scale(1) rotate(0)".
vhardy@3672 1779 </p>
vhardy@3672 1780 <p>
dschulze@4484 1781 The identity functions are translate(0), translate3d(0, 0, 0),
dschulze@4484 1782 translateX(0), translateY(0), translateZ(0), scale(1), scale3d(1, 1, 1),
dschulze@4484 1783 scaleX(1), scaleY(1), scaleZ(1), rotate(0), rotate3d(1, 1, 1, 0),
dschulze@4484 1784 rotateX(0), rotateY(0), rotateZ(0), skew(0), skewX(0), skewY(0),
dschulze@4484 1785 matrix(1, 0, 0, 1, 0, 0) and
dschulze@4484 1786 matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1).
vhardy@3672 1787 </p>
vhardy@3672 1788 </li>
vhardy@3672 1789 </ul>
vhardy@3672 1790 </li>
vhardy@3672 1791 <li>
vhardy@3672 1792 If both the 'from' and 'to' transforms have the same number of
vhardy@3672 1793 transform functions and corresponding functions in each transform
vhardy@3672 1794 list are of the same type:
vhardy@3672 1795 <ul>
vhardy@3672 1796 <li>
vhardy@3672 1797 Each transform function is animated with its corresponding
vhardy@3672 1798 destination function in isolation using the rules described above.
dschulze@4484 1799 The individual values are then applied as a list to produce
vhardy@3672 1800 resulting transform value.
vhardy@3672 1801 </li>
vhardy@3672 1802 </ul>
vhardy@3672 1803 </li>
vhardy@3672 1804 <li>
vhardy@3672 1805 Otherwise:
vhardy@3672 1806 <ul>
vhardy@3672 1807 <li>
vhardy@3672 1808 The transform function lists are each converted into the
dschulze@4484 1809 equivalent matrix3d value and animation proceeds using the rule
vhardy@3672 1810 for a single function above.
vhardy@3672 1811 </li>
vhardy@3672 1812 </ul>
vhardy@3672 1813 </li>
vhardy@3672 1814 </ul>
vhardy@3672 1815
vhardy@3672 1816 <p>
vhardy@3672 1817 In some cases, an animation might cause a transformation matrix to
vhardy@3672 1818 be singular or non-invertible. For example, an animation in which
vhardy@3672 1819 scale moves from 1 to -1. At the time when the matrix is in such
vhardy@3672 1820 a state, the transformed element is not rendered.
vhardy@3672 1821 </p>
vhardy@3672 1822
vhardy@3672 1823 <h2 id="matrix-decomposition">
dschulze@4511 1824 Matrix Decomposition for Animation
vhardy@3672 1825 </h2>
vhardy@3672 1826
vhardy@3672 1827 <p>
vhardy@3672 1828 When interpolating between 2 matrices, each is decomposed into the
dschulze@4484 1829 corresponding translation, rotation, scale, skew and perspective
vhardy@3672 1830 values. Not all matrices can be accurately described by these values.
vhardy@3672 1831 Those that can't are decomposed into the most accurate representation
dschulze@4484 1832 possible, using the technique below. This technique is taken from the
dschulze@4484 1833 "unmatrix" method in "Graphics Gems II, edited by Jim Arvo".
dschulze@4493 1834 The pseudocode below works on a 4x4 homogeneous matrix.
vhardy@3672 1835 </p>
vhardy@3672 1836
vhardy@3672 1837 <h3 id="unmatrix">Unmatrix</h3>
vhardy@3672 1838 <pre>
dschulze@4484 1839 Input: matrix ; a 4x4 matrix
dschulze@4484 1840 Output: translation ; a 3 component vector
dschulze@4484 1841 rotation ; Euler angles, represented as a 3 component vector
dschulze@4484 1842 scale ; a 3 component vector
dschulze@4484 1843 skew ; skew factors XY,XZ,YZ represented as a 3 component vector
dschulze@4484 1844 perspective ; a 4 component vector
vhardy@3672 1845 Returns false if the matrix cannot be decomposed, true if it can
vhardy@3672 1846
dschulze@4484 1847 Supporting functions (point is a 3 component vector, matrix is a 4x4 matrix):
dschulze@4484 1848 double determinant(matrix) returns the 4x4 determinant of the matrix
dschulze@4484 1849 matrix inverse(matrix) returns the inverse of the passed matrix
dschulze@4484 1850 matrix transpose(matrix) returns the transpose of the passed matrix
dschulze@4484 1851 point multVecMatrix(point, matrix) multiplies the passed point by the passed matrix
dschulze@4484 1852 and returns the transformed point
dschulze@4484 1853 double length(point) returns the length of the passed vector
vhardy@3672 1854 point normalize(point) normalizes the length of the passed point to 1
dschulze@4484 1855 double dot(point, point) returns the dot product of the passed points
dschulze@4484 1856 double cos(double) returns the cosine of the passed angle in radians
dschulze@4484 1857 double asin(double) returns the arcsine in radians of the passed value
dschulze@4484 1858 double atan2(double y, double x) returns the principal value of the arc tangent of
vhardy@3672 1859 y/x, using the signs of both arguments to determine
vhardy@3672 1860 the quadrant of the return value
vhardy@3672 1861
vhardy@3672 1862 Decomposition also makes use of the following function:
dschulze@4484 1863 point combine(point a, point b, double ascl, double bscl)
vhardy@3672 1864 result[0] = (ascl * a[0]) + (bscl * b[0])
vhardy@3672 1865 result[1] = (ascl * a[1]) + (bscl * b[1])
dschulze@4484 1866 result[2] = (ascl * a[2]) + (bscl * b[2])
vhardy@3672 1867 return result
vhardy@3672 1868
dschulze@4484 1869 // Normalize the matrix.
dschulze@4484 1870 if (matrix[3][3] == 0)
dschulze@4484 1871 return false
vhardy@3672 1872
dschulze@4484 1873 for (i = 0; i < 4; i++)
dschulze@4484 1874 for (j = 0; j < 4; j++)
dschulze@4484 1875 matrix[i][j] /= matrix[3][3]
dschulze@4484 1876
dschulze@4484 1877 // perspectiveMatrix is used to solve for perspective, but it also provides
dschulze@4484 1878 // an easy way to test for singularity of the upper 3x3 component.
dschulze@4484 1879 perspectiveMatrix = matrix
dschulze@4484 1880
dschulze@4484 1881 for (i = 0; i < 3; i++)
dschulze@4484 1882 perspectiveMatrix[i][3] = 0
dschulze@4484 1883
dschulze@4484 1884 perspectiveMatrix[3][3] = 1
dschulze@4484 1885
dschulze@4484 1886 if (determinant(perspectiveMatrix) == 0)
dschulze@4484 1887 return false
dschulze@4484 1888
dschulze@4484 1889 // First, isolate perspective.
dschulze@4484 1890 if (matrix[0][3] != 0 || matrix[1][3] != 0 || matrix[2][3] != 0)
dschulze@4484 1891 // rightHandSide is the right hand side of the equation.
dschulze@4484 1892 rightHandSide[0] = matrix[0][3];
dschulze@4484 1893 rightHandSide[1] = matrix[1][3];
dschulze@4484 1894 rightHandSide[2] = matrix[2][3];
dschulze@4484 1895 rightHandSide[3] = matrix[3][3];
dschulze@4484 1896
dschulze@4484 1897 // Solve the equation by inverting perspectiveMatrix and multiplying
dschulze@4484 1898 // rightHandSide by the inverse.
dschulze@4484 1899 inversePerspectiveMatrix = inverse(perspectiveMatrix)
dschulze@4484 1900 transposedInversePerspectiveMatrix = transposeMatrix4(inversePerspectiveMatrix)
dschulze@4484 1901 perspective = multVecMatrix(rightHandSide, transposedInversePerspectiveMatrix)
dschulze@4484 1902
dschulze@4484 1903 // Clear the perspective partition
dschulze@4484 1904 matrix[0][3] = matrix[1][3] = matrix[2][3] = 0
dschulze@4484 1905 matrix[3][3] = 1
dschulze@4484 1906 else
dschulze@4484 1907 // No perspective.
dschulze@4484 1908 perspective[0] = perspective[1] = perspective[2] = 0
dschulze@4484 1909 perspective[3] = 1
dschulze@4484 1910
dschulze@4484 1911 // Next take care of translation
dschulze@4484 1912 translate[0] = matrix[3][0]
dschulze@4484 1913 matrix[3][0] = 0
vhardy@3672 1914 translate[1] = matrix[3][1]
dschulze@4484 1915 matrix[3][1] = 0
dschulze@4484 1916 translate[2] = matrix[3][2]
dschulze@4484 1917 matrix[3][2] = 0
vhardy@3672 1918
dschulze@4484 1919 // Now get scale and shear. 'row' is a 3 element array of 3 component vectors
dschulze@4484 1920 for (i = 0; i < 3; i++)
dschulze@4484 1921 row[i][0] = matrix[i][0]
dschulze@4484 1922 row[i][1] = matrix[i][1]
dschulze@4484 1923 row[i][2] = matrix[i][2]
vhardy@3672 1924
vhardy@3672 1925 // Compute X scale factor and normalize first row.
vhardy@3672 1926 scale[0] = length(row[0])
vhardy@3672 1927 row[0] = normalize(row[0])
vhardy@3672 1928
dschulze@4484 1929 // Compute XY shear factor and make 2nd row orthogonal to 1st.
dschulze@4484 1930 skew[0] = dot(row[0], row[1])
dschulze@4484 1931 row[1] = combine(row[1], row[0], 1.0, -skew[0])
vhardy@3672 1932
vhardy@3672 1933 // Now, compute Y scale and normalize 2nd row.
vhardy@3672 1934 scale[1] = length(row[1])
vhardy@3672 1935 row[1] = normalize(row[1])
dschulze@4484 1936 skew[0] /= scale[1];
vhardy@3672 1937
dschulze@4484 1938 // Compute XZ and YZ shears, orthogonalize 3rd row
dschulze@4484 1939 skew[1] = dot(row[0], row[2])
dschulze@4484 1940 row[2] = combine(row[2], row[0], 1.0, -skew[1])
dschulze@4484 1941 skew[2] = dot(row[1], row[2])
dschulze@4484 1942 row[2] = combine(row[2], row[1], 1.0, -skew[2])
dschulze@4484 1943
dschulze@4484 1944 // Next, get Z scale and normalize 3rd row.
dschulze@4484 1945 scale[2] = length(row[2])
dschulze@4484 1946 row[2] = normalize(row[2])
dschulze@4484 1947 skew[1] /= scale[2]
dschulze@4484 1948 skew[2] /= scale[2]
dschulze@4484 1949
dschulze@4484 1950 // At this point, the matrix (in rows) is orthonormal.
dschulze@4484 1951 // Check for a coordinate system flip. If the determinant
dschulze@4484 1952 // is -1, then negate the matrix and the scaling factors.
dschulze@4484 1953 pdum3 = cross(row[1], row[2])
dschulze@4484 1954 if (dot(row[0], pdum3) < 0)
dschulze@4484 1955 for (i = 0; i < 3; i++) {
dschulze@4484 1956 scale[0] *= -1;
dschulze@4484 1957 row[i][0] *= -1
dschulze@4484 1958 row[i][1] *= -1
dschulze@4484 1959 row[i][2] *= -1
dschulze@4484 1960
dschulze@4484 1961 // Now, get the rotations ou
dschulze@4484 1962 rotate[1] = asin(-row[0][2]);
dschulze@4484 1963 if (cos(rotate[1]) != 0)
dschulze@4484 1964 rotate[0] = atan2(row[1][2], row[2][2]);
dschulze@4484 1965 rotate[2] = atan2(row[0][1], row[0][0]);
dschulze@4484 1966 else
dschulze@4484 1967 rotate[0] = atan2(-row[2][0], row[1][1]);
dschulze@4484 1968 rotate[2] = 0;
vhardy@3672 1969
vhardy@3672 1970 return true;</pre>
vhardy@3672 1971
vhardy@3672 1972 <h3>Animating the components</h3>
vhardy@3672 1973 <p>
vhardy@3672 1974 Once decomposed, each component of each returned value of the source matrix is linearly interpolated
vhardy@3672 1975 with the corresponding component of the destination matrix. For instance, the translate[0] and
vhardy@3672 1976 translate[1] values are interpolated numerically, and the result is used to set the
vhardy@3672 1977 translation of the animating element.
vhardy@3672 1978 </p>
vhardy@3672 1979 <h3>Recomposing the matrix</h3>
vhardy@3672 1980 <p><em>This section is not normative.</em></p>
vhardy@3672 1981 <p>
vhardy@3672 1982 After interpolation the resulting values are used to position the element. One way to use these values
dschulze@4601 1983 is to recompose them into a 4x4 matrix. This can be done using the transform functions of the
dschulze@4602 1984 'transform' property. This can be done by the following pseudo code. The
vhardy@3672 1985 values passed in are the output of the Unmatrix function above:
vhardy@3672 1986 </p>
vhardy@3672 1987 <pre>
dschulze@4484 1988 matrix3d(1,0,0,0, 0,1,0,0, 0,0,1,0, perspective[0], perspective[1], perspective[2], perspective[3])
dschulze@4484 1989 translate3d(translation[0], translation[1], translation[2])
dschulze@4484 1990 rotateX(rotation[0]) rotateY(rotation[1]) rotateZ(rotation[2])
dschulze@4484 1991 matrix3d(1,0,0,0, 0,1,0,0, 0,skew[2],1,0, 0,0,0,1)
dschulze@4484 1992 matrix3d(1,0,0,0, 0,1,0,0, skew[1],0,1,0, 0,0,0,1)
dschulze@4484 1993 matrix3d(1,0,0,0, skew[0],1,0,0, 0,0,1,0, 0,0,0,1)
dschulze@4484 1994 scale3d(scale[0], scale[1], scale[2])</pre>
dschulze@4491 1995
dschulze@4491 1996 <h2 id="mathematical-description">
dschulze@4511 1997 Mathematical Description of Transformation Functions
dschulze@4491 1998 </h2>
dschulze@4491 1999 <p>
dschulze@4601 2000 Mathematically, all transform functions can be represented as 4x4 transformation matrices of the following form:
dschulze@4491 2001 </p>
simon@4583 2002 <img src="4x4matrix.png" alt="\begin{bmatrix} m11 & m21 & m31 & m41 \\ m12 & m22 & m32 & m42 \\ m13 & m23 & m33 & m43 \\ m14 & m24 & m34 & m44 \end{bmatrix}" width="222" height="106">
dschulze@4491 2003
dschulze@4491 2004 <ul>
dschulze@4491 2005 <li id="MatrixDefined">
dschulze@4491 2006 <p>
dschulze@4491 2007 A 2D 3x2 matrix with six parameters <em>a</em>, <em>b</em>, <em>c</em>, <em>d</em>, <em>e</em> and <em>f</em> is equivalent to to the matrix:
dschulze@4491 2008 </p>
simon@4583 2009 <img src="matrix.png" alt="\begin{bmatrix} a & c & 0 & e \\ b & d & 0 & f \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}" width="108" height="106">
dschulze@4491 2010 </li>
dschulze@4491 2011 <li id="TranslateDefined">
dschulze@4491 2012 <p>
dschulze@4491 2013 A 2D translation with the parameters <em>tx</em> and <em>ty</em> is equivalent to a <a href="#Translate3dDefined">3D translation</a> where <em>tz</em> has zero as a value.
dschulze@4491 2014 </p>
dschulze@4491 2015 </li>
dschulze@4491 2016 <li id="ScaleDefined">
dschulze@4491 2017 <p>
dschulze@4491 2018 A 2D scaling with the parameters <em>sx</em> and <em>sy</em> is equivalent to a <a href="#Scale3dDefined">3D scale</a> where <em>sz</em> has one as a value.
dschulze@4491 2019 </p>
dschulze@4491 2020 </li>
dschulze@4491 2021 <li id="RotateDefined">
dschulze@4491 2022 <p>
dschulze@4491 2023 A 2D rotation with the parameter <em>alpha</em> is equivalent to a <a href="#RotateZDefined">rotation around the Z axis</a>.
dschulze@4491 2024 </p>
dschulze@4491 2025 </li>
dschulze@4491 2026 <li id="SkewDefined">
dschulze@4491 2027 <p>
dschulze@4491 2028 A 2D skew transformation with the parameters <em>alpha</em> and <em>beta</em> is equivalent to the matrix:
dschulze@4491 2029 </p>
simon@4583 2030 <img src="skew.png" alt="\begin{bmatrix} 1 & \tan(\alpha) & 0 & 0 \\ \tan(\beta) & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}" width="205" height="106">
dschulze@4491 2031 </li>
dschulze@4491 2032 <li id="Translate3dDefined">
dschulze@4491 2033 <p>
dschulze@4491 2034 A 3D translation with the parameters <em>tx</em>, <em>ty</em> and <em>tz</em> is equivalent to the matrix:
dschulze@4491 2035 </p>
simon@4584 2036 <img src="translate3d.png" alt="\begin{bmatrix} 1 & 0 & 0 & tx \\ 0 & 1 & 0 & ty \\ 0 & 0 & 1 & tz \\ 0 & 0 & 0 & 1 \end{bmatrix}" width="114" height="106">
dschulze@4491 2037 </li>
dschulze@4491 2038 <li id="Scale3dDefined">
dschulze@4491 2039 <p>
dschulze@4491 2040 A 3D scaling with the parameters <em>sx</em>, <em>sy</em> and <em>sz</em> is equivalent to the matrix:
dschulze@4491 2041 </p>
simon@4583 2042 <img src="scale3d.png" alt="\begin{bmatrix} sx & 0 & 0 & 0 \\ 0 & sy & 0 & 0 \\ 0 & 0 & sz & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}" width="137" height="106">
dschulze@4491 2043 </li>
dschulze@4491 2044 <li id="Rotate3dDefined">
dschulze@4491 2045 <p>
dschulze@4491 2046 A 3D rotation with the vector [x,y,z] and the parameter <em>alpha</em> is equivalent to the matrix:
dschulze@4491 2047 </p>
simon@4583 2048 <img src="rotate3dmatrix.png" 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}" width="647" height="106">
dschulze@4491 2049 <p>
dschulze@4491 2050 where:
dschulze@4491 2051 </p>
simon@4584 2052 <img src="rotate3dvariables.png" alt="\newline sc = \sin (\alpha/2) \cdot \cos (\alpha/2) \newline sq = \sin^2 (\alpha/2)" width="221" height="50">
dschulze@4491 2053 </li>
dschulze@4491 2054 <li id="RotateXDefined">
dschulze@4491 2055 <p>
dschulze@4491 2056 A 3D rotation about the X axis with the parameter <em>alpha</em> is equivalent to the matrix:
dschulze@4491 2057 </p>
simon@4583 2058 <img src="rotateX.png" alt="\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos(\alpha) & -\sin(\alpha) & 0 \\ 0 & \sin(\alpha) & \cos(\alpha) & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}" width="220" height="106">
dschulze@4491 2059 </li>
dschulze@4491 2060 <li id="RotateYDefined">
dschulze@4491 2061 <p>
dschulze@4491 2062 A 3D rotation about the Y axis with the parameter <em>alpha</em> is equivalent to the matrix:
dschulze@4491 2063 </p>
simon@4583 2064 <img src="rotateY.png" alt="\begin{bmatrix} \cos(\alpha) & 0 & \sin(\alpha) & 0 \\ 0 & 1 & 0 & 0 \\ -\sin(\alpha) & 0 & \cos(\alpha) & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}" width="220" height="106">
dschulze@4491 2065 </li>
dschulze@4491 2066 <li id="RotateZDefined">
dschulze@4491 2067 <p>
dschulze@4491 2068 A 3D rotation about the Z axis with the parameter <em>alpha</em> is equivalent to the matrix:
dschulze@4491 2069 </p>
simon@4583 2070 <img src="rotateZ.png" alt="\begin{bmatrix} \cos(\alpha) & -\sin(\alpha) & 0 & 0 \\ \sin(\alpha) & \cos(\alpha) & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix}" width="220" height="106">
dschulze@4491 2071 </li>
dschulze@4491 2072 <li id="PerspectiveDefined">
dschulze@4491 2073 <p>
dschulze@4491 2074 A perspective projection matrix with the parameter <em>d</em> is equivalent to the matrix:
dschulze@4491 2075 </p>
simon@4583 2076 <img src="perspective.png" alt="\begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & -1/d & 1 \end{bmatrix}" width="143" height="106">
dschulze@4491 2077 </li>
dschulze@4491 2078 </ul>
vhardy@3672 2079
vhardy@3672 2080
vhardy@3672 2081 <h2>References</h2>
vhardy@3672 2082
vhardy@3672 2083 <h3 class="no-num">Normative references</h3>
vhardy@3672 2084 <!--normative-->
vhardy@3672 2085
vhardy@3672 2086 <h3 class="no-num">Other references</h3>
vhardy@3672 2087 <!--informative-->
vhardy@3672 2088
vhardy@3672 2089
vhardy@3672 2090
vhardy@3672 2091 <h2 class="no-num">Property index</h2>
vhardy@3672 2092 <!-- properties -->
vhardy@3672 2093
vhardy@3672 2094
vhardy@3672 2095
vhardy@3672 2096 <h2 class="no-num" id="index">Index</h2>
vhardy@3672 2097 <!--index-->
vhardy@3672 2098
vhardy@3672 2099 </body>
vhardy@3672 2100 </html>
vhardy@3672 2101 <!-- Keep this comment at the end of the file
vhardy@3672 2102 Local variables:
vhardy@3672 2103 mode: sgml
vhardy@3672 2104 sgml-declaration:"~/SGML/HTML4.decl"
vhardy@3672 2105 sgml-default-doctype-name:"html"
vhardy@3672 2106 sgml-minimize-attributes:t
vhardy@3672 2107 sgml-nofill-elements:("pre" "style" "br")
vhardy@3672 2108 sgml-live-element-indicator:t
vhardy@3672 2109 sgml-omittag:nil
vhardy@3672 2110 sgml-shorttag:nil
vhardy@3672 2111 sgml-namecase-general:t
vhardy@3672 2112 sgml-general-insert-case:lower
vhardy@3672 2113 sgml-always-quote-attributes:t
vhardy@3672 2114 sgml-indent-step:nil
vhardy@3672 2115 sgml-indent-data:t
vhardy@3672 2116 sgml-parent-document:nil
vhardy@3672 2117 sgml-exposed-tags:nil
vhardy@3672 2118 sgml-local-catalogs:nil
vhardy@3672 2119 sgml-local-ecat-files:nil
vhardy@3672 2120 End:
vhardy@3672 2121 -->
vhardy@3672 2122

mercurial