Web Animations/Additive Animation

From Effects Task Force

Preamble: Order of Transform Matrix Application

There's often a lot of confusion about the order in which matrix operations apply. The following section lays out the conventions adhered to by this document.

A x B is to be interpreted as A post-multiplied by B - that is, if A consists of the matrix defining a translation of (100px, 0px), and B consists of the matrix defining a rotation of 90 degrees clockwise, then:

            / 1   0  100 \     / 0    1    0 \     / 0    1   100 \
A x B =     | 0   1   0  |  x  |-1    0    0 |  =  |-1    0    0  |
            \ 0   0   1  /     \ 0    0    1 /     \ 0    0    1  /

In other words, this translation followed by rotation results in the object being shifted to the right by 100px and rotated by 90 degress. On the other hand, B x A is:

            / 0   1   0 \     / 1    0   100 \     / 0    1    0  \
A x B =     |-1   0   0 |  x  | 0    1    0  |  =  |-1    0  -100 |
            \ 0   0   1 /     \ 0    0    1  /     \ 0    0    1  /

In other words, this rotation followed by translation results in the object being shifted down by 100px and rotated by 90 degrees.

One way of interpreting this is that all operations are considered to act on the object being transformed, preserving its local origin and coordinate system. Hence in the case of AxB the translation shifts the object and its origin by 100px to the right, then the rotation acts on the object about the local origin. On the other hand, in the case of BxA the rotation rotates both the object and its coordinate system by 90 degrees, to right to the object is down in the global coordinate system, and the translation then shifts the object right locally, but down globally.

Types of Animation

There are three basic types of animation to consider when it comes to addition of animations: simple linear animations, transform-based animations, and path-based animations.

Simple Linear Animations

The majority of animatable values are independent and behave in a commutative fashion. Examples include colors, border widths, box dimensions, position described as left and top, etc. Animations involving this type of value are fundamentally easier to add than transform-based or path-based animations.

Transform-based Animations

It is possible to define 2D affine transforms on dom elements using a variety of approaches; and it is possible to animate these transform values. Addition of transform animations is complicated by the fact that transforms are non commutative - that is, in general given two transforms A and B, doing A then B does not give the same result as doing B then A.

Path-based Animations

SVG's animateMotion element allows objects to be animated along paths. Furthermore, it is possible to specify that an object should orient itself to face along the normal of a path referenced by animateMotion as the object is animated - i.e. both the location and the rotation of the object are animated simultaneously.

Introduction of a rotation component means that path-based animations are non-commutative - if an object is to follow two paths then the result will depend upon the order in which the transforms generated by those paths are evaluated.

Absolute vs. Relative Animation

Absolute animations are those in which the parameters of the animation are globally specified. For example, all CSS Transitions are specified in terms of a global start position and a global end position. On the other hand, relative animations are those in which the parameters of the animation are specified as relative offsets, either from the starting conditions, the ending conditions, or both. For example, animate elements in SVG that define the by attribute are relative animations.

Absolute animations can be recontextualized as relative animations by considering them as offsets from a defined zero point. For example, a path that starts at (0,0) could either be considered as an absolute path that starts at (0,0), or a relative path that specifies offsets from the current position of an animated element. Conversely, relative transforms can be viewed as absolute transforms by applying them to the current start and end conditions.

Note, however, that both the start and end conditions of an animation can change while the animation is in-flight. For example, the width of a container div can be changed while the width of a contained div is transitioning. Because of this fact, a relative animation can always act potentially differently to an absolute animation, even if both agree completely on animation parameters at the beginning of the animation.

In general, only relative animations can be added to other animations meaningfully, as absolute animations fix position independently of any other influence. For simplicity, I recommend that we always treat animations as relative when adding them to other animations.

Addition vs. Blending

These are two quite distinct combination operators for animations, both of which we should support.

Addition

When adding animations together, the intention is that the full effect of both animations should be applied. In practise, I can see a couple of use-cases (there are probably more, too... ):

  • Adding a small effect to a large one - e.g. pulsing the color of an object slightly while transitioning from one color to another, or supplying a path for random jitter while an object is moving from one location to another.
  • Coordinating complicated animated effects - e.g. adding the effect of one joint movement to the effect of another joint movement in an articulated figure.

Any relative animation can be added to any other animation without ambiguity. Note that animation addition is not in general commutative - A + B is different to B + A. This means that a priority ordering of animations on an element is required to support addition.

Simple Linear Animations

Each animation 'A' and 'B' will resolve unambiguously to a single value for each simple linear variable which is animating. The result of 'A + B' at each point in time is the sum of the resolved values for A and B.

Transform-based Animations

Each animation 'A' and 'B' will resolve unambiguously to transform matrices Ma and Mb. The result of 'A + B' at each point in time is the product of the two matrices Ma x Mb.

Path-based Animations

Each animation 'A' and 'B' will resolve unambiguously into position transforms Ta and Tb, and rotation transforms Ra and Rb. The result of 'A + B' at each point in time is the product Ta x Ra x Tb x Rb. Note that this implies that the motion path generated by B is rotated by the effect of moving along A's motion path - intuitively, this makes sense, as it ensures that the relative motion path defined for B remains aligned to the local coordinate system for objects being animated by B.

Blending

When blending animations, the intention is that a compromise between the blended animations should be applied. A common use case for blending is transitioning smoothly from one animation to another. When blending, a progress parameter controls the relative contributions of each animation.

Animations need to be treated as absolute animations for the purposes of blending. Blending is commutative, however, it's important to note that blend(A, blend(B, C, progress), progress) will not produce the same result as blend(blend(A, B, progress), C, progress) - in the first case, the relative contributions of A, B and C are (1 - progress), (1 - progress)x(1 - progress) and progress x progress respectively, while in the second case the relative contributions are (1 - progress) x (1 - progress), (1 - progress) x progress, and progress.

It is may not always be true that two animations can be blended together - see below for details.

It is possible to describe a blending operation that combines more than 2 animations at a time - in this case, a progress vector is required, and the vector must be normalized before application. I'm not sure if this level of complexity is warranted for the first version of the Web Animations specification; however I do feel that ultimately it will be useful functionality.

Simple Linear Animations

Any 2 simple linear animations can be blended by calculating the weighted linear average of their resolved effects.

Transform-based Animations

There are a number of different potential approaches for blending two transforms. The approach used for interpolation when generating CSS transitions and animations is described here, however what is desirable for intra-path interpolation is not necessarily desirable for inter-path interpolation, so a different approach may need to be defined.

We should investigate quaternion decomposition, slerping (Spherical Linear Interpolation), and nlerping (Normalised Linear Interpolation), and keep an eye on developments in the CSS and SVG transforms specifications.

Path-based Animations

It is possible in principle to blend any two paths, by generating the resolved values for each path at each point in time and interpolating between them. In practice a better result is obtained by blending control points only, so we could consider disallowing blending for paths with different combinations of curves, line segments, and gaps.