Things to try with a mouse:
- Drag outside the diagram, and come back {should still be dragging}
- Drag outside the diagram, and let go of the mouse button, then come back into the diagram {should stop dragging}
- Drag outside the window, then let go of the mouse button {should stop dragging}
- Right click on the circle {should not drag, but bring up the context menu}
- Right button drag the circle {should not drag, but bring up the context menu on Mac or Linux, or do nothing on Windows}
- Drag with the middle button {should not drag, but enable autoscroll}
- Drag with the left button, then hold down right button, continue drag, then release left button, then move mouse, then release right button {should stop dragging when releasing left button; I want a different behavior from this test[1]}
- Chords¹: drag with the left button, then hold down Ctrl, then release the left button {Mac/Firefox behaves differently, giving
pointerdown.left
and thenpointerup.right
whereas other browsers givepointerdown.left
andpointerup.left
} - While dragging, Alt+Tab (Cmd+Tab) to switch windows, then let go of the mouse button {should stop dragging}
- While dragging, use keyboard to scroll {should still be dragging²}
- While dragging, use scrollwheel to scroll {should still be dragging²}
- While dragging, use middle button to scroll {should still be dragging²}
- While dragging, resize the window {should still be dragging²}
- Select all text on page, then drag the circle {should drag the circle, not the text}
- Plug in two mice, start dragging on one, click on the other {want this to continue dragging, but it won’t³}
- On Mac, use an iPad as a second screen, drag with stylus on a mac browser {should drag}
- While dragging, put the computer to sleep and then wake it up and continue the drag {??}
- While dragging, unplug the mouse and plug it back in {??}
Things to try with touch:
- Drag the circle up or down {should not scroll the page}
- Drag the diagram up or down {should scroll the page}
- Long press on the circle {should not select the text or bring up a menu}
- Use two separate fingers to drag two separate objects {should both drag independently}
- Use two separate fingers to drag one object {should only drag with the first finger⁴}
- Drag with one finger then try to pinch zoom with a second finger {should not zoom}
- Drag with one finger then try to pinch zoom with two other fingers {does not zoom, not sure what it should do}
- Drag with one finger then rotate the phone {will rotate and continue dragging on iOS; will not rotate on Android}
- On iPad, use Mac “continuity” to drag with the mouse on an ipad browser {should drag}
Notes:
- ¹solution based on pointermove getting called for button changes[2]
- ²it won’t update until you nudge the mouse pointer
- ³this is a limitation of the OS level mouse handling
- ⁴I have a solution but only use it when the object is large
1 Test: SVG single element#
- Basic tests work
- On desktop, scrolling while dragging doesn’t drag until you move your mouse a tiny amount. This could be solved either with a timer or by catching the scroll event. Low priority for me.
2 Test: SVG nested element with text#
- I use pointer capture on
currentTarget
nottarget
. - While dragging, I set CSS user-select: none. This prevents selecting the text by dragging or double clicking (desktop) or long press (mobile). But I don’t want this all the time. When not dragging, I want the text to be selectable.
- On desktop, if you select the text of the page and then try to drag it, it will let you drag that text outside the browser. But if you also try to drag this circle the two drag handlers will intefere. Use preventDefault() on the
dragstart
event to fix this.
3 Test: Canvas drawing#
The same drag event handlers can be used for drawing instead of moving an object:
4 Test: Canvas dragging#
- ⁴if I put a second finger on the diagram it had been jumping to the second finger’s position. This is because the same is getting the
pointermove
event for the second finger, whereas in the other demos a different element gets the events for the second finger. To fix this, I checked the.pointerId
field in thepointermove
event to make sure it matches the.pointerId
from thepointerdown
event.
5 Test: HTML div absolute positioned#
Drag me
- It is possible to place the box outside the container by placing it on the right, then shrinking the browser size. I’m going to leave this up to the application and not try to solve it generically.
6 Test: HTML div css transform#
Drag me
7 Notes#
None of these handle CSS transforms on the parent elements. This is an unsolved issue, not only for me, but also other libraries like d3.js. See https://github.com/d3/d3-selection/issues/67[3] and https://bugzilla.mozilla.org/show_bug.cgi?id=1610093[4] . There’s probably something we can do using window.getComputedStyle(element)
but this is a low priority for me, as I almost never use css transforms above a draggable element.