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