Message Boards Message Boards

How to work with "MouseDragged"

Posted 2 years ago

I want to build a user interface similar to that of GeoGebra, and create a Graphics expression in WL that does what is seen in the gif file:

enter image description here

The goal is very simple: I want to let the user to drag the point on the canvas. I will later add some computations to this point.

I think that the function I need to use is EventHandler. I got stuck, as I don't know what to specify as an action to be paired to "MouseDragged" in the following attempt:

DynamicModule[
 p = {0, 0},
 EventHandler[
  Framed@Dynamic[Graphics[Point[p], PlotRange -> 2]],
  "MouseDragged" :> 
   "What needs to be here?"]
 ]

I have not seen any examples in the documentation about the "MouseDragged" event.

  • I prefer not to use LocatorPane since it obliges me to add a background to the graphics, which is not necessary in my case.
POSTED BY: Ehud Behar
9 Replies

How can we export this example, or another similar one, with Export, in a gif file to look like it on my Moodle page?

Here is a bit of code to make a simple drawing palette,

DynamicModule[
  {
    endpt = {}, (*I like dynamic arrays for efficiently growing a list*)
    newline = CreateDataStructure @ "DynamicArray",
    otherlines = CreateDataStructure @ "DynamicArray"
  },
  EventHandler[
    Dynamic[
      Graphics[
        {
           PointSize[Large], Point[endpt], Line[Normal[newline]], 
           Line[Normal[otherlines]] (*Normal converts the dynamic array to a regular list*)
        },
        PlotRange -> 2
      ]
    ],
    {
      "MouseDown" :> (otherlines["Append", Normal[newline]];
      newline @ "DropAll"),
      "MouseDragged" :> newline["Append", endpt = MousePosition["Graphics"]],
      "MouseUp" :> (endpt = {})
    }
  ]
]

enter image description here

POSTED BY: Jason Biggs
Posted 2 years ago

Jason, there is a syntax problem with the code you posted. A lonely, unmatched, curly brace.

enter image description here

POSTED BY: Hans Milton

Thanks! Fixed now.

POSTED BY: Jason Biggs
Posted 2 years ago

The red frame that appears when you click can be annoying. That frame does not appear with the event MouseDown. So one can combine it with MouseDragged to get rid of the frame.

DynamicModule[
 {p = {0, 0}},
 EventHandler[
  Framed@Dynamic[Graphics[{PointSize@Large, Point[p]}, PlotRange -> 2]],
  {
   "MouseDown" :> (p = MousePosition["Graphics"]),
   "MouseDragged" :> (p = MousePosition["Graphics"])
  }
 ]
]
POSTED BY: Hans Milton
Posted 2 years ago

Thanks a lot Hans Milton! This definitely helps me. What if I have some other object on the Graphics canvas? Below you can see that I added another point, p2, that may also be clicked and dragged to change its position.

The thing is that each mouse-click moves both of them!

enter image description here

In GeoGebra the user can move the point only after the mouse pointer is in its vicinity.

Do you have any idea how to make a similar thing in WL?

POSTED BY: Ehud Behar
Posted 2 years ago

Ehud, this is what I can come up with. Nested EventHandlers.

DynamicModule[
 {pR = {0, 0}, pB = {0.5, 0.5}, sel = False},
 EventHandler[
  EventHandler[
    Framed@Dynamic@Graphics[
     {PointSize@Large, Red, Point[pR], Blue, Point[pB]}, PlotRange -> 2
    ],
    "MouseDown" :> (sel = EuclideanDistance[MousePosition["Graphics"], pR] >EuclideanDistance[MousePosition["Graphics"], pB])
  ],
  "MouseDragged" :> If[sel, pB = MousePosition["Graphics"], pR = MousePosition["Graphics"]]
 ]
]

Edit:

On more testing I see that the nesting is not needed. A single EventHandler also works:

DynamicModule[
 {pR = {0, 0}, pB = {0.5, 0.5}, sel = False},
 EventHandler[
  Framed@Dynamic@Graphics[
    {PointSize@Large, Red, Point[pR], Blue, Point[pB]}, PlotRange -> 2
  ],
  {
   "MouseDown" :> (sel = EuclideanDistance[MousePosition["Graphics"], pR] > EuclideanDistance[MousePosition["Graphics"], pB]),
   "MouseDragged" :> If[sel, pB = MousePosition["Graphics"], pR = MousePosition["Graphics"]]
  }
]]
POSTED BY: Hans Milton

If you wish to move multiple points around, look at Locator and LocatorPane

POSTED BY: Jason Biggs
Posted 2 years ago
DynamicModule[
 {p = {0, 0}},
 EventHandler[
  Framed@Dynamic[Graphics[{PointSize@Large, Point[p]}, PlotRange -> 2]],
  "MouseDragged" :> (p = MousePosition["Graphics"])
 ]
]
POSTED BY: Hans Milton
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract