Here is the sequence of mouse events involved in dragging something:
1) m1.press is True when you depress the mouse button (it is
'left' if left button; nonzero is True in Python).
2) m1.drag is True when the mouse coordinates change from what they were at
the time of m1.press.
At the time of the drag event, the mouse position is reported to be what it
was at the time of the press event, so that the dragging can start at the place
where the user first clicked. If the mouse is in motion at the time of the press
event, it is quite possible that the next position seen by the computer, at
the time of the drag event, could be quite far from the click position. This
is why the position of the drag event is reported as though it occurred at the
press location.
3) No events occur while dragging; you continually use scene.mouse.pos to update
what you're dragging.
4) m1.drop is True when you release the mouse button.
You can program dragging with the mouse simply by continually
reading the current value of scene.mouse.pos.
Here is a complete routine for dragging a sphere with the left button down.
Note the statements for making the cursor invisible during the drag.
if new_pos
!= drag_pos: # if the mouse has moved since last position
pick.pos
+= new_pos - drag_pos # offset for where the ball was clicked
drag_pos
= new_pos # update drag position
If you do a lot of processing of each mouse movement, or you
are leaving a trail behind the moving object, you may need to check whether
the "new" mouse position is in fact different from the previous position
before processing the "move", as is done in the example above. For
example, a trail drawn with a curve object that contains a huge number of points
all at the same location may not display properly.
Only some of the VPython objects can be "picked" by
clicking them, including sphere, box, and cylinder. Here is a more general routine
which lets you drag either the tail or the tip of an arrow: