81 points by ndyg 8 days ago | 24 comments
EsportToys 1 day ago
Closed-form (non-iterative) PID solution:

https://www.desmos.com/calculator/mu80ttc9aa

   function sprung_response(t,pos,vel,k,c,m)
      local decay = c/2/m
      local omega = math.sqrt(k/m)
      local resid = decay*decay-omega*omega
      local scale = math.sqrt(math.abs(resid))
      local T1,T0 = t , 1
      if resid<0 then
         T1,T0 = math.sin( scale*t)/scale , math.cos( scale*t)
      elseif resid>0 then
         T1,T0 = math.sinh(scale*t)/scale , math.cosh(scale*t)
      end
      local dissipation = math.exp(-decay*t)
      local evolved_pos = dissipation*( pos*(T0+T1*decay) + vel*(   T1      ) )
      local evolved_vel = dissipation*( pos*(-T1*omega^2) + vel*(T0-T1*decay) )
     return evolved_pos , evolved_vel
   end
For anticipation, just add an extra initial velocity in the opposite direction and let the closed-form solution handle the time evolution. The main trick here is to keep both position and velocity as state. There is no need to “step through the simulation”.
creata 1 day ago
Material Design 3's "motion physics system" uses damped harmonic oscillators, too. The parameters (undamped angular frequency omega0 and damping ratio zeta) they use are on this page:

https://m3.material.io/styles/motion/overview/how-it-works

pahgawk 1 day ago
This is good! Although I'd also say that initial velocity doesn't quite cover what I was talking about in the post -- even anticipation arguably can start from 0 velocity, accelerate backwards, decelerate, then accelerate in the opposite direction. Imo, any sudden change in velocity should by default be avoided (there are always valid uses where breaking that expectation is good, but I'd want it smooth by default.)

That could possibly be done by incrementally changing force to move it back first, then forward, or to model this as a PD controller following an input with some baked in reversal before moving forward. That can still be closed-form (state response to a known input will be; Laplace transforms can help there), but still would need a bit of effort to model and tune to look right.

LegionMammal978 1 day ago
You wouldn't really need an incremental force: a step-function force (first backward for some time steps, then instantly forward) will still produce a continuous velocity curve.
pahgawk 1 day ago
true! I suppose you'd risk getting some oscillations in the anticipation depending on the scale of the force, but that could be desirable, or might not happen if the scale is small enough, and certainly makes the math a little easier
EsportToys 1 day ago
You can trivially calculate the time-to-peak overshoot using the closed form equation. It’s the first (0-indexed) zero of the velocity response, i.e. happens at t = (pi / scale)

And obviously it would only apply for the underdamped case.

joenot443 1 day ago
Wow, this is excellent!

Is there a name for this kind of motion? I'd love to use it sometime.

EsportToys 1 day ago
It’s the general solution to a damped harmonic oscillator/mass-spring-damper system:

    m * x’’ + c * x’ + k * x = f(t)
See https://web.archive.org/web/20230604215211/https://esporttoy...
ww520 1 day ago
Wow. This is so good. I would never imagine using PID control for animation motion. Saving this.
1 day ago
thomascountz 1 day ago
Wow, this is great!
esafak 1 day ago
How did you even find this site; did you make it?
thomascountz 1 day ago
The section on feedback control reminded me of procedural animation where you don't calculate the velocities and positions directly; instead the animation is a consequence of constraints and a target.

I took your PD controller concept and added anticipation using two targets: the original mouse target, and an "anticipation" target set proportionally based on the distance from the point to the main target[1].

This also made me think of Jelly Car and the amazing simulations they did using rigid frames for soft bodies, called Shape Matching[2]. Instead of simulating the soft body physics directly, they used a frame, springs, and "gas" to constrain points, which moved towards targets fixed to the frame.

[1]: https://editor.p5js.org/Thomascountz/sketches/YXWm_VV6s

[2]: https://www.gamedeveloper.com/programming/deep-dive-the-soft...

pahgawk 1 day ago
Author here! Nice, thanks for taking the time to create that demo! I also like the look of commenting out `vel.set(0, 0)` when the anticipation target is reached, as it has less "snap" between velocities. Although if you keep velocity the same, now it'll go a little farther than the anticipation target. So maybe if you wanted to have a specific distance of anticipation (I think something an animator would reasonably want to do), one could do some math to figure out where to place the target position so that by the time it decelerates to 0, the distance is the real anticipation distance.
unconed 8 days ago
Bouncy animations that overshoot just seem like a bad idea in general. The purpose of a UI animation is to guide the eye, but the bounce explicitly introduces a reversal of motion at the end before stopping.

Easing functions are just very cargo culty. We've had the same basic set that dates from the Flash era. Now there's an Apple variant that's just a parametric version of the same idea, but it lacks guaranteed continuity and it's even harder to control?

Personally I've had far better results using the repeated-lerping-towards-a-target trick, aka a true exponential ease. When stacked, you get a classic LTI (linear time invariant) system, and the math around how those behave is well established.

Classic hand-drawn animation does often use stretching and squeezing to emphasize and to create a sense of anticipation, but that's very different and always dependent on the specific motion. You can't automate that by making everything act like jello.

pahgawk 7 days ago
Hi, author here! When writing this, I was thinking more in the space of procedural character animation and motion graphics than UI animations. That's part of why I want a system with nice parameters, so that I do have the ability to fine tune and tweak the motion to fit the context. My background is in classical animation so it's something I might just keyframe by hand in a non-code context, or in Flash when it's easier to jump back and forth between code and non code. Although I think having it parameterized still can lead to interesting opportunities for variation in procedural animation!
ipv6ipv4 1 day ago
Overshoot is important for scroll views. Without the bounce, there is no feedback if you have scrolled to the edge or not. Early Android lacked the bounce, and it would invariably lead to users scrolling again to be sure they had indeed scrolled to the edge of the view.
Jensson 1 day ago
Desktop doesn't have bounce and I prefer it that way. For mobile maybe bounce is more important since its less precise than a mouse, but point is that bounce is not obviously superior since on desktop the bounce just feels buggy rather than what you want.
ipv6ipv4 18 hours ago
Desktop on Mac does if you swipe to scroll. It doesn't if you drag the scroll bar to scroll. On Windows, a scroll wheel doesn't bounce either. It doesn't need to when the scroll wheel itself provides physical feedback that you actually did something.

Touch interfaces tend to need some visual (or artificial haptic) feedback because touch itself is not enough.

panic 1 day ago
You can add the bounce as a second layer of dynamics on top of the exponential deceleration (this is how iOS scroll views do it).
Jyaif 1 day ago
> Early Android lacked the bounce

Early android had some visual feedback (a gradient that faded out) instead of the bounce, possibly because Apple owns a patent ( https://patents.google.com/patent/US7469381B2/en ).

Current Android still does not use the bounce, and instead stretches the content, which works well enough on the high resolution screens that we have now.

1 day ago
ipv6ipv4 1 day ago
Initial Android had scroll bars with no overshoot specific indication.
socalgal2 1 day ago
Why does literally every single article on easing functions mention Penner? First off he didn’t invent them. Games had been using those functions since at least the 80s.

Second, why only him and these functions? I don’t write: In JavaScript by Brendan Eich using Node.js by Ryan Dahl I installed a package using npm by Isaac Z. Schlueter called React by Jordan Walke and for the backend I used TJ Holowaychuk’s express.js. Instead just write: In JavaScript using node.js I installed react and express.js

But literally, I’ve never read an article about easing functions that just says “easing functions”. they all feel obligated to mention Penner” Why? and no, it’s not because open source or multiple contributors. I used those examples because I can’t name the 1000s of people for functions which is precisely my point

xwolfi 1 day ago
Sir, this is a Wendy
neuroscihacker 1 day ago
I wrote about analytic easing functions a number of years ago and show how to precisely design a spring function:

https://medium.com/hackernoon/the-spring-factory-4c3d988e712...

And a bounce function:

https://medium.com/hackernoon/the-bounce-factory-3498de1e526...

franciscop 1 day ago
I also didn't like when a new easing happened _while_ another easing was happening, which often felt very jerky. Had to do a bunch of calculus (derivatives) by hand and wrote a small library for it in JS:

https://github.com/franciscop/ola

Note: ola means (sea) wave in Spanish

pahgawk 1 day ago
Thanks for sharing this library! Author of the post here, I'll definitely check out your implementation.
franciscop 1 day ago
Thanks! From your article, you might not want/like my library since it's based on a single easing function. I used a cubic function to find out the interpolation values, and the derivative to make sure it's always smooth. The equation looks like this, it's on the source code:

https://www.wolframalpha.com/input/?i=x+%3D+2+*+t+%5E+3+-+3+...

If you wanted some more details please feel free to ping me (email through my website's resume, or Twitter) and I'll dig the handwritten equations.

spankalee 1 day ago
There are a lot of post and talks out there about why spring is easier to use and gives nicer results than most easing functions.

In CSS, there's a long standing feature request to add a spring() timing function: https://github.com/w3c/csswg-drafts/issues/280

This would not only be great for developer ergonomics, but would remove JS from the animation path for these cases.

x187463 1 day ago
I have found myself leaning heavily on easing functions to smooth motion within my terminal visual effects engine. I do not have a very strong math background so I am limited in how much I can modify the commonly available functions. I have found it useful to create custom easing functions by mapping the easing function progress across a bezier curve. There's an example in the changeblog write-up from the last release:

https://chrisbuilds.github.io/terminaltexteffects/changeblog...

bhk 1 day ago
Oscullation/"anticipation" in transitions is so gimmicky and cartoonish. Living things don't move like that, and mechanical things don't unless they are broken, chintzy, or poorly designed (underdamped).
magicalhippo 1 day ago
In my view we most certainly do, though of course not all the time.

Oscillations typically happen when moving quickly and then stopping at a certain position.

A prime example is the ISSF 25m rapid fire pistol event, where you start with the pistol pointing down at 45 degrees, and within 8, 6 and 4 seconds have to raise the pistol and take 5 aimed shots.

Beginners will often find they oscillate vertically above and below the center of the target as they raise the pistol, and it usually takes a fair bit of practice not to oscillate. This is more pronounced at the rapid pistol events due to the tight time constraint forcing them to move quickly, especially at the final 4 second round.

Another example is gymnastic rings, especially when they go from a swinging motion to stopping vertically or horizontally.

Anticipation-like movement often occurs when we want to get a bit of extra momentum. For example, casually tossing a base ball or tennis ball often results in a bit of backwards movement first, before the main swing. Typically it's one smooth movement.

thomascountz 1 day ago
Think of a slingshot? Or a person jumping?[1].

We see this, not only in mammals and muscles, but in organic systems which evolved to trade speed for power by storing mechanical, electrical, or chemical potential energy over time.

Overshoot and damping is the same in reverse: dissipating kinetic energy when you, for example, bend your knees when you land from a jump (hopefully).

[1]: https://www.youtube.com/watch?v=qN3apht8zRs&t

nilamo 1 day ago
Sure they do? When people do a standing jump, they first crouch lower to the ground. An arrow is pulled back on the bow before fired. A ball pushed uphill will roll uphill before stopping and rolling downhill.
fidotron 1 day ago
Those are distinct actions though.

"Anticipation" in character animations is a source of persistent friction between game programmers and animators because if incorporated as part of user/player action it simply kills responsiveness. OTOH being able to see NPCs prepare to do something (like pulling the bow) is incredibly useful.

pc86 1 day ago
Eh, sort of. You do that if you're working out, because you're trying to maximize performance.

Most living beings aren't trying maximize performance, they're trying to maximize survival. That crouch gives away that you're about to jump, and it allows prey to avoid you more easily or predators to adjust their attack to counter for it. A rabbit trying to get away from a predator simply bounds away in its given direction without giving away what its doing.

nilamo 1 day ago
My experience seeing animals is apparently different from yours. The anticipation/tell is very clear for a wide range of animals... Birds squat down before taking off, cats hunker down to the ground before pouncing, etc.

Even the human jumping example again... Suggesting people only bend their knees for performance would mean the "normal" way of jumping involves keeping your legs straight at all times and using your ankles/toes for all your thrust?

panic 1 day ago
The correct way to do "anticipation" is to apply it as something is being pressed, then finish the animation on release. Putting both together in a single easing function is missing the point, IMO.
SimplyUnknown 1 day ago
I have the feeling that B-splines would be a good solution for this problem. Given that they have a continuous zeroth (i.e., the function is continuous), first, and second derivative, the motion will always be smooth and there will be no kinks. However, maybe it's moving the problem because now you must tune the coefficients of the B-spline instead of damping parameters (even though a direct mapping between these must exist but this mapping may not be trivial).
jcalx 1 day ago
Apple's easing function (like others) is parameterized by physical characteristics (e.g. spring force, damping) that are easier to model from first principles, but there are other parameters (overshoot distance, anticipation size, animation time) that are more useful for animation. A closed-form parametrization with the latter might be tricky to derive, but some kind of iterative solver (plug in desired animation parameters, get values for the physical parameters) shouldn't be too difficult?
1 day ago
1 day ago
sixthDot 1 day ago
Basically any transfert function that is used as interpolator can also be used as "easing". E.g a quadratic Bézier (let's say with empirically determined coeffs). One lesser known I used to like much is the super ellipse, although very costly.
aappleby 1 day ago
I've used the same easing function in my personal projects for decades now - move the variable 90% of the way to the goal every 80 milliseconds.
Koffiepoeder 1 day ago
Reminds me of Zeno's paradox. Do you have a terminating condition? Or just a fixed number of iterations?
bsimpson 1 day ago
> maybe I can start by just writing up my rant, and maybe someone else will read this and find a Research Project in here and will make the time before me

This is one of the things I find fascinating about Bret Victor. In the early 10s, he was giving a lot of really influential talks on creative coding. Someone asked him what his motivation was. He essentially said that he gives his ideas away, because he wants to live in a world where they exist. It's easy enough to build enough of a demo to give a talk, but he wanted someone else to do the legwork to grow it into a full project.

shermantanktop 1 day ago
That runs counter to conventional wisdom about patents: very few ideas are worth protecting, because they have zero value until they have been built into something of value in the real world.

And most builders are most passionate about their own ideas. An idea “gifted” from someone else may actually have negative value.

sfink 17 hours ago
I think it's not about the original idea, it's when you want to build (or live) on top of that idea. Patents hinder building on them. Disclosing an idea can either squelch interest in it or ignite inspiration based on it, depending on the presentation and the recipient. I agree that builders are most passionate about their own ideas, but that's still the case if their idea is an application or extension of someone else's idea.

I agree that just taking an idea and implementing it as-is isn't very inspiring. Or at least, not until you actually do it -- since in the process, you'll invariably discover that the idea is incomplete or needs adaptation for your specific situation, and it turns out you have to come up with your own ideas for it to be a "true" manifestation of the original idea.

MITSardine 1 day ago
Interesting article. But why is it an issue for it to be iterative?

I would imagine you're going to step through time anyways, to draw frame after frame. Wouldn't it in fact be cheaper to step through using some finite differences scheme, with one FD step for one draw step? It could be as cheap as a handful of additions per time step. Unless I'm overlooking something?

If needed for stability or accuracy, you can also step through several FD steps in one frame, but I'd imagine at a rate of 20fps, this should not be necessary for the types of equations considered.

pahgawk 1 day ago
Hi, author here! Two things come to mind:

- Part of my use case is that I build animation software. In there, you've got a timeline, and you can seek anywhere on the timeline. So in that scenario, you're not always moving consistently forward in time.

- In real-time contexts, sometimes you drop frames, even for simple motion, just due to the hardware it's being run on and what else the computer is doing. Simulations can be sensitive to time steps and produce slightly different results depending on them. The size of the issue depends on a lot of factors, but you don't have that issue at all with a closed form solution.

MITSardine 1 day ago
I see!

For your second point, you can decouple ODE time stepping and frame time stepping. I think it suffice to step until the lowest time ODE time step that is greater than the current frame time and interpolate between that and the previous ODE time step.

This technique is used in loosely coupled systems, for instance in mechanics where a rigid body needs a much lower time step (higher frequencies) than a soft body to compute the dynamics of, but you still need common time steps to compute interactions. Often times, the time steps are dictated by CFL conditions, and they may not even be integer multiples of each other.

However your first point is where I see the iterative approach really wouldn't work. Especially if the user might change the parameters before you've done anything with them, it wouldn't make sense to precompute values using the iterative scheme. Otherwise, that could be done, and then values interpolated between steps.

If you have few parameters, one solution that comes to mind if you cannot find a closed form solution is to grid the params space, and precompute the curve at each point of the grid. Then, when the user requests any value, simply localize that in the grid and interpolate from the nodes of the element. It becomes problematic if start and end points are parameters, though... In that case I suppose a linear transform of the curve to fit the end points precisely would be in order. You can consider the end points alone, it wouldn't be very complicated.

An improvement would be an adaptive grid; each time a point is inserted in a hypercube, compute also at the projections of that point on the hypercube's facets (and then the projection of that onto the facets' facets, and so on...), and split it. Consider whether to insert based on an indicator that takes into account the solutions at the nodes of the initial hypercube (if they are too distinct, a split is in order). Maybe this is too much complication for something this simple, but anyways there would be solutions for using more difficult ODEs that don't have closed-form solutions. Note if a single family of ODEs is considered, then this can be done offline, or online but cached.

There are more sophisticated methods like PINNs of course, but I don't know if you'd gain anything in performance versus a bespoke scheme. In particular if the inference step is more expensive than localizing in a kd-tree and interpolating from a few points.

pgorczak 1 day ago
I guess the issue is having to store the intermediate state somewhere. It’s true for the PID example that numerical integration is easier to compute - if you look at the comment with the closed form solution, you need trigonometric and exponential functions to evaluate it. It’s kind of fascinating that the iterative method approximates the same thing with just addition and multiplication.
MITSardine 1 day ago
At the same time, the cos and exp are also computed using addition and multiplication. Unless the values are tabulated, I imagine you'd use a series expansion. Or an even more straightforward argument is computers only know how to do addition and multiplication...

In the case of the exponential, if you're willing to start from a known value (say 0, where exp(0) = 1) and need values until the last, then using the very definition of the exponential is even more straightforward... this is the only function s.t. f' = f and f(0) = 1. In other words, step through it! The most natural definition of the exponential is as an ODE to begin with.

Tangentially related, this is one of my favourite articles "Nineteen Dubious Ways to Compute the Exponential of a Matrix":

https://www.cs.jhu.edu/~misha/ReadingSeminar/Papers/Moler03....

fidotron 1 day ago
Honestly, I think once you are tired of easing functions you are best off going to real physics. (By which I mean a simple Verlet integrator).

I've posted this before for other reasons but https://www.luduxia.com/showdown/ - in this case everything is easing functions, except for, bizarrely, the giant text that announces win/draw and the text inside the counter, which is done with actual physics because that proves better, especially with constantly moving targets.

ndyg 8 days ago
The friction Dave describes where changing one param effects all the other params in an animation brought to mind this section of an old Bret Victor talk: https://www.youtube.com/watch?v=a-OyoVcbwWE&t=716s
Trung0246 8 days ago
There was an old experiment of mine where I tried to mix match easing function, maybe it'll be of interest to you

https://codepen.io/Trung0246/pen/jxvvzY

ajkjk 1 day ago
imo there just need to be a few more default easing functions, the standard ones aren't quite natural enough. There must be a standard curve equivalent to the "human pushing/pulling an object from A->B" function that would actually look natural. EaseIn/EaseOut/etc is never quite it; human motion has a bit of higher-order feedback used to regulate it. Maybe to do with the combination of: all the motion happens via muscular springs, plus, there's a well-trained system that regulates the motion to minimize inefficient use of energy. Whether I jerk suddenly and then stop it, or move it slowly so it smoothly decelerates to the final point, it never looks as mechanical as the stuff you see in code.
eviks 1 day ago
And the parameters should be tied to reality as well like object weight, surface tension, hand strength, ...?
ajkjk 1 day ago
If you want? I don't care about the parameters, I just think the default functions should include some more sensible options that look less mechanical.
1 day ago
Obscurity4340 1 day ago
Can anyone comment on easing functions vs constant on a longer period of time, would they be distinictive or seem the same on a long and smooth enough slope
sfink 17 hours ago
Distinctive. Easing functions usually force the beginning and end to be noticeably different, and throughout the middle portion they're basically identical to constant velocity. The discontinuity at the start and stop are what easing functions are most concerned with.

In the limit, constant velocity still has the same discontinuity (infinite acceleration) at those points, and easing functions generally stick with the same constant-ish acceleration at those points. Easing makes it feel like the object has to get up to speed, and it takes about the same amount of time regardless of distance/overall time.

Liftyee 1 day ago
As an engineer I'm attracted towards the PID based one, but also wary of the amount of CPU cycles used just for a little animation. It seems like overkill, for some reason.
MITSardine 1 day ago
I don't imagine stepping through the ODE with finite differences at the same time step as drawing should be very expensive, essentially it's a handful of sums and products. In fact, using a closed form solution with an exponential is probably more expensive.
EsportToys 1 day ago
A middleground is to use fixed timesteps with the closed form solution. Then the integration factors can be statically precomputed as constants, and every frame becomes just a 2x2 matrix multiplication.

And even if you are to calculate the integration factors based on dynamic frame rates, they only need to be computed just once per frame for all objects that share the same damping configuration.

pahgawk 1 day ago
You're right, it's not that expensive! The main limiting factor for me is that not all animations play monotonically forward in time. I'm also interested in using these in animation software where you have a timeline and can seek anywhere. So a closed form is helpful in handling that case too.
istjohn 1 day ago
I'd like to see a toggle switch easing function. Slow down as you approach 40%, then snap to 100%.
Bluestein 1 day ago
> I'm unsatisfied with easing functions

Er ... "un ... eased"? :)

f33d5173 1 day ago
To me this article is ridiculous bcause the first thing I think of when I hear "easing function" is the css version of that concept, which seems to solve all the authors problems? The css easing functions are weirdly limited, because they consist of a single function that takes 4 parameters, then a bunch of specializations of that function. There are great websites on the internet for configuring those parametere though, and they are quite general from a practical standpoint. It should be trivial to emulate the concept in any other language/system.
jakelazaroff 1 day ago
By "CSS version" I'm assuming you mean cubic-bezier [1], which definitely does not solve all the author's problems. For example, you cannot use it to create their third example (easeOutElastic), nor many of Apple's kinematic easing functions or the feedback control.

[1] https://developer.mozilla.org/en-US/docs/Web/CSS/easing-func...

f33d5173 1 day ago
Yes, you can't use it to create those other functions, but you can use it to fulfill the authors purported goal in using those other functions. It also solves the deficiencies the author highlights in those other approaches. You could of course point to deficiencies in it and seek to resolve those deficiencies, but that wasn't how the article was structured.
jakelazaroff 1 day ago
I'm not sure why you think that? The author defines "easing functions" like this (which describes CSS's `cubic-bezier`):

> An easing function takes in a linear progress value, and returns a new progress value, but converted to nonlinear motion.

They then describe the problem with them in the section "Easing is not so easy", after introducing easing functions that are already more expressive than `cubic-bezier`:

> In traditional animation, the principles are just guidelines; you still end up creating new unique motion each time based on what acting the scene calls for. Easing functions in code don't quite give you the flexibility to do that.

shermantanktop 1 day ago
I read the article as an unreasonably deep dive into something that few people care about as much as the author. I certainly don’t, but that’s what makes it good. That’s perfect for HN.
sfink 17 hours ago
Not disagreeing, but you might be surprised at how widespread the interest in easing is. In my experience, easing is a major topic of debate whenever people are discussing the look and feel of animations.

Often people just argue over the proper parameters for the same old functions, but that's all they have available. Their arguments use lots of ambiguous human terminology like snappiness, surprise, anticipation, sluggishness, etc. that don't cleanly map to specific parameters.

Adjusting easing can produce dramatically different results in how we feel about something. It triggers our hindbrain. We want to pounce on the mouse, or block the incoming rock, or whatever, I guess? Try going in for a handshake a little faster or slower than usual and see what happens...

mattkrause 1 day ago
My only real beef with the article is that "Uneasy about easing functions" would have been a much better title.
Bluestein 1 day ago
Oh, you beat me to it, I see :)

Kudos.-

mattkrause 1 day ago
Great minds, etc!
Bluestein 1 day ago
Totally :)

PS. And, if I may as a recovering Flash 5/Actionscript victim ...

... this (great) article brought back memories.-

pahgawk 1 day ago
Author here -- kicking myself because this is way better lmao
ziml77 1 day ago
You should edit the title. I'm sure there's plenty of people who will find this post later on and be tickled by that :)
mattkrause 1 day ago
Take it--it's all yours :-)
f33d5173 1 day ago
It didn't seem unreasonably deep at all. It was long, sure, but it seemed to only scratch the surface of the topics it was discussing. That was sort of my point in bringing up the css function - it is itself incredibly bare-bones, but just describing it's usage would have covered more ground imo.
shermantanktop 1 day ago
"Unreasonably deep" is a relative term. Certainly deeper than I care to go. But sure, it could be unreasonably deeper.

Every time I have used animation my approach has been to treat it as frosting to be used sparingly. As such I would be much more attracted to simple/supported modes (that someone else will be interested in keeping functional) than I would be to obsessing over physics realism. But I am also a UI caveman with no taste, so there's that.

ajkjk 1 day ago
how would any of that make the article ridiculous?
f33d5173 1 day ago
It circles around the point without ever reaching it. Each section seemed like it was missing the obvious. "To me" meaning that was my personal impression.