diff --git a/modules/behavior/draw.js b/modules/behavior/draw.js index 7f6c2216da..5a541ba809 100644 --- a/modules/behavior/draw.js +++ b/modules/behavior/draw.js @@ -89,7 +89,8 @@ export function behaviorDraw(context) { var p2 = downPointer.pointerLocGetter(d3_event); var dist = geoVecLength(downPointer.downLoc, p2); - if (dist < _closeTolerance || (dist < _tolerance && (t2 - downPointer.downTime) < 500)) { + if (dist < _closeTolerance || + (dist < _tolerance && (t2 - downPointer.downTime) < 500)) { // Prevent a quick second click d3_select(window).on('click.draw-block', function() { d3_event.stopPropagation(); diff --git a/modules/modes/move.js b/modules/modes/move.js index 4e7de30db1..d1cfb7ba86 100644 --- a/modules/modes/move.js +++ b/modules/modes/move.js @@ -7,10 +7,12 @@ import { t } from '../core/localizer'; import { actionMove } from '../actions/move'; import { actionNoop } from '../actions/noop'; import { behaviorEdit } from '../behavior/edit'; -import { geoViewportEdge, geoVecSubtract } from '../geo'; +import { geoVecLength, geoVecSubtract } from '../geo/vector'; +import { geoViewportEdge } from '../geo/geom'; import { modeBrowse } from './browse'; import { modeSelect } from './select'; import { utilKeybinding } from '../util'; +import { utilFastMouse } from '../util/util'; import { operationCircularize } from '../operations/circularize'; @@ -21,6 +23,9 @@ import { operationRotate } from '../operations/rotate'; export function modeMove(context, entityIDs, baseGraph) { + + var _tolerancePx = 4; // see also behaviorDrag, behaviorSelect, modeRotate + var mode = { id: 'move', button: 'browse' @@ -45,6 +50,9 @@ export function modeMove(context, entityIDs, baseGraph) { var _origin; var _nudgeInterval; + // use pointer events on supported platforms; fallback to mouse events + var _pointerPrefix = 'PointerEvent' in window ? 'pointer' : 'mouse'; + function doMove(nudge) { nudge = nudge || [0, 0]; @@ -129,12 +137,29 @@ export function modeMove(context, entityIDs, baseGraph) { behaviors.forEach(context.install); + var downEvent; + context.surface() - .on('mousemove.move', move) - .on('click.move', finish); + .on(_pointerPrefix + 'down.modeMove', function(d3_event) { + downEvent = d3_event; + }); + + d3_select(window) + .on(_pointerPrefix + 'move.modeMove', move, true) + .on(_pointerPrefix + 'up.modeMove', function(d3_event) { + if (!downEvent) return; + var mapNode = context.container().select('.main-map').node(); + var pointGetter = utilFastMouse(mapNode); + var p1 = pointGetter(downEvent); + var p2 = pointGetter(d3_event); + var dist = geoVecLength(p1, p2); + + if (dist <= _tolerancePx) finish(d3_event); + downEvent = null; + }, true); context.history() - .on('undone.move', undone); + .on('undone.modeMove', undone); keybinding .on('⎋', cancel) @@ -153,11 +178,14 @@ export function modeMove(context, entityIDs, baseGraph) { }); context.surface() - .on('mousemove.move', null) - .on('click.move', null); + .on(_pointerPrefix + 'down.modeMove', null); + + d3_select(window) + .on(_pointerPrefix + 'move.modeMove', null, true) + .on(_pointerPrefix + 'up.modeMove', null, true); context.history() - .on('undone.move', null); + .on('undone.modeMove', null); d3_select(document) .call(keybinding.unbind); diff --git a/modules/modes/rotate.js b/modules/modes/rotate.js index 68aa601a93..454e0e028e 100644 --- a/modules/modes/rotate.js +++ b/modules/modes/rotate.js @@ -11,7 +11,7 @@ import { t } from '../core/localizer'; import { actionRotate } from '../actions/rotate'; import { actionNoop } from '../actions/noop'; import { behaviorEdit } from '../behavior/edit'; -import { geoVecInterp } from '../geo'; +import { geoVecInterp, geoVecLength } from '../geo/vector'; import { modeBrowse } from './browse'; import { modeSelect } from './select'; @@ -21,10 +21,14 @@ import { operationMove } from '../operations/move'; import { operationOrthogonalize } from '../operations/orthogonalize'; import { operationReflectLong, operationReflectShort } from '../operations/reflect'; -import { utilGetAllNodes, utilKeybinding } from '../util'; +import { utilKeybinding } from '../util/keybinding'; +import { utilFastMouse, utilGetAllNodes } from '../util/util'; export function modeRotate(context, entityIDs) { + + var _tolerancePx = 4; // see also behaviorDrag, behaviorSelect, modeMove + var mode = { id: 'rotate', button: 'browse' @@ -49,6 +53,9 @@ export function modeRotate(context, entityIDs) { var _prevTransform; var _pivot; + // use pointer events on supported platforms; fallback to mouse events + var _pointerPrefix = 'PointerEvent' in window ? 'pointer' : 'mouse'; + function doRotate(d3_event) { var fn; @@ -127,12 +134,29 @@ export function modeRotate(context, entityIDs) { behaviors.forEach(context.install); + var downEvent; + context.surface() - .on('mousemove.rotate', doRotate) - .on('click.rotate', finish); + .on(_pointerPrefix + 'down.modeRotate', function(d3_event) { + downEvent = d3_event; + }); + + d3_select(window) + .on(_pointerPrefix + 'move.modeRotate', doRotate, true) + .on(_pointerPrefix + 'up.modeRotate', function(d3_event) { + if (!downEvent) return; + var mapNode = context.container().select('.main-map').node(); + var pointGetter = utilFastMouse(mapNode); + var p1 = pointGetter(downEvent); + var p2 = pointGetter(d3_event); + var dist = geoVecLength(p1, p2); + + if (dist <= _tolerancePx) finish(d3_event); + downEvent = null; + }, true); context.history() - .on('undone.rotate', undone); + .on('undone.modeRotate', undone); keybinding .on('⎋', cancel) @@ -147,11 +171,14 @@ export function modeRotate(context, entityIDs) { behaviors.forEach(context.uninstall); context.surface() - .on('mousemove.rotate', null) - .on('click.rotate', null); + .on(_pointerPrefix + 'down.modeRotate', null); + + d3_select(window) + .on(_pointerPrefix + 'move.modeRotate', null, true) + .on(_pointerPrefix + 'up.modeRotate', null, true); context.history() - .on('undone.rotate', null); + .on('undone.modeRotate', null); d3_select(document) .call(keybinding.unbind);