Recently I mentioned the characteristics a Discord alternative should have (much like the posts I boosted today). I also mentioned federation is probably detrimental, but I wasn't able to verbalize it well, so here's my next attempt.
People want the convenience of a single account which gives them access to not just a single community, but many. And they're all browseable in the app itself. I said this and the other factors are only viable if there's a single huge provider running it, which means any alternative would essentially have to be Discord 2.0.
Why would federation be detrimental? Because federation means you're starting to deal with multiple independent nodes which communicate with each other. This distributes control, but it also means that you go from "I register at chat.app and talk with my friends" to "I need to find an instance to use chat.app to talk with my friends". This in itself is a downgrade to the experience as far as average users are concerned.
But on top of that, the way federation is implemented may add more hurdles. If it's anything like the fediverse, the experience becomes way worse because then choosing an instance is a significant choice where your ability to talk with friends differs a lot due to instance politics. Politics that new users would have absolutely zero knowledge of. And that fucking sucks.
There are better solutions for federation, but none can change the fact that "I register at chat.app and talk with my friends" becomes "I need to look for an instance first". I said in the past that people resist any improvement if it leads to even the tiniest decrease of convenience, which is reflected in my experience with Discord communities where forum channels and threads are mostly unused features, and if people do use a forum channel, they use it like more chat rooms.
It actually didn't add that much code.
I added a function to record the current velocity since the last frame. It loops with requestAnimationFrame and stores the coordinates in a variable so the next call can compare current and previous coordinates.
The velocity itself is computed as moving average. The window size is dynamic: 2 if the velocity is higher than the recorded one, and 15 if it's lower. The higher the window size, the less the impact of a new value on the average. This is necessary because when you're about to lift your finger, you typically slow down and this would've caused the final velocity to be lower than expected.
The inertia is also implemented with a function which calls itself in a requestAnimationFrame loop. I simply multiply the velocity variables by 0.95 and then add the velocity to the image coordinates.