Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 83 additions & 9 deletions css-transforms-2/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ spec:css-transforms-1;
text: <transform-list>
type: function;
text: matrix()
spec:css2;
type: dfn;
text: stacking context
spec: infra
type:dfn;
text: list
spec: filter-effects-1; type:property; text:filter;
spec: html; type: element; text: a;
</pre>
Expand Down Expand Up @@ -62,15 +68,15 @@ Module Interactions {#module-interactions}

The <a>3D transform functions</a> here extend the set of functions for the 'transform' property.

Some values of 'perspective', 'transform-style' and 'backface-visibility' result in the creation of a [=containing block for all descendants=], and/or the creation of a <a spec="css21">stacking context</a>.
Some values of 'perspective', 'transform-style' and 'backface-visibility' result in the creation of a [=containing block for all descendants=], and/or the creation of a <a>stacking context</a>.

Three-dimensional transforms affect the visual layering of elements, and thus override the back-to-front painting order described in <a href="https://www.w3.org/TR/CSS2/zindex.html">Appendix E</a> of [[!CSS21]].


Terminology {#terminology}
==========================

: <dfn>3D-transformed element</dfn>
: <dfn>3D transformed element</dfn>
:: An element whose computed value for the 'transform' property includes one of the <a>3D transform functions</a>

: <dfn>3D matrix</dfn>
Expand Down Expand Up @@ -274,16 +280,16 @@ The rendering of elements in a 3D rendering context is as follows (numbers refer
<li>The content and descendant elements without 3D transforms, ordered according to steps 3—7, are rendered into a plane at z=0 relative to to the establishing element.
<li>3D-transformed elements are each rendered into their own plane, transformed by the <a href="#accumulated-3d-transformation-matrix-computation">accumulated 3D transformation matrix</a>.
<li>Intersection is performed between the set of planes generated by steps B and C, according to <a href="http://en.wikipedia.org/wiki/Newell%27s_algorithm">Newell's algorithm</a>.
<li>The resulting set of planes is rendered on top of the backgrounds and box decorations rendered in this step A. Coplanar 3D transformed elements are rendered in painting order.
<li>The resulting set of planes is rendered on top of the backgrounds and box decorations rendered in this step A. Coplanar [=3D transformed elements=] are rendered in painting order.
</ol>

Issue: is it OK to not pop 2D-transformed elements into their own planes?

Issue: requiring intersection with non-transformed content and descendants requires UAs to allocate additional textures (possibly doubling memory use). Would be more efficient to simply render content and untransformed descendants along with background and borders.

Note that elements with transforms which have a negative z-component will render behind the content and untransformed descendants of the establishing element, and that 3D transformed elements may interpenetrate with content and untransformed elements.
Note that elements with transforms which have a negative z-component will render behind the content and untransformed descendants of the establishing element, and that [=3D transformed elements=] may interpenetrate with content and untransformed elements.

Note: Because the 3D-transformed elements in a 3D rendering context can all depth-sort and intersect with each other, they are effectively rendered as if they were siblings. The effect of transform-style: preserve-3d can then be thought of as causing all the 3D transformed elements in a 3D rendering context to be hoisted up into the establishing element, but still rendered with their <a href="#accumulated-3d-transformation-matrix-computation">accumulated 3D transformation matrix</a>.
Note: Because the 3D-transformed elements in a 3D rendering context can all depth-sort and intersect with each other, they are effectively rendered as if they were siblings. The effect of transform-style: preserve-3d can then be thought of as causing all the [=3D transformed elements=] in a 3D rendering context to be hoisted up into the establishing element, but still rendered with their <a href="#accumulated-3d-transformation-matrix-computation">accumulated 3D transformation matrix</a>.

<div class="example">
<pre>
Expand Down Expand Up @@ -325,7 +331,7 @@ This example shows show elements in a 3D rendering context can intersect. The co

The ''perspective'' property can be used to ensure that 3D transformed elements in the resulting 3D rendering context appear to live in a common three-dimensional space with depth, by suppling a common perspective matrix to descendant transformed members of its 3D rendering context, which is taken into account in the <a href="#accumulated-3d-transformation-matrix-computation">accumulated 3D matrix computation</a>.

By default, elements with value for ''perspective'' other than ''perspective/none'' are flattening, and thus establish a 3D rendering context. However, setting ''transform-style'' to ''preserve-3d'' allows the perspective element to extend its containing 3D rendering context (provided no other <a href="#grouping-property-values">grouping property values</a> are in effect).
By default, elements with value for ''perspective'' other than ''perspective/none'' are [=flattening element|flattening=], and thus establish a 3D rendering context. However, setting ''transform-style'' to ''preserve-3d'' allows the perspective element to extend its containing 3D rendering context (provided no other <a href="#grouping-property-values">grouping property values</a> are in effect).

<div class="example">
<pre>
Expand Down Expand Up @@ -356,7 +362,7 @@ By default, elements with value for ''perspective'' other than ''perspective/non
&lt;/div>
</pre>

This example shows how nested 3D transforms are rendered. 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 the same 3D rendering context; the parent is "flattening". Thus the lime element only appears shorter; it does not "pop out" of the blue element.
This example shows how nested 3D transforms are rendered. 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 the same 3D rendering context; the parent is [=flattening element|flattening=]. Thus the lime element only appears shorter; it does not "pop out" of the blue element.

<div class="figure">
<img src="examples/3d-rendering-context-flat.png" width="240" height="200" alt="Nested 3D transforms, with flattening">
Expand All @@ -365,7 +371,7 @@ This example shows how nested 3D transforms are rendered. The blue div is transf

### Transformed element hierarchies ### {#transformed-element-hierarchies}

By default, <a>transformed elements</a> are flattening, and thus establish a <a>3D rendering context</a>. However, since it is useful to construct hierarchies of transformed objects that share a common 3-dimensional space, this flattening behavior may be overridden by specifying a value of ''preserve-3d'' for the ''transform-style'' property, provided no other <a href="#grouping-property-values">grouping property values</a> are in effect. This allows descendants of the transformed element to share the same 3D rendering context. Non-3D-transformed descendants of such elements are rendered into the plane of the element in step C above, but 3D-transformed elements in the same 3D rendering context will "pop out" into their own planes.
By default, <a>transformed elements</a> are [=flattening element|flattening=], and thus establish a <a>3D rendering context</a>. However, since it is useful to construct hierarchies of transformed objects that share a common 3-dimensional space, this flattening behavior may be overridden by specifying a value of ''preserve-3d'' for the ''transform-style'' property, provided no other <a href="#grouping-property-values">grouping property values</a> are in effect. This allows descendants of the transformed element to share the same 3D rendering context. Non-3D-transformed descendants of such elements are rendered into the plane of the element in step C above, but 3D-transformed elements in the same 3D rendering context will "pop out" into their own planes.

<div class="example">
<pre>
Expand Down Expand Up @@ -419,7 +425,7 @@ Note: as described here, the <a>accumulated 3D transformation matrix</a> takes i

Using three-dimensional transforms, it's possible to transform an element such that its reverse side is visible. 3D-transformed elements show the same content on both sides, so the reverse side looks like a mirror-image of the front side (as if the element were projected onto a sheet of glass). Normally, elements whose reverse side is towards the viewer remain visible. However, the 'backface-visibility' property allows the author to make an element invisible when its reverse side is towards the viewer. This behavior is "live"; if an element with ''backface-visibility: hidden'' were animating, such that its front and reverse sides were alternately visible, then it would only be visible when the front side were towards the viewer.

Visibility of the reverse side of an element is considered using the <a>accumulated 3D transformation matrix</a>, and is thus relative to the enclosing flattening element.
Visibility of the reverse side of an element is considered using the <a>accumulated 3D transformation matrix</a>, and is thus relative to the enclosing [=flattening element=].

Note: This property is useful when you place two elements back-to-back, as you would to create a playing card. Without this property, the front and back elements could switch places at times during an animation to flip the card. Another example is creating a box out of 6 elements, but where you want to see only the inside faces of the box.

Expand Down Expand Up @@ -1106,6 +1112,74 @@ The transform functions <<matrix()>>, ''matrix3d()'' and ''perspective()'' get c

For interpolations with the primitive ''rotate3d()'', the direction vectors of the transform functions get normalized first. If the normalized vectors are equal, the rotation angle gets interpolated numerically. Otherwise the transform functions get converted into 4x4 matrices first and interpolated as defined in section <a href="#matrix-interpolation">Interpolation of Matrices</a> afterwards.

Addition and accumulation of transform lists {#combining-transform-lists}
============================================

<div algorithm="transform list addition">
<a lt="value addition">Addition</a> of two transform lists
<var>V<sub>a</sub></var> and <var>V<sub>b</sub></var>
is defined as [=list=] concatenation
such that <var ignore>V<sub>result</sub></var> is equal to
<var>V<sub>b</sub></var> [=list/appended=] to
<var>V<sub>a</sub></var>.
</div>

<div algorithm="transform list accumulation">
<a lt="value accumulation">Accumulation</a> of two transform lists
<var>V<sub>a</sub></var> and <var>V<sub>b</sub></var>
follows the same steps as interpolation
with regards to matching transform functions including
padding lists with <a>identity transform functions</a>,
converting ''transform/none'' to an <a>identity transform function</a>,
and converting both arguments to matrices as necessary (see
[[css-transforms-1#interpolation-of-transforms]]).
However, instead of interpolating the individual parameters,
they are combined using arithmetic addition--
except in the case of parameters whose value is one in the
<a>identity transform function</a>
(e.g. scale parameters and matrix elements
<var ignore>m11</var>, <var ignore>m22</var>,
<var ignore>m33</var>, and <var ignore>m44</var>),
which combine using <dfn export>accumulation for one-based values</dfn>
as follows:

<var ignore>V<sub>result</sub></var> =
<var>V<sub>a</sub></var> + <var>V<sub>b</sub></var> - 1

<div class="note">
The above definition preserves the intent of <a lt="value
accumulation">accumulation</a> which is that
<var>V<sub>b</sub></var> acts as
a delta from <var>V<sub>a</sub></var>
and allows an animation such as:

<pre class="lang-javascript">
div.animate(
{ transform: ['scale(1)', 'scale(2)'] },
{
duration: 1000,
easing: 'ease',
}
);
</pre>

to produce the expected behavior when extended as follows:

<pre class="lang-javascript">
div.animate(
{ transform: ['scale(1)', 'scale(2)'] },
{
duration: 1000,
easing: 'ease',
<strong>iterations: 5,
iterationComposite: 'accumulate',</strong>
}
);
</pre>
</div>
</div>


Mathematical Description of Transform Functions {#mathematical-description}
===============================================

Expand Down
51 changes: 0 additions & 51 deletions web-animations-1/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -3068,57 +3068,6 @@ to the property's specified {{PropertyDescriptor/syntax}}
or when the <a>custom property</a> is not registered,
the <a>animation type</a> is <a>discrete</a>.

<h4 id="transform-list-animation-type-section">Transform list</h4>

A property whose <a>animation type</a> is <dfn
lt="transform list animation type">transform list</dfn> has the following
behavior:

* <a lt="interpolation">interpolation</a>:
as defined in <a
href="https://www.w3.org/TR/css-transforms-1/#interpolation-of-transforms">Interpolation
of Transforms</a> [[CSS3-TRANSFORMS]].

* <a lt="value addition">addition</a>: performed by
concatenating transform lists as
&lsquo;<var>V</var><sub>a</sub> <var>V</var><sub>b</sub>&rsquo;.

* <a lt="value accumulation">accumulation</a>:

1. Beginning at the end of each list, <var>V</var><sub>a</sub>
and <var>V</var><sub>b</sub>,
find the largest contiguous portion of each list where the
corresponding list elements from each list have the same
transform type.
Call the matching portions from <var>V</var><sub>a</sub> and
<var>V</var><sub>b</sub>, <var>V</var><sub>matching-a</sub>
and
<var>V</var><sub>matching-b</sub> respectively and likewise
<var>V</var><sub>remainder-a</sub> and
<var>V</var><sub>remainder-b</sub> for the non-matching
parts.
<p class="issue">
We should probably expand 2d functions to their 3d
equivalents before matching?
</p>
2. Let <var>V</var><sub>combined</sub> be a transform list
combining <var>V</var><sub>matching-a</sub> and
<var>V</var><sub>matching-b</sub> by adding the numeric
components of each corresponding function.
<p class="issue">
This needs to be more specific, e.g. when combining
<code>translate(20px)</code> and <code>translate(30px
10px)</code> we have to expand the first function to
<code>translate(20px 0px)</code> first.
Probably need to define unit conversion too.
</p>
3. The result of accumulation is a transform list created by <a
lt="value addition">adding</a> the combined result
with the non-matching portions of the two lists as follows:
&lsquo;<var>V</var><sub>remainder-a</sub>
<var>V</var><sub>remainder-b</sub>
<var>V</var><sub>combined</sub>&rsquo;.


<h3 id="keyframe-effects">Keyframe effects</h3>

Expand Down