Skip to content

Commit

Permalink
Use pointer events for node dragging and drawing (re: openstreetmap#5505
Browse files Browse the repository at this point in the history
)

Enable dragging nodes with touches and styluses (close openstreetmap#7415)
  • Loading branch information
quincylvania authored and zlavergne committed Mar 10, 2020
1 parent a3b0dcd commit a1edf3a
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 47 deletions.
34 changes: 14 additions & 20 deletions modules/behavior/drag.js
Expand Up @@ -5,8 +5,7 @@ import {
event as d3_event,
mouse as d3_mouse,
select as d3_select,
selection as d3_selection,
touches as d3_touches
selection as d3_selection
} from 'd3-selection';

import { osmNote } from '../osm';
Expand Down Expand Up @@ -37,6 +36,8 @@ export function behaviorDrag() {
var _target;
var _surface;

// use pointer events on supported platforms; fallback to mouse events
var _pointerPrefix = 'PointerEvent' in window ? 'pointer' : 'mouse';

var d3_event_userSelectProperty = utilPrefixCSSProperty('UserSelect');
var d3_event_userSelectSuppress = function() {
Expand Down Expand Up @@ -68,15 +69,14 @@ export function behaviorDrag() {
_event = eventOf(_target, arguments);

var eventTarget = d3_event.target;
var touchId = d3_event.touches ? d3_event.changedTouches[0].identifier : null;
var offset;
var startOrigin = point();
var started = false;
var selectEnable = d3_event_userSelectSuppress(touchId !== null ? 'drag-' + touchId : 'drag');
var selectEnable = d3_event_userSelectSuppress();

d3_select(window)
.on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', dragmove)
.on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', dragend, true);
.on(_pointerPrefix + 'move.drag', dragmove)
.on(_pointerPrefix + 'up.drag', dragend, true);

if (_origin) {
offset = _origin.apply(_target, arguments);
Expand All @@ -85,16 +85,12 @@ export function behaviorDrag() {
offset = [0, 0];
}

if (touchId === null) {
d3_event.stopPropagation();
}
d3_event.stopPropagation();


function point() {
var p = _surface || _target.parentNode;
return touchId !== null ? d3_touches(p).filter(function(p) {
return p.identifier === touchId;
})[0] : d3_mouse(p);
return d3_mouse(p);
}


Expand Down Expand Up @@ -134,8 +130,8 @@ export function behaviorDrag() {
}

d3_select(window)
.on(touchId !== null ? 'touchmove.drag-' + touchId : 'mousemove.drag', null)
.on(touchId !== null ? 'touchend.drag-' + touchId : 'mouseup.drag', null);
.on(_pointerPrefix + 'move.drag', null)
.on(_pointerPrefix + 'up.drag', null);

selectEnable();
}
Expand Down Expand Up @@ -171,15 +167,13 @@ export function behaviorDrag() {
}

selection
.on('mousedown.drag' + _selector, delegate)
.on('touchstart.drag' + _selector, delegate);
.on(_pointerPrefix + 'down.drag' + _selector, delegate);
}


behavior.off = function(selection) {
selection
.on('mousedown.drag' + _selector, null)
.on('touchstart.drag' + _selector, null);
.on(_pointerPrefix + 'down.drag' + _selector, null);
};


Expand All @@ -199,8 +193,8 @@ export function behaviorDrag() {

behavior.cancel = function() {
d3_select(window)
.on('mousemove.drag', null)
.on('mouseup.drag', null);
.on(_pointerPrefix + 'move.drag', null)
.on(_pointerPrefix + 'up.drag', null);
return behavior;
};

Expand Down
36 changes: 17 additions & 19 deletions modules/behavior/draw.js
Expand Up @@ -3,8 +3,7 @@ import { dispatch as d3_dispatch } from 'd3-dispatch';
import {
event as d3_event,
mouse as d3_mouse,
select as d3_select,
touches as d3_touches
select as d3_select
} from 'd3-selection';

import { behaviorEdit } from './edit';
Expand Down Expand Up @@ -35,6 +34,9 @@ export function behaviorDraw(context) {
var _mouseLeave = false;
var _lastMouse = null;

// use pointer events on supported platforms; fallback to mouse events
var _pointerPrefix = 'PointerEvent' in window ? 'pointer' : 'mouse';


// related code
// - `mode/drag_node.js` `datum()`
Expand All @@ -57,29 +59,25 @@ export function behaviorDraw(context) {
}


function mousedown() {
function pointerdown() {

function point() {
var p = context.container().node();
return touchId !== null ? d3_touches(p).filter(function(p) {
return p.identifier === touchId;
})[0] : d3_mouse(p);
return d3_mouse(context.container().node());
}

var element = d3_select(this);
var touchId = d3_event.touches ? d3_event.changedTouches[0].identifier : null;
var t1 = +new Date();
var p1 = point();

element.on('mousemove.draw', null);
element.on(_pointerPrefix + 'move.draw', null);

d3_select(window).on('mouseup.draw', function() {
d3_select(window).on(_pointerPrefix + 'up.draw', function() {
var t2 = +new Date();
var p2 = point();
var dist = geoVecLength(p1, p2);

element.on('mousemove.draw', mousemove);
d3_select(window).on('mouseup.draw', null);
element.on(_pointerPrefix + 'move.draw', pointermove);
d3_select(window).on(_pointerPrefix + 'up.draw', null);

if (dist < closeTolerance || (dist < tolerance && (t2 - t1) < 500)) {
// Prevent a quick second click
Expand All @@ -100,7 +98,7 @@ export function behaviorDraw(context) {
}


function mousemove() {
function pointermove() {
_lastMouse = d3_event;
dispatch.call('move', this, datum());
}
Expand All @@ -120,7 +118,7 @@ export function behaviorDraw(context) {
}

// related code
// - `mode/drag_node.js` `doMode()`
// - `mode/drag_node.js` `doMove()`
// - `behavior/draw.js` `click()`
// - `behavior/draw_way.js` `move()`
function click() {
Expand Down Expand Up @@ -215,8 +213,8 @@ export function behaviorDraw(context) {
selection
.on('mouseenter.draw', mouseenter)
.on('mouseleave.draw', mouseleave)
.on('mousedown.draw', mousedown)
.on('mousemove.draw', mousemove);
.on(_pointerPrefix + 'down.draw', pointerdown)
.on(_pointerPrefix + 'move.draw', pointermove);

d3_select(document)
.call(keybinding);
Expand All @@ -238,11 +236,11 @@ export function behaviorDraw(context) {
selection
.on('mouseenter.draw', null)
.on('mouseleave.draw', null)
.on('mousedown.draw', null)
.on('mousemove.draw', null);
.on(_pointerPrefix + 'down.draw', null)
.on(_pointerPrefix + 'move.draw', null);

d3_select(window)
.on('mouseup.draw', null);
.on(_pointerPrefix + 'up.draw', null);
// note: keyup.space-block, click.draw-block should remain

d3_select(document)
Expand Down
2 changes: 1 addition & 1 deletion modules/behavior/draw_way.js
Expand Up @@ -76,7 +76,7 @@ export function behaviorDrawWay(context, wayID, index, mode, startGraph, baselin


// related code
// - `mode/drag_node.js` `doMode()`
// - `mode/drag_node.js` `doMove()`
// - `behavior/draw.js` `click()`
// - `behavior/draw_way.js` `move()`
function move(datum) {
Expand Down
2 changes: 1 addition & 1 deletion modules/modes/drag_node.js
Expand Up @@ -192,7 +192,7 @@ export function modeDragNode(context) {

if (!_nudgeInterval) { // If not nudging at the edge of the viewport, try to snap..
// related code
// - `mode/drag_node.js` `doMode()`
// - `mode/drag_node.js` `doMove()`
// - `behavior/draw.js` `click()`
// - `behavior/draw_way.js` `move()`
var d = datum();
Expand Down
15 changes: 9 additions & 6 deletions modules/renderer/map.js
Expand Up @@ -64,6 +64,9 @@ export function rendererMap(context) {
// whether a pointerdown event started the zoom
var _pointerDown = false;

// use pointer events on supported platforms; fallback to mouse events
var _pointerPrefix = 'PointerEvent' in window ? 'pointer' : 'mouse';

// use pointer event interaction if supported; fallback to touch/mouse events in d3-zoom
var _zoomerPannerFunction = 'PointerEvent' in window ? utilZoomPan : d3_zoom;

Expand Down Expand Up @@ -169,27 +172,27 @@ export function rendererMap(context) {
_gestureTransformStart = projection.transform();
})
.on('gesturechange.surface', gestureChange)
.on('mousedown.zoom', function() {
.on(_pointerPrefix + 'down.zoom', function() {
if (d3_event.button === 2) {
d3_event.stopPropagation();
}
}, true)
.on('mouseup.zoom', function() {
.on(_pointerPrefix + 'up.zoom', function() {
if (resetTransform()) {
immediateRedraw();
}
})
.on('mousemove.map', function() {
.on(_pointerPrefix + 'move.map', function() {
_mouseEvent = d3_event;
})
.on('mouseover.vertices', function() {
.on(_pointerPrefix + 'over.vertices', function() {
if (map.editableDataEnabled() && !_isTransformed) {
var hover = d3_event.target.__data__;
surface.call(drawVertices.drawHover, context.graph(), hover, map.extent());
dispatch.call('drawn', this, { full: false });
}
})
.on('mouseout.vertices', function() {
.on(_pointerPrefix + 'out.vertices', function() {
if (map.editableDataEnabled() && !_isTransformed) {
var hover = d3_event.relatedTarget && d3_event.relatedTarget.__data__;
surface.call(drawVertices.drawHover, context.graph(), hover, map.extent());
Expand Down Expand Up @@ -898,7 +901,7 @@ export function rendererMap(context) {


map.startEase = function() {
utilBindOnce(surface, 'mousedown.ease', function() {
utilBindOnce(surface, _pointerPrefix + 'down.ease', function() {
map.cancelEase();
});
return map;
Expand Down

0 comments on commit a1edf3a

Please sign in to comment.