Snap objects while dragging

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

croivo
Posts: 111
Joined: Wed Feb 26, 2014 11:02 pm

Snap objects while dragging

Post by croivo » Sun Feb 08, 2015 11:50 pm

When user is dragging the button, I want buttons to snap to the 2 graphic lines if the button is 30px far from that line.
Here is sketch:
Capture.PNG
Capture.PNG (4.55 KiB) Viewed 9199 times
I used this code

Code: Select all

put the mouseloc into mouseLocation
   if (item 1 of mouseLocation < the left of graphic "vLine" + 40) and (item 1 of mouseLocation > the left of graphic "vLine" - 40) then
      put the width of me into myWidth
      divide myWidth by 2
      set the left of me to (the left of graphic "vLine" - myWidth)
   else if (item 2 of mouseLocation < the top of graphic "hLine" + 40) and (item 2 of mouseLocation > the top of graphic "hLine" - 40) then
      put the height of me into myHeight
      divide myHeight by 2
      set the top of me to (the top of graphic "hLine" - myHeight)
   else
   end if
However, that doesn't looks like best solution... It's all laggy :( Anybody has better idea?

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10332
Joined: Wed May 06, 2009 2:28 pm

Re: Snap objects while dragging

Post by dunbarx » Mon Feb 09, 2015 1:39 am

Hi.

I am just including a gadget I made for another purpose. I simplified and modified it into a compact example. It might help. Make a single line graphic, set at an angle near 45°, and a button named "test". In the button script:

Code: Select all

local x1,x2,y1,y2,xDff,yDiff,slope

on mouseMove
   if the mouse is down then 
      put the mouseLoc
      switch 
         case x1 > x2 
            if  the mouseH < x1 and the mouseH > x2  then set the loc of btn "test" to the mouseH & "," & (the mouseH - x1) * slope + y1
            break
         case x1 <x2
            if  the mouseH > x1 and the mouseH < x2  then set the loc of btn "test"  to the mouseH & "," & (the mouseH - x1) * slope + y1
            break
         case x1 = x2
            if  the mouseV > item 2 of the topleft of grc 1 and the mouseV < item 2 of the botRight  of grc 1
            then set the loc of btn "test"  to x1 & "," & the mouseV
            break
      end switch
   else 
      set the loc of btn "test" to the mouseLoc
   end if
end mouseMove

on mouseEnter
     put item 1 of line 1 of the points of grc 1 into x1
      put item 2 of line 1 of the points of grc 1 into y1
      put item 1 of line 2 of the points of grc 1 into x2
      put item 2 of line 2 of the points of grc 1 into y2
      
      put y2 - y1  into yDiff
      put x2 - x1  into xDiff
      if xDiff <> 0 then put yDiff / xDiff into slope
      pass mouseEnter
end mouseEnter
.

Not sure if this simply complicates your problem with the jitters. But it at least has the advantage of requiring the mouse to be down when it locks to the line. You currently have no escape in your code.

Craig Newman

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10332
Joined: Wed May 06, 2009 2:28 pm

Re: Snap objects while dragging

Post by dunbarx » Mon Feb 09, 2015 1:58 am

Aw, now I see what you wanted. Here is a handler for just the vertical graphic. You can surely extend to both:

Code: Select all

on mouseMove
   if the mouse is down and abs(item 1 of the loc of me - item 1 of the left of grc "vline") < 40 then
      set the loc of me to item 1 of the left of grc "vline" & "," & item 2 of the mouseLoc
   else
      set the loc of me to the mouseLoc
      end if
end mouseMove
Craig

croivo
Posts: 111
Joined: Wed Feb 26, 2014 11:02 pm

Re: Snap objects while dragging

Post by croivo » Mon Feb 09, 2015 11:54 am

Hm... tried your code, but still it's not working as it should... here is project: https://mega.co.nz/#!sUoXnB7Z!uJ_njOMxd ... Y-Ej6hIq58

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10332
Joined: Wed May 06, 2009 2:28 pm

Re: Snap objects while dragging

Post by dunbarx » Mon Feb 09, 2015 4:11 pm

Hi,

Could not open your stack. It was corrupted.

What is not working? The button will nominally track the cursor all over the card. And when the mouse is down, it will snap to the graphic if it gets close enough..

That graphic was a vertical line, right, as in your example? And it was named "vLine", correct? If you need to track a slanted line, you need more stuff, like my earlier example.

Craig

jiml
Posts: 339
Joined: Sat Dec 09, 2006 1:27 am

Re: Snap objects while dragging

Post by jiml » Mon Feb 09, 2015 8:20 pm

Is this what you want?

Code: Select all

on mousedown
   grab me
end mousedown

on mouseup
   if   abs(item 1 of the loc of me - the left of grc "vline") < 40 then
      set the loc of me to  the left of grc "vline", item 2 of the loc of me --the mouseLoc
   end if
   put (item 2 of the loc of me ,  the top of grc "hline") 
   if   abs(item 2 of the loc of me -   the top of grc "hline") < 40 then
      set the loc of me to  item 1 of the Loc of me, the top of grc "hline"
   end if
end mouseup

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10332
Joined: Wed May 06, 2009 2:28 pm

Re: Snap objects while dragging

Post by dunbarx » Mon Feb 09, 2015 8:32 pm

Jimi.

@jimi This does not track the graphic under cursor control, which is what I think croivo wanted.

@croivo. Any luck with my test gadget? If not, what is the error?

Craig

croivo
Posts: 111
Joined: Wed Feb 26, 2014 11:02 pm

Re: Snap objects while dragging

Post by croivo » Mon Feb 09, 2015 10:53 pm

jiml wrote:Is this what you want?

Code: Select all

on mousedown
   grab me
end mousedown

on mouseup
   if   abs(item 1 of the loc of me - the left of grc "vline") < 40 then
      set the loc of me to  the left of grc "vline", item 2 of the loc of me --the mouseLoc
   end if
   put (item 2 of the loc of me ,  the top of grc "hline") 
   if   abs(item 2 of the loc of me -   the top of grc "hline") < 40 then
      set the loc of me to  item 1 of the Loc of me, the top of grc "hline"
   end if
end mouseup
Hi jimi, that's about what I'm looking for. However, I want the button to snap WHILE user is dragging it around. When I change your "mouseup" handler to "mousemove", the button becomes very laggy when it's near the line...

Jimi.

@jimi This does not track the graphic under cursor control, which is what I think croivo wanted.

@croivo. Any luck with my test gadget? If not, what is the error?

Craig
The little problem here is that the button is dragging even when it's not clicked. So I changed 'else' statement to this:

Code: Select all

else if the mouse is down then
     grab me
end if
And than again, it becomes laggy...

Hm, looks like there is no ideal solution for this... Button will always be laggy if it's snapping to lines while dragging, so the only solution is to snap the button on "mouseUp" handler.

Thanks for helping me :)

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10332
Joined: Wed May 06, 2009 2:28 pm

Re: Snap objects while dragging

Post by dunbarx » Tue Feb 10, 2015 12:15 am

croivo.

I find no "dragginess". The action is smooth, responsive and stable. Something is wrong with either my understanding of the problem, or your testing.

When you drag with the mouse down, what do you see that button doing?

Craig

croivo
Posts: 111
Joined: Wed Feb 26, 2014 11:02 pm

Re: Snap objects while dragging

Post by croivo » Tue Feb 10, 2015 12:44 am

When I drag with the mouse down, the button is flashing and it's moving slowly...

Here is what I want: https://mega.co.nz/#!JYRixIRS!27gawdKQH ... SeK0u72OpQ

jiml
Posts: 339
Joined: Sat Dec 09, 2006 1:27 am

Re: Snap objects while dragging

Post by jiml » Tue Feb 10, 2015 1:35 am

Here's some code.
Caveats:
Once it is snapped there's no dragging it away from the line.
And at the intersection of the lines it jumps about.

Code: Select all

local lLastPosition, lSnapped

on mousedown
   put false into lSnapped
end mousedown

on mouseup
   beep
   put false into lSnapped
end mouseup

on mouseMove newh,newy
   if the mouse is not down then exit mouseMove
   if newh,newy <> lastPosition then
      if   abs(item 1 of the mouseloc - the left of grc "vline") < 40 then
         set the loc of me to  the left of grc "vline", item 2 of the mouseloc --the mouseLoc
         put true into lSnapped
      end if
      if   abs(item 2 of the mouseloc -   the top of grc "hline") < 40 then
         set the loc of me to  item 1 of the mouseloc , the top of grc "hline"      
         put true into lSnapped
      end if
      if lSnapped is true then 
         exit mouseMove
      else
         set the loc of me to newh,newy
      end if
      put newh,newy into lastPosition
      
   end if
end mouseMove

Simon
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 3901
Joined: Sat Mar 24, 2007 2:54 am

Re: Snap objects while dragging

Post by Simon » Tue Feb 10, 2015 1:57 am

I'm with Craig in that I don't see "lag" so I have to ask.
Is this on mobile?

Simon
I used to be a newbie but then I learned how to spell teh correctly and now I'm a noob!

croivo
Posts: 111
Joined: Wed Feb 26, 2014 11:02 pm

Re: Snap objects while dragging

Post by croivo » Tue Feb 10, 2015 1:18 pm

jiml wrote:Here's some code.
Caveats:
Once it is snapped there's no dragging it away from the line.
And at the intersection of the lines it jumps about.

Code: Select all

local lLastPosition, lSnapped

on mousedown
   put false into lSnapped
end mousedown

on mouseup
   beep
   put false into lSnapped
end mouseup

on mouseMove newh,newy
   if the mouse is not down then exit mouseMove
   if newh,newy <> lastPosition then
      if   abs(item 1 of the mouseloc - the left of grc "vline") < 40 then
         set the loc of me to  the left of grc "vline", item 2 of the mouseloc --the mouseLoc
         put true into lSnapped
      end if
      if   abs(item 2 of the mouseloc -   the top of grc "hline") < 40 then
         set the loc of me to  item 1 of the mouseloc , the top of grc "hline"      
         put true into lSnapped
      end if
      if lSnapped is true then 
         exit mouseMove
      else
         set the loc of me to newh,newy
      end if
      put newh,newy into lastPosition
      
   end if
end mouseMove
That's now closer to what I'm looking for, but I still want user to be able to drag button away when it's snapped to line... Like in Photoshop (if you've worked in it), you can enable to snap objects while dragging...

@Simon It's on Windows 8... Here is new rec https://mega.co.nz/#!RVYgBZqS!tq40xj5SJ ... RxxJSECAK0

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10332
Joined: Wed May 06, 2009 2:28 pm

Re: Snap objects while dragging

Post by dunbarx » Tue Feb 10, 2015 3:08 pm

OK.

Try this. Still two intersecting line graphics, one named "hLine" and one named "vLine", and a button with this in its script:

Code: Select all

on mouseMove
   switch
      case the mouse is up
         set the loc of me to the mouseLoc
         break
      case the mouse is down and abs(item 1 of the mouseLoc - the left of grc "vline") < 10
         set the loc of me to the left of grc "vline" & "," & item 2 of the mouseLoc
         break
      case  the mouse is down and  abs(item 2 of the mouseLoc - the top of grc "hline") < 10
         set the loc of me to  item 1 of the mouseLoc & "," & the top of grc "hline"
         break
   end switch
end mouseMove
You must move the mouse slowly, but that is another problem. Also, the mouse cannot be held down if the button is too far from either line. But that is another problem.

Craig

dunbarx
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 10332
Joined: Wed May 06, 2009 2:28 pm

Re: Snap objects while dragging

Post by dunbarx » Tue Feb 10, 2015 3:52 pm

A little better...

Code: Select all

on mouseMove
   switch
      case abs(item 1 of the mouseLoc - the left of grc "vline") < 10
         set the loc of me to the left of grc "vline" & "," & item 2 of the mouseLoc
         break
      case  abs(item 2 of the mouseLoc - the top of grc "hline") < 10
         set the loc of me to  item 1 of the mouseLoc & "," & the top of grc "hline"
         break
      case abs(item 1 of the mouseLoc - the left of grc "vline") > 10 or abs(item 2 of the mouseLoc - the top of grc "hline") > 10
         set the loc of me to the mouseLoc
         break
   end switch
end mouseMove
Why do you suppose there is a little hitch when moving left/right on the hLine, but not when moving up/down on the vLine?

Craig

Post Reply