Closed fnky closed 2 years ago
@fnky is attempting to deploy a commit to the tldraw Team on Vercel.
A member of the Team first needs to authorize it.
This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployments, click below or on the icon next to each commit.
🔍 Inspect: https://vercel.com/tldraw/core/7BqaFHtAeBzi6u5LdwPnvgfJshZ4
✅ Preview: https://core-git-fork-fnky-feature-grids-tldraw.vercel.app
🔍 Inspect: https://vercel.com/tldraw/tldraw/3pP5eLFsJVj1ucWiJii1CUMVJAX1
✅ Preview: https://tldraw-git-fork-fnky-feature-grids-tldraw.vercel.app
Looking very good 👌 May be snap to Grid next :)
This is awesome!
Some initial thoughts:
Excellent use of the <pattern
element.
Do we need to make the renderer support an unlimited number of grids? I can't think of many apps where a "major" and "minor" grid wouldn't be sufficient. This could simplify the props (gridMajor: number
and gridMinor: number
) and avoid needing to memoize the arrays outside of the Renderer. We already have a theme
object, so we could add gridMajor
and gridMinor
there as well.
This feature doesn't implement grid snapping for transforms and translations of layers, though that would be a great feature to add.
I think this would make sense as something to work out as part of this PR, just because it could shape the way we implement the grid in the core library, too.
Throughout the app's dragging interactions, we use "delta"s to decide where the dragged shapes should go. A delta is the vector between the place in the document where the user started pointing, or the originPoint
, and the place where their pointer is now, or the currentPoint
.
Features like snapping or "axis" dragging are easily implemented by adjusting this delta.
let delta = Vec.sub(currentPoint, originPoint)
if (shiftKey) {
if (Math.abs(delta[0]) < Math.abs(delta[1])) {
delta[0] = 0
} else {
delta[1] = 0
}
}
In this case, I we would need to make sure that the result after the delta is a point on the grid, so we would round both the originPoint
and the currentPoint
to be on the grid.
let delta = app.appState.grid
? Vec.sub(TLDR.roundToGrid(currentPoint), TLDR.roundToGrid(originPoint))
: Vec.sub(currentPoint, originPoint)
I'll dig into the code to check for any problems but on first look I feel really positive about this getting into the core lib.
@steveruizok Thanks!
Initially I had a "grid" and "subgrid" and changed it to take more grids similar to Figma. But I agree that we could simplify this by just having two. I like your "major" and "minor" terminology here.
As for snapping, I agree it makes sense to implement it as part of this PR. Your insight helps a lot here, as I was a bit lost in where to put this.
As for the UX, there are different approaches to this. There are at least three approaches I can think of on top of my head:
Had a look into implementing the grid snap and found that using the center point of the shape wouldn't be enough to snap it to the grid lines.
I believe this could be solved by using the edges of the shape, such we can snap by the top (in Y coordinate) and left (in X coordinate) edges when translating, and snap the grabbed edge when resizing/transforming the shape.
I'll dig more into the code to get a better understanding of how this could be done.
Hey, doing some more work on this and looking at different ways to present grids that scale with the zoom level.
A couple of changes:
gridStroke
theme color@steveruizok Looks really neat, really nice improvement!
I haven't had time to work much on grid snapping yet, but hopefully will be able to look into it in the weekend. If someone else finds time to take a stab at it, don't hesitate :)
Blocked at the moment by svg pattern fill not working on iOS. Not sure what the fix there is but would love to hear ideas!
Blocked at the moment by svg pattern fill not working on iOS. Not sure what the fix there is but would love to hear ideas!
Huh, that's odd. Seems like it needs the entire path and not just the fragment. Will this work?:
<rect fill={`url('${location.href}#grid-${i}')`} />
SVG issue solved! Ready for testing.
@steveruizok Awesome work! Appreciate your hard work on this. Love the dot grid; makes much more sense for tldraw.
Tried on iOS too and it works really well.
Can't thank you enough!
I'm going to implement snapping to grid for arrow handles before we merge.
Still not sure whether to have individual shapes snap to grid while resizing a selection. 🤔
This PR now also brings vec and intersect back into the monorepo, solves a bug with tiny arrows, and improves TypeScript imports throughout the monorepo.
Adds support for adding grids of various colors and sizes to the renderer.
It also implements the grid into the app, which can be toggled from the Preferences menu and with the shortcut Ctrl+G/Command+G.
A possible improvement would be to add/remove grids from UI.
API Changes
Adds an optional
grids
prop to theRenderer
andCanvas
components, which takes a list ofTLGrid
objects:This feature doesn't implement grid snapping for transforms and translations of layers, though that would be a great feature to add.