Re: [web-animations] Simplifying timing groups

Hi list,

Responses inline.


On Thu, Aug 8, 2013 at 1:25 PM, Brian Birtles <bbirtles@mozilla.com> wrote:

> Hi public-fx,
>
> I have a proposal to simplify Web Animations by not allowing timing
> functions on groups (at least not yet, see the last part).
>
>
> MOTIVATION:
>
> Allowing arbitrary timing functions on groups complicates Web Animations
> in many ways:
>
> i. It means you can't convert from an animation's local time to the
> corresponding document time since timing functions are not always
> invertible. This introduces all sorts of complexity. For example, for event
> handling to report both a local time and document time for an event we have
> introduced uneased timing[1] which is not well-liked and as an alternative
> we have considered some fairly arbitrary approximations.
>

I think this is a misrepresentation. Every observable animation start, end
and iteration change has an exact corresponding document time. These times
are in general derivable from the timing functions.

Uneased timing was an attempt to restrict the number of events generated
for each state change to 1, even if an animation actually started, ended,
and/or changed iteration multiple times. It was unpopular since it tried to
do so by pretending that timing functions didn't exist, which could lead to
(among other problems) event times being which were completely outside the
active interval of the animation.

If anything, this desire to misrepresent what is actually occurring to
animations is at fault. Consider an analogous situation: iterations are a
form of carefully controlled timing function. It would be weird if child
animations only generated a single start and end event, regardless of the
number of iterations the parent went through.


> It also introduces some as-yet unresolved questions such, "If a timing
> function on a group causes a child to oscillate between being in and out of
> the active phase repeatedly, perhaps even a dozen times in 100ms for a
> spring function, do we dispatch events for every one of those transitions?"
> (And if we have real spring functions the number of crossings would depend
> on how you evaluate the function and could be huge.)
>

If we have short iteration durations and lots of iterations we have the
same problem.


> ii. It introduces complexity when timing functions on groups overshoot the
> [0, 1] range since then children won't stretch as they would if the timing
> function was applied directly to them, but rather will go into their fill
> behavior which will result in them being clipped. We discussed this
> previously[2] and considered adding special handling specifically for this
> situation which feels at least a little bit hacky (it involves passing
> extra state around and is only applied to children that touch the edge of
> their parent).
>

This is partly true. Timing functions on children only stretch because we
decided to handle that situation specifically. If this is the correct
approach then it is natural to extend that handling to groups.


> iii. It complicates implementation since this feature makes it difficult
> to decompose timing hierarchies into simple animations that could be passed
> off to another process or even another API. Without this feature, any
> timing hierarchy could potentially be flattened down to a series of very
> simple sub-animations. (For example, an iteration count of a group would be
> represented by producing several sub-animations, one for each iteration. A
> direction setting on a group could be represented by flipping the playback
> rate on some of those sub-animations etc. On the other hand, splitting a
> timing function on a parent into pieces, then combining the appropriate
> piece with any timing functions already applied to the child's
> sub-animations, is far more complex.)
>

This is false. It is entirely possible to decompose timing hierarchies with
timing functions on groups. Given that timing functions need to be
represented in the simple sub-animations anyway, it is not much of a
stretch at all to allow a stacked timing function to be used here.


> I'm not sure if implementations will actually take this approach but I
> think the fact that arbitrary timing functions on groups greatly
> complicates this approach is indicative of the complexity introduced by
> this feature.
>

I think you're greatly overstating the complexity that this feature
introduces.


>
> OBSERVATIONS:
>
> No other animation API I can find allows arbitrary timing functions on
> groups.
>

I'm not sure how this is particularly relevant. However:


>
> For example,
>
> * Core Animation talks about groups and timing functions but the groups in
> this case correspond to our keyframe animations. That is, a set of
> properties being animated together.
>
> * GSAP, which has an impressive feature set, has no 'ease' property on
> TimelineLite / TimelineMax.


GSAP allows you to tween both the currentTime and the timeScale on
TimelineLite and TimelineMax, which is the same thing as a timing function.


> * WPF which has, by far, the most complicated animation API I have ever
> seen, only has easing functions on animations.
>

WPF provides at least the ability to accelerate and decelerate Timelines,
from which both Animations and TimelineGroups inherit.


>
> * SMIL3, as discussed later, which is infamous for its complexity, does
> not allow arbitrary timing functions on groups.
>

And yet SMIL3 does supply auto-reversing, which is not invertible.


> This begs the question, do we really need this?
>

If you choose your features based on what everybody else does, then given
that 3/4 of the animations engines you supplied provide it, the answer is
clearly yes. However, I'd prefer to analyse whether this feature is
*useful* and proceed from there.


> A further implication of the fact that other APIs don't provide this
> facility is that it is therefore probably quite difficult to implement the
> Web Animations model on top of an existing animation API.
>

So is it a further implication of the fact the 3/4 APIs do provide this
facility that it's probably quite simple to implement the Web Animations
model on top of an existing animation API?


> PROPOSAL:
>
> I propose making timing functions a property of animations only, at least
> initially. This would have the following benefits:
>
> * Events become a lot simpler. There is no need for uneased timing or
> approximations of timing functions and no questions about which events get
> dispatched.
>

This is true. However, I think it's based on a misconstruing of how the
event system should behave.


> * In general, provided the 'current iteration' of each parent is known, it
> is possible to convert from an animation's local time to document time
> which may be useful in a number of contexts (it may, for example, be
> something we expose via the API in future).
>

This is always possible. Note that sometimes multiple document times can
produce the same local time. Note further that this is already true in the
presence of iterations, without taking timing functions into account.


> * There is no need for special overflow fill handling.
>

We already perform special overflow fill handling on Animations. Why are
TimingGroups different?


> * Implementations can easily flatten timing hierarchies into
> sub-animations and pass them off to a separate process and possibly another
> animation API.
>

As mentioned above, I think you're overstating the complexity of this.


> * Media references are not required to support timing functions initially.
> If timing functions are useful there, we can determine the sort of timing
> functions that are readily implementable and restrict the set of timing
> functions permitted accordingly. For example, overshoot doesn't make much
> sense for media. Likewise, some features of chained timing functions
> probably don't make much sense for anything other than animations (like the
> keyframe alignment feature).
>

This is an orthogonal issue to your proposal.


> * For timing groups, we can likewise add a restricted set of timing
> functions later as needed. Due to the complications noted above, such
> timing functions could be restricted so that they are invertible and can't
> go outside the [0, 1] range. Note that this is what SMIL3 does.[3] For time
> containers (groups) it defines time manipulations and these include only
> playback rate control, auto-reversing, and accelerate/decelerate (which can
> be combined to produce ease-in / ease-out effects where the result is
> invertible and in the range [0, 1]).
>

SMIL3's restricted set of timing functions aren't invertible.


> There are a number of options for how we might represent this in the API
> but I'd like to start by deciding about the model.
>

It's probably clear by now that I don't agree with your reasoning. Can we
come at this question from a use-case based analysis instead?

For a start, timing functions on groups make it easy to:
(1) keep the timing of a number of animations in sync (by applying the
function to a ParGroup)
(2) smear a timing function across a composite effect (for example,
applying an ease-in across a SeqGroup containing multiple child animations)
(3) keeping consistent timing across a complex hierarchy of ParGroups and
SeqGroups

Without timing functions on groups, how would you provide this
functionality?

Sincerely,
    -Shane Stephens

Best regards,
>
> Brian
>
> [1] http://www.w3.org/TR/web-**animations/#uneased-timing<http://www.w3.org/TR/web-animations/#uneased-timing>
> [2] http://lists.w3.org/Archives/**Public/public-fx/2013AprJun/**0184.html<http://lists.w3.org/Archives/Public/public-fx/2013AprJun/0184.html>,
> item 15
> [3] http://www.w3.org/TR/SMIL/**smil-timemanip.html#TimeManip-**
> Overview-support<http://www.w3.org/TR/SMIL/smil-timemanip.html#TimeManip-Overview-support>
>
>

Received on Thursday, 8 August 2013 04:33:26 UTC