I have a canvas with draggable objects. I would like to implement a snap-to-grid feature but I am a bit lost about how to implement. I’ve looked at examples in the Xojo distribution and have not found anything useful.
I’m not sure I understand what you’re asking. It sounds like it should be as simple as adjusting the X,Y values in DropObject. What have you tried, what did you expect, and what did you actually get?
Have not tried anything yet. These are not necessarily dropped objects, though they could be. They are general graphic objects. The user can drag them around, like the supplied examples. But, I want them to snap to a grid that some NxN pixels, where N>1.
I am guessing that I need to get the current position in pixels, divide that by the grid size, rounding up or down to get the closest, and when the mouse button is released, shift the top,left to the nearest grid location.
This seems like a common requirement for dragged graphic objects (like electrical schematic diagrams) and I was hoping that someone already had something worked out.
That sounds tidier doing it in the mousedrag so the object remains where the user has dragged it to after the mouse up rather than releasing the mouse and then the object jump to the snapped location
The problem with this is… the user has to pull the object away from the last snap… which might be impossible sometimes
Take for example you have a Snap to Grid of 10 pixels… You have to be able to move the object 11 pixels before you can snap to the next grid. But if the object is snapping everytime you move… you go no where fast. What you need to do is track TWO sets of coordinates… the MOUSE and the OBJECT… and compare the two
Dave, you lost me. You’re already using the mouse coordinates to calculate the position of the object. As long as you’re not repositioning the mouse, there’s no problem. If there’s 10 pixels between snap points, as soon as you move 6 pixels, it snaps to the next one.
Tim… you need to track where the mouse IS, and where the object IS, other wise how do you know you moved 6 pixels?
the 6 pixels is the DELTA in MOUSE Movement… NOT the delta in OBJECT movement
You have TWO things… the moving mouse and the moving object
xx=floor(mouse_x/10)
if xx<>object_x then object_x=xx
simplified… as you would also need to track if you updated object_x so to only invalidate the canvas when the object actually moved
I wrote a snapToGrid recently, it works but not perfect. see a video here.
First you have to paint the grids (i have on paint event) some like:
Dim GridStep As Integer= GridValue ' example: 100px
Dim GridStepSum As Integer= 0
While GridStepSum< g.Width
g.DrawLine GridStepSum, 0, GridStepSum, g.Height ' vertical
GridStepSum= GridStepSum+ GridStep
Wend
Then when move the object, raise an event to handle. You have to check if is “near” of the grid:
Const tresshold= 5 ' 5 pixels near
Dim GridStep, GridStepSum, rangeL, rangeH As Integer
GridStep= GridValue ' example: 100px
GridStepSum= 0
While GridStepSum< Canvas1.Width
rangeL= elementMoving.Left- tresshold
rangeH= elementMoving.Left+ tresshold
If GridStepSum>= rangeL And GridStepSum<= rangeH Then
elementMoving.Left= GridStepSum ' here change the position
elementMoving.Refresh
' here you need to reinit elementMoving mousedrag... i don't know how... :(
Exit
End
GridStepSum= GridStepSum+ GridStep
Wend