import { services } from '../services'; import { actionNoop } from '../actions/noop'; import { behaviorDrag } from '../behavior/drag'; import { behaviorEdit } from '../behavior/edit'; import { geoVecSubtract, geoViewportEdge } from '../geo'; import { modeSelectNote } from './select_note'; export function modeDragNote(context) { var mode = { id: 'drag-note', button: 'browse' }; var edit = behaviorEdit(context); var _nudgeInterval; var _lastLoc; var _note; // most current note.. dragged note may have stale datum. function startNudge(d3_event, nudge) { if (_nudgeInterval) window.clearInterval(_nudgeInterval); _nudgeInterval = window.setInterval(function() { context.map().pan(nudge); doMove(d3_event, nudge); }, 50); } function stopNudge() { if (_nudgeInterval) { window.clearInterval(_nudgeInterval); _nudgeInterval = null; } } function origin(note) { return context.projection(note.loc); } function start(d3_event, note) { _note = note; var osm = services.osm; if (osm) { // Get latest note from cache.. The marker may have a stale datum bound to it // and dragging it around can sometimes delete the users note comment. _note = osm.getNote(_note.id); } context.surface().selectAll('.note-' + _note.id) .classed('active', true); context.perform(actionNoop()); context.enter(mode); context.selectedNoteID(_note.id); } function move(d3_event, entity, point) { d3_event.stopPropagation(); _lastLoc = context.projection.invert(point); doMove(d3_event); var nudge = geoViewportEdge(point, context.map().dimensions()); if (nudge) { startNudge(d3_event, nudge); } else { stopNudge(); } } function doMove(d3_event, nudge) { nudge = nudge || [0, 0]; var currPoint = (d3_event && d3_event.point) || context.projection(_lastLoc); var currMouse = geoVecSubtract(currPoint, nudge); var loc = context.projection.invert(currMouse); _note = _note.move(loc); var osm = services.osm; if (osm) { osm.replaceNote(_note); // update note cache } context.replace(actionNoop()); // trigger redraw } function end() { context.replace(actionNoop()); // trigger redraw context .selectedNoteID(_note.id) .enter(modeSelectNote(context, _note.id)); } var drag = behaviorDrag() .selector('.layer-touch.markers .target.note.new') .surface(context.container().select('.main-map').node()) .origin(origin) .on('start', start) .on('move', move) .on('end', end); mode.enter = function() { context.install(edit); }; mode.exit = function() { context.ui().sidebar.hover.cancel(); context.uninstall(edit); context.surface() .selectAll('.active') .classed('active', false); stopNudge(); }; mode.behavior = drag; return mode; }