Snap To Grid?

Greetings -

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.

Suggestions? Hints?


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.


It should be pretty simple math.

X = Round(X/N) * N
Y = Round(Y/N) * N

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

Yes; agreed.

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

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

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

          ' here you need to reinit elementMoving mousedrag... i don't know how... :(

        GridStepSum= GridStepSum+ GridStep

I hope help you.

Thanks for the input, folks. I really do appreciate the insight you have offered.

Jim Wagner