w3c / csswg-drafts

CSS Working Group Editor Drafts
https://drafts.csswg.org/
Other
4.48k stars 659 forks source link

[css-values] Add easing function interpolation to calc #6697

Open smfr opened 3 years ago

smfr commented 3 years ago

It should be possible to compute the output of an easing function, given an input fraction, in calc. Something like: width: calc(100% * interpolate(ease-in-out, 0.7)). The first argument to interpolate() would accept any of the easing functions specified in https://drafts.csswg.org/css-easing-1/#easing-functions.

smfr commented 3 years ago

This would allow calc to cover some of the use cases proposed for https://github.com/w3c/csswg-drafts/issues/6245

tabatkins commented 3 years ago

What about a math-specific interpolation function, akin to color-mix() and cross-fade(), that allows a % and an easing function? Like interp(70% ease-in-out, 100px, 40em).

Loirooriol commented 3 years ago

Like https://github.com/w3c/csswg-drafts/issues/581#issuecomment-926353789, but just for calculation values?

tabatkins commented 3 years ago

Yeah. Single-value mixing functions intended to be allowed everywhere need to advertise their type in a way that's determinable at parse-time, like color-mix() or cross-fade() do. Math functions can determine their type at parse time; we'd do the same here. (Like, say, min(), the type of the function would be the result of adding the types of the two arguments, so you could mix "50%" and "20px", but not "20px" and "30deg".)

smfr commented 3 years ago

interp(70% ease-in-out, 100px, 40em) would be identical to: calc(100px + interpolate(ease-in-out, 70%) * (40em - 100px)) I think?

Maybe we need lerp(start, end, fraction) so you can do calc(100px + lerp(100px, 40em, interpolate(ease-in-out, 70%)))

I think calc() should generally expose the primitives, but add convenience functions when appropriate.

fantasai commented 3 years ago

Whatever syntax we're adding here, it should be consistent with mix() as possible.

tabatkins commented 3 years ago

Rather than adding a lerp() that takes a progress amount, and an interpolate() that computes a progress amount from an easing function, we can just do the two together like I suggested. ^_^ We should design it to be easy in the situations we expect it to be used, rather than just providing primitives that might be awkward or verbose in practice.

If you do need the raw progress value that's easy to extract by just using 0 and 1 as the start/end values.

birtles commented 3 years ago

(For what it's worth, I wonder if we'd really use the easing parameter as part of the serialization from animations. We're going to have to evaluate the effect easing first anyway in order to find the keyframes to interpolate between, so we may as well evaluate the keyframe easing too -- especially given some of the very verbose easing functions we looking to introduce soon. Furthermore, we'd still need to work out how to represent addition in CSS in order to be able to use this function in any computed value.)