Quick refresher on how arrows are *supposed to* work.
When we have an arrow between shapes, that arrow has a start and end point (actual location is based on a normalized "anchor" from when the arrow was last modified, long story)
We fire a ray from the start point through end point.
We expect to have have one intersection from the start shape, and two intersections in the end shape. We pick the intersection closer to the start point.
If the arrow has a decoration (ie an arrowhead) then we move the point back toward the other point by some distance.
Now we can draw our arrow.
Hooray!
To my great shame and frustration, this routine only works if certain conditions are met. Did you catch them?
For example, what if the shapes are overlapping?
Then you get this one.
Doesn't look very good, in part because the arrow is no longer pointing "towards" its anchor, but through it.
The fix for this is to force an arrow of a known distance that points toward the anchor point.
This also works if the shape is overlapping the target point, though not as well.
There's some more to deciding when to change strategies (arrow too short? contain or collide?) but that's the main approach.
Working on a new Undo / Redo manager that runs on mobx and JSON patches. Here's how it works! 🧵
First off, here's a CodeSandbox. Looks pretty simple but there's a lot going on. I've included my tests! codesandbox.io/s/mobx-undo-re…
In our system, we're tracking changes to a "document". Each time the document changes, we generate a "snapshot" and compare it with our previous snapshot in order to create a "patch" that describes how to get from the current snapshot back to the previous.
Implemented click detection all the way up to quadruple clicks. 🤯
It sort of works like this: each time the user clicks, we fire three events—we fire onPointerDown when they start clicking, then onPointerUp _and_ onClick when the they stop clicking.
We also keep track of a clicking state.
This starts in "idle" and can be either "idle", "pendingDoubleClick", "pendingTripleClick", "pendingQuadrupleClick", or "overflow".
What do I mean by smarter? Let's say each of our blocks has a position in a grid, [x, y]. (It's actually a 3D grid, so [x, y, z], but we can ignore the z for now)
The positions map to the block's index in z/y/x arrays. This means that a block's position can only be an integer like 1 or 2, but never a float like 1.25 or 2.81.
So a position like [0, 0] is fine but [0.5, 0] is not.
I'm currently experiencing a "where do I put whitespace in my code" crisis.
I've usually placed empty lines between pretty much everything except maybe variable definitions, but this makes different methods hard to spot and sometimes makes methods themselves harder to read?
But saving empty lines for just separating methods / class fields can lead to some very dense code.