mirror of
https://github.com/FoggedLens/iD.git
synced 2026-06-01 20:51:36 +02:00
Use pointer events for node dragging and drawing (re: #5505)
Enable dragging nodes with touches and styluses (close #7415)
This commit is contained in:
+14
-20
@@ -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';
|
||||
@@ -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() {
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
+17
-19
@@ -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';
|
||||
@@ -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()`
|
||||
@@ -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
|
||||
@@ -100,7 +98,7 @@ export function behaviorDraw(context) {
|
||||
}
|
||||
|
||||
|
||||
function mousemove() {
|
||||
function pointermove() {
|
||||
_lastMouse = d3_event;
|
||||
dispatch.call('move', this, datum());
|
||||
}
|
||||
@@ -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() {
|
||||
@@ -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);
|
||||
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user