Re: [css-transitions] Proposal and RFC: spring() timing function

On Thu, Jun 30, 2016 at 6:05 PM, Dean Jackson <dino@apple.com> wrote:
> On 1 Jul 2016, at 7:38 AM, Tab Atkins Jr. <jackalmage@gmail.com> wrote:
>> On Wed, Jun 29, 2016 at 9:32 PM, Dean Jackson <dino@apple.com> wrote:
>>> spring(mass stiffness damping initialVelocity)
>>>
>>>  Simulate a spring using the solving algorithm defined by this JavaScript
>>>  function [1].
>>>
>>>  mass: The mass of the object attached to the end of the spring. Must be greater
>>>  than 0. Defaults to 1.
>>>
>>>  stiffness: The spring stiffness coefficient. Must be greater than 0.
>>>  Defaults to 100.
>>>
>>>  damping: The damping coefficient. Must be greater than or equal to 0.
>>>  Defaults to 10.
>>>
>>>  initialVelocity: The initial velocity of the object attached to the spring.
>>>  Defaults to 0, which represents an unmoving object. Negative values
>>>  represent the object moving away from the spring attachment point, positive
>>>  values represent the object moving towards the spring attachment point.
>>
>> These all look like they're <number>s? Is that intentional? Can they
>> be typed in some way?  In particular, it looks like stiffness might be
>> amenable to becoming <percentage>?
>
> They are all numbers. I don't think percentage makes sense - what are
> they are percentage of?

I don't know - I was asking because it seemed like a stiffness with a
min of 0 and a default of 100 felt like something that might be a
percentage.

> This brings up the question a few people have asked: what are the units
> for all these? The answer is it doesn't really matter :) The output value
> is determined by the parameters fed to the solving function. You could
> assign some units if you like, but it's not like initialVelocity is in
> pixels per second.

And given the reminder you provided that you can be animating anything
with a spring function, such as color, I suppose units would have to
be oddly abstract anyway.

Okay, so the main benefits of unitted values is that they (a)
distinguish values from each other, so you can more easily omit
arbitrary bits, and (b) help identify the values mnemonically.  The
current "everything is a number" fails on both counts, as the only way
to identify things is positionally, so you can only omit from the end,
and you'll have to look up what the values are every time.

I think we shouldn't ignore these benefits. We can recapture them with
explicit labelling, by putting in keywords before each of the values.
That way you can just do `spring(mass 2 velocity 5)` and it'll fill in
the defaults for the rest!

(Alternate syntax: use units for these, like `spring(2mass
5velocity)`. Stronger connection between value and type, but also
maybe weird? Unsure.)

(Second alternate syntax: finally invent "named arguments" for real,
like some people have been agitating for for a while.  `spring(mass:
2; velocity: 5;)`?  To be less weird we'd have then go and backport
this to other functions. Probably a decent idea? Need to noodle on
syntax more, look at several different functions that use syntax
differently.

>>> What's unusual about this form of timing function is that the animation
>>> effect is now independent of its duration. The spring timing function
>>> completely controls how the animation reaches its end point, and certain
>>> parameter values can produce an animation that does not settle at the end
>>> point before the animation duration expires (technically they never
>>> completely settle).
>>
>> Is it possible to get the opposite behavior, and leave one or more of
>> the parameters undefined, then auto-compute them from the desired
>> time?  (Just curious, I don't have a use-case in mind for this.)  The
>> equation looks annoyingly non-linear, but I dunno.
>
> The problem here is that the equation never technically settles, so we'd
> have to pick some epsilon value for distance from end point and rate of change,
> and then call that the end. I'm not sure how hard it would be to work
> back from that to a set of inputs, but I think if we fix some of them
> to default values we should be able to auto-compute at least one.

Right, but "the duration never technically settles" applies to
"specify all of them and use an auto duration", too.

> We could pick another formula that is more amenable to duration-based
> springs.
>
> However, there is some criticism against coding an animation like this
> purely on duration:
> https://medium.com/@flyosity/your-spring-animations-are-bad-and-it-s-probably-apple-s-fault-784932e51733

That criticism is geared towards a bad API design that required you to
specify a *technically redundant* duration, and if you didn't specify
what the algo would have "naturally" provided you get an
unnatural-looking result.

I don't think it directly applies to "specify any four out of (the
four spring arguments) + duration, we'll auto-compute the fifth".
There might be other good arguments against that, maybe even closely
related ones, I dunno, but that article in particular doesn't argue
against this afaict.

>>
>>> We therefore also propose a new keyword for duration: "auto", which means
>>> the duration will be calculated to be the time where the animation has settled.
>>>
>>> NOTE: Lots of hand-waving here at the moment. Firstly, what "settle" means
>>> to most people is dependent on the type of animation, and the size of the
>>> animating object, and the distance being animated over. Secondly, we'd need to
>>> describe how this works for a keyframed animation, where the duration applies
>>> over all the keyframes.
>>
>> "auto" seems reasonable here, but we also have to define what it means
>> for all the other timing functions.
>
> At the moment we were thinking that auto only makes sense for springs. I
> am happy for it to be 0 or some other value if we'd rather it do something.

Yeah, I don't have a strong opinion on what it should be, just noting
that it needs to have *a* definition.  Matching the default 0s value
for t/a-duration is probably good, yeah.

>>> The spring() timing function as described above has been implemented in
>>> WebKit. It is currently exposed in the Safari Technology Preview, although note
>>> that the current implementation does not handle optional parameters (you have
>>> to specify them all). It's not exposed in regular Safari builds - we'll consider
>>> that if we can reach consensus here.
>>
>> Are the parameters currently arranged in the most useful order for
>> defaulting? If they're all untyped numbers, the only way to omit is
>> in-order from the end...
>
> Yeah. This is something we were hoping to get feedback on.

I addressed this up above.

~TJ

Received on Friday, 1 July 2016 21:13:42 UTC