function _clampFn(dx, dy, minDrag) {
        if(Math.abs(dx) < minDrag) dx = 0;
        if(Math.abs(dy) < minDrag) dy = 0;
        return [dx, dy];
    }
Abstracts click & drag interactions

During the interaction, a "coverSlip" element - a transparent
div covering the whole page - is created, which has two key effects:
- Lets you drag beyond the boundaries of the plot itself without
  dropping (but if you drag all the way out of the browser window the
  interaction will end)
- Freezes the cursor: whatever mouse cursor the drag element had when the
  interaction started gets copied to the coverSlip for use until mouseup

If the user executes a drag bigger than MINDRAG, callbacks will fire as:
     prepFn, moveFn (1 or more times), doneFn
If the user does not drag enough, prepFn and clickFn will fire.

Note: If you cancel contextmenu, clickFn will fire even with a right click
(unlike native events) so you'll get a `plotly_click` event. Cancel context eg:
   gd.addEventListener('contextmenu', function(e) { e.preventDefault(); });
TODO: we should probably turn this into a `config` parameter, so we can fix it
such that if you *don't* cancel contextmenu, we can prevent partial drags, which
put you in a weird state.

If the user clicks multiple times quickly, clickFn will fire each time
but numClicks will increase to help you recognize doubleclicks.

@param {object} options with keys:
     element (required) the DOM element to drag
     prepFn (optional) function(event, startX, startY)
         executed on mousedown
         startX and startY are the clientX and clientY pixel position
         of the mousedown event
     moveFn (optional) function(dx, dy)
         executed on move, ONLY after we've exceeded MINDRAG
         (we keep executing moveFn if you move back to where you started)
         dx and dy are the net pixel offset of the drag,
         dragged is true/false, has the mouse moved enough to
         constitute a drag
     doneFn (optional) function(e)
         executed on mouseup, ONLY if we exceeded MINDRAG (so you can be
         sure that moveFn has been called at least once)
         numClicks is how many clicks we've registered within
         a doubleclick time
         e is the original mouseup event
     clickFn (optional) function(numClicks, e)
         executed on mouseup if we have NOT exceeded MINDRAG (ie moveFn
         has not been called at all)
         numClicks is how many clicks we've registered within
         a doubleclick time
         e is the original mousedown event
     clampFn (optional, function(dx, dy) return [dx2, dy2])
         Provide custom clamping function for small displacements.
         By default, clamping is done using `minDrag` to x and y displacements
         independently.