Skip to content

Commit 81d7081

Browse files
committed
[css-transforms-1] Specify the "pad, interpolate prefix, then smoosh" interpolation behavior
This fixes w3c#927.
1 parent c5115ea commit 81d7081

File tree

1 file changed

+66
-34
lines changed

1 file changed

+66
-34
lines changed

css-transforms-1/Overview.bs

Lines changed: 66 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,45 +1092,76 @@ The scaling causes a non-invertible CTM for the coordinate space of the div box.
10921092
Interpolation of Transforms {#interpolation-of-transforms}
10931093
==========================================================
10941094

1095-
When animating or transitioning transforms, the transform function lists must be interpolated. For interpolation between one transform <em>from-transform</em> and a second transforms <em>to-transform</em>, the rules described below are applied.
1095+
[=Interpolation=] of transform function lists is performed as follows:
10961096

10971097
<ul>
1098-
<li id="none-none-animation">
1099-
If both the <em>from-</em> and <em>to-transform</em> are ''transform/none'':
1100-
* There is no interpolation necessary. The computed value stays ''transform/none''.
1101-
1102-
<li id="none-transform-animation">
1103-
If one of the <em>from-</em> or <em>to-transforms</em> is ''transform/none'':
1104-
* The value ''transform/none'' is replaced by an equivalent [=identity transform function=] list for the corresponding transform function list. Both transform function lists get interpolated following the next rule.
1105-
1106-
<div class="example">
1107-
For example, if <em>from-transform</em> is ''scale(2)'' and <em>to-transform</em> is ''transform/none'' then the value ''scale(1)'' will be used for <em>to-transform</em> and animation will proceed using the next rule. Similarly, if <em>from-transform</em> is ''transform/none'' and <em>to-transform</em> is ''scale(2) rotate(50deg)'' then the animation will execute as if <em>from-transform</em> is ''scale(1) rotate(0)''.
1108-
1098+
<li id=none-none-interpolation>
1099+
If both <var>V<sub>a</sub></var> and <var>V<sub>b</sub></var>
1100+
are ''transform/none'':
1101+
* <var>V<sub>result</sub></var> is ''transform/none''.
1102+
1103+
<li id=transform-interpolation-length-fixup>
1104+
Treating ''transform/none'' as a list of zero length,
1105+
if <var>V<sub>a</sub></var> or <var>V<sub>b</sub></var> differ in length:
1106+
* extend the shorter list to the length of the longer list,
1107+
setting the function at each additional position
1108+
to the [=identity transform function=] matching
1109+
the function at the corresponding position in the longer list.
1110+
Both transform function lists are then interpolated
1111+
following the next rule.
1112+
1113+
<div class=example>
1114+
For example, if <var>V<sub>a</sub></var> is ''scale(2)''
1115+
and <var>V<sub>b</sub></var> is ''transform/none''
1116+
then the value ''scale(1)'' will be used for <var>V<sub>b</sub></var>
1117+
and interpolation will proceed using the next rule.
1118+
Similarly, if <var>V<sub>a</sub></var> is ''scale(1)''
1119+
and <var>V<sub>b</sub></var> is ''scale(2) rotate(50deg)''
1120+
then the interpolation will be performed as if
1121+
<var>V<sub>a</sub></var> were ''scale(1) rotate(0)''.
11091122
</div>
11101123

1111-
<li id="transform-transform-animation">
1112-
If <em>from-</em> and <em>to-transform</em> have the same number of transform functions, each transform function pair has either the same name, or is a derivative of the same <a href="#transform-primitives">primitive</a>:
1113-
* Interpolate each transform function pair as described in <a href="#interpolation-of-transform-functions">Interpolation of transform functions</a>. The computed value is the resulting transform function list.
1114-
1115-
<div class="example">
1116-
For example, if <em>from-transform</em> is ''scale(1) translate(0)'' and <em>to-transform</em> is ''translate(100px) scale(2)'' then ''scale(1)'' and ''translate(100px)'' as well as ''translate(0)'' and ''scale(2)'' don't share a common primitive and therefore can not get interpolated following this rule.
1117-
1124+
<li>
1125+
Let <var>V<sub>result</sub></var> be an empty list.
1126+
Beginning at the start of
1127+
<var>V<sub>a</sub></var> and <var>V<sub>b</sub></var>,
1128+
compare the corresponding functions at each position:
1129+
* While the functions have either the same name,
1130+
or are derivatives of the same
1131+
[[#transform-primitives|primitive transform function]],
1132+
interpolate the corresponding pair of functions as described in
1133+
[[#interpolation-of-transform-functions]]
1134+
and append the result to <var>V<sub>result</sub></var>.
1135+
* If the pair do not have a common name
1136+
or [[#transform-primitives|primitive transform function]],
1137+
post-multiply the remaining transform functions in each of
1138+
<var>V<sub>a</sub></var> and <var>V<sub>b</sub></var> respectively
1139+
to produce two 4x4 matrices.
1140+
[=Interpolate=] these two matrices as described in
1141+
[[#matrix-interpolation]],
1142+
append the result to <var>V<sub>result</sub></var>,
1143+
and cease iterating over
1144+
<var>V<sub>a</sub></var> and <var>V<sub>b</sub></var>.
1145+
1146+
<div class=example>
1147+
For example,
1148+
if <var>V<sub>a</sub></var> is ''rotate(0deg) scale(1) translate(20px)''
1149+
and <var>V<sub>b</sub></var> is ''rotate(270deg) translate(10px) scale(2)'',
1150+
the ''rotate(0deg)'' and ''rotate(360deg)'' functions will be interpolated
1151+
according to [[#interpolation-of-transform-functions]]
1152+
while the remainder of each list--
1153+
''scale(1) translate(20px)'' and ''translate(10px) scale(2)''--
1154+
will first be converted to equivalent 4x4 matrices
1155+
and then interpolated as described in [[#matrix-interpolation]].
1156+
1157+
A previous version of this specification
1158+
did not attempt to interpolate matching pairs of transform functions
1159+
unless all functions in the list matched.
1160+
As a result, the two lists in this example would be interpolated
1161+
using matrix interpolation only
1162+
and the ''rotate(360deg)'' component of the second list would be lost.
11181163
</div>
11191164

1120-
<li id="transform-transform-neutral-extend-animation">
1121-
If <em>from-</em> and <em>to-transform</em> have a different number of transform functions, and the functions of the shorter transform list have either the same name, or are derivatives of the same <a href="#transform-primitives">primitive</a> of the function at the equivalent position in the longer list:
1122-
* Extend the shorter list to the length of the longer list, setting the function at each additional position to the [=identity transform function=] matching the function at the equivalent position in the longer list.
1123-
1124-
* Interpolate each transform function pair as described in <a href="#interpolation-of-transform-functions">Interpolation of transform functions</a>. The computed value is the resulting transform function list.
1125-
1126-
<div class="example">
1127-
For example, if <em>from-transform</em> is ''scale(1.5)'' and <em>to-transform</em> is ''scale(1.5) rotate(720deg)'', it interpolates as if the <em>from-transform</em> were specified as ''scale(1.5) rotate(0deg)''.
1128-
</div>
1129-
1130-
<li id="other-animation">
1131-
In all other cases:
1132-
* The transform functions of each transform function list on the <em>from-</em> and <em>to-transform</em> get <a>post-multiplied</a> and converted into 4x4 matrices. Each of the matrices gets interpolated following the instructions in <a href="#matrix-interpolation">Interpolation of matrices</a>. The computed value is the transform function <<matrix()>>.
1133-
11341165
</ul>
11351166

11361167
In some cases, an animation might cause a transformation matrix to be singular or non-invertible. For example, an animation in which scale moves from 1 to -1. At the time when the matrix is in such a state, the transformed element is not rendered.
@@ -1502,7 +1533,8 @@ The following changes were made since the <a href="https://www.w3.org/TR/2017/WD
15021533
* Clarify behavior of 'transform' on overflow area.
15031534
* Remove ''translateX(0)'', ''translateY(0)'', ''scaleX(0)'', ''scaleY(0)'' from the list of neutral elements.
15041535
* Remove any reference of 3D transformations of transform function definitions.
1505-
* Allow interpolation between some <<transform-list>>s with different length.
1536+
* Specify interpolation between <<transform-list>>s to match lengths and
1537+
avoid matrix interpolation for the common prefix of the two lists.
15061538
* No 'transform' on non-replaced inline boxes, table-column boxes, and table-column-group boxes.
15071539
* Define target coordinate space for transformations on <{pattern}>, <{linearGradient}>, <{radialGradient}> and <{clipPath}> elements.
15081540
* Remove 3-value <<rotate()>> from transform function primitives.

0 commit comments

Comments
 (0)