Ever wonder why regular pencil tools wait until after you finish drawing to smooth out your line? It's usually because the app using a line-simplification algorithm—and these sorts of algorithms aren't "stable" as a line is changing. 🧵
Here's the algorithm at work, picking new points on almost every frame. Each solution is "correct" for each set of points, but it is overall "incorrect" in the sense that the solutions keep changing! codesandbox.io/s/simplified-t…
Why simplify at all? The "raw" input points are often very jerky and noisy.
But it's still a lot of data, especially if you're expecting to edit the points after the fact. So why not just wait until the end to simplify. codesandbox.io/s/agitated-knu…
If you're in a design tool, then waiting until the end is probably fine—but it's not a great experience for drawing or writing. So one of the big challenges in perfect-freehand was coming up with a "stable" way to simplify lines.
You can see it at work on the corners of this curve—first with the smoothing at minimum, and then with it turned up. codesandbox.io/s/freehand-y1i…
This is still something I'm working on, too. If you have any ideas, let me know. Or dive into the code! github.com/steveruizok/pe…
The regular @croquet/react bindings have a lot of boilerplate that's available from their context object (e.g. a viewId) so these bindings folds that stuff in.
It’s still a lot of boilerplate though. Most of the “subscriptions” I’m writing are manually syncing these two data sources (the data published from the model and the React state).
tricker than I thought: making sure that pasted shapes don't end up on top of each other
Normally we'd like to place a pasted shape in the middle of the editor. You can think of this as an offset of [0,0] from the center.
But there are two circumstances where we'd want to offset this position. First, if the shapes that we copied happen to also be perfectly centered in the window, then we'd increase our offset (e.g. to [16, 16]).
Introducing rko, a three-letter state management library for #reactjs with built-in undo, redo, and local persistence. Built on @pmndrs zustand. github.com/steveruizok/rko.
The idea here is to update state either with a "patch", or a deep partial of the state containing only the changes that you want to make...
...or else a "command" made up of two patches, before and after. Only commands become part of the undo/redo stack.
Live cursors are interesting. You don't really want to be constantly sending updates but you do want the cursors to move smoothly and naturally like this. What's the trick?
Here's what it looks like without any animations.
Regular tweens/duration-based animations won't work here because each new update will "redirect" the animation. While the cursor is moving from A to B, a new update may come in that means it should move instead from its current point (C) to point D instead.
perf breakthru on ios, panning and zooming back to 60 FPS
I was over here staring at the performance tab, all signs green, no dropped frames reported—while also watching things obviously skip around at <30 fps. Super frustrating, couldn't figure it out.
Finally I think, maybe I'm not actually updating the state on every frame? Of course I was, but somehow in a way that didn't quite count for Safari.