# Re: [csswg-drafts] [css-transitions][css-animations] Complex timing functions

From: VisibleCode via GitHub <sysbot+gh@w3.org>
Date: Fri, 24 Jun 2016 05:12:10 +0000

Message-ID: <issue_comment.created-228259642-1466745129-sysbot+gh@w3.org>
```Cubic beziers aren't a bad choice for timing functions. They're very
easy to evaluate (just a few additions and multiplications). Also,
most animation tools use some form of cubic spline to specify
animation paths, which can be converted into cubic bezier easings with
good fidelity.

There are two problems with `cubic-bezier()` as it is currently
specced, however:

1. You can't specify a spline of multiple segments
2. `cubic-bezier()` is abusing 2d parametric curves to specify 1d
functions

points to the cubic-bezier() syntax. I believe this has already been
proposed in various forms.

The second issue is pretty significant, though, and deserves some
unpacking. `cubic-bezier()` is specified as a _2d_ bezier, a 2d
parametric curve. This has a lot of implications, including:

1. Without additional constraints, the resulting curve isn't
guaranteed to have a singular y value for a given x and can't be used
to define a mathematical function. This has been dealt with by
restricting x to the range [0, 1], but that doesn't actually address
the root (no pun) problem -- because a cube root is involved there are
still two extra solutions in the complex plane.
2. As mentioned, implementors must solve cube roots to work backwards
from x to the implicit t parameter, before they get to the normal (and
much simpler/exact!) bezier calculation to evaluate the easing
function.
3. Tool authors who want to do a direct conversion of cubic spline
segments to cubic-bezier()s have no use at all for the extra
dimension, but must clutter the output with decimal approximations of
1/3 and 2/3.

The extra dimension isn't useful and makes life harder for
implementors and tool authors alike. Ideally, instead of having to
specify a two-dimensional curve like `cubic-bezier(0.33333, 0.4,
0.66666, 0.6)`, we ought to have gotten _one-dimensional_ curves, e.g.
`cubic-bezier(0.4, 0.6)`.

With one dimension, instead of having to work backwards from
(normalized) time to an implicit t, the normalized time could be used
directly as the input without having to solve cube roots first.

I guess if I were going to make a concrete proposal, I'd like to see
syntax for specifying 1d bezier splines, in a format something like
`cubic-spline(c, [c,t,c,]* c)` (where the cs and ts are numbers).

The first and last values are exactly like the control points in
`cubic-bezier()`, except since we're only dealing with one dimension,
the "control points" are specified by scalar values, rather than pairs
of them.

Between those end "control values", you could have zero or more
(control value, time, control value) triples representing intermediate
knots with their adjacent control "points". The knot positions (the
middle value of the triples) would have to be monotonically
increasing, in the range (0, 1).

As a concrete example, let's take the following complex easing:

```
@keyframes example {
from {
some-property: 100px;
animation-timing-function: cubic-bezier(0.33333, 0.25,
0.66666, 0.8);
}
50% {
some-property: 75px;
animation-timing-function: cubic-bezier(0.33333, 0.5,
0.66666, 0.6);
}
to {
some-property: 50px;
}
}
```
Given the aforementioned `cubic-spline()` function, you could define
the same animation more simply as:

```
@keyframes example {
from {
some-property: 100px;
animation-timing-function: cubic-spline(0.125, 0.4,0.5,0.75,
0.8);
}
to {
some-property: 50px;
}
}
```

IMO this seems better for both export tooling and hand authoring.

One thing this proposal doesn't address are use cases where you want
easings/animations with sudden jumps in them. (i.e. not C0 continuous)
Having multiple intermediate CSS keyframes may still be a good answer
for animations with discontinuities (rather than trying to define
timing functions with discontinuities), though in order to do that
there would need to be a mechanism to specify different incoming and
outgoing property values for a CSS keyframe.

--
GitHub Notification of comment by visiblecode
Please view or discuss this issue at
https://github.com/w3c/csswg-drafts/issues/229#issuecomment-228259642