More fixes for drawing/snapping, don't draw touch targets for activeIDs

This commit is contained in:
Bryan Housel
2017-12-18 22:54:49 -05:00
parent eafc2b4300
commit 7a8f50c74e
13 changed files with 95 additions and 49 deletions

View File

@@ -26,7 +26,7 @@
.way.target {
pointer-events: stroke;
fill: none;
stroke-width: 10;
stroke-width: 12;
stroke-opacity: 0.8;
stroke: currentColor;
}

View File

@@ -33,5 +33,9 @@
.fill-partial path.area.fill {
fill-opacity: 0;
stroke-width: 60px;
pointer-events: none;
}
.mode-browse .fill-partial path.area.fill,
.mode-select .fill-partial path.area.fill {
pointer-events: visibleStroke;
}

View File

@@ -48,11 +48,17 @@ export function behaviorDraw(context) {
function datum() {
if (d3_event.altKey) return {};
var element;
if (d3_event.type === 'keydown') {
return (_lastMouse && _lastMouse.target.__data__) || {};
element = _lastMouse && _lastMouse.target;
} else {
return d3_event.target.__data__ || {};
element = d3_event.target;
}
// When drawing, connect only to things classed as targets..
// (this excludes area fills and active drawing elements)
var selection = d3_select(element);
return (selection.classed('target') && element.__data__) || {};
}
@@ -116,8 +122,7 @@ export function behaviorDraw(context) {
function click() {
var trySnap = geoViewportEdge(context.mouse, context.map().dimensions()) !== null;
var trySnap = geoViewportEdge(context.mouse(), context.map().dimensions()) === null;
if (trySnap) {
// If we're not at the edge of the viewport, try to snap..
// See also: `modes/drag_node.js doMove()`
@@ -128,8 +133,8 @@ export function behaviorDraw(context) {
dispatch.call('clickNode', this, d);
return;
// Snap to a way (not an area fill)
} else if (d.type === 'way' && !d3_select(d3_event.sourceEvent.target).classed('fill')) {
// Snap to a way
} else if (d.type === 'way') {
var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection);
var edge = [d.nodes[choice.index - 1], d.nodes[choice.index]];
dispatch.call('clickWay', this, choice.loc, edge);

View File

@@ -13,7 +13,8 @@ import { behaviorDraw } from './draw';
import {
geoChooseEdge,
geoEdgeEqual
geoEdgeEqual,
geoViewportEdge
} from '../geo';
import {
@@ -31,17 +32,18 @@ import { utilEntitySelector } from '../util';
export function behaviorDrawWay(context, wayId, index, mode, startGraph) {
var origWay = context.entity(wayId),
isArea = context.geometry(wayId) === 'area',
tempEdits = 0,
annotation = t((origWay.isDegenerate() ?
'operations.start.annotation.' :
'operations.continue.annotation.') + context.geometry(wayId)),
draw = behaviorDraw(context),
startIndex,
start,
end,
segment;
var origWay = context.entity(wayId);
var isArea = context.geometry(wayId) === 'area';
var tempEdits = 0;
var annotation = t((origWay.isDegenerate() ?
'operations.start.annotation.' :
'operations.continue.annotation.') + context.geometry(wayId));
var draw = behaviorDraw(context);
var _activeIDs = [];
var startIndex;
var start;
var end;
var segment;
// initialize the temporary drawing entities
@@ -49,7 +51,8 @@ export function behaviorDrawWay(context, wayId, index, mode, startGraph) {
startIndex = typeof index === 'undefined' ? origWay.nodes.length - 1 : 0;
start = osmNode({ id: 'nStart', loc: context.entity(origWay.nodes[startIndex]).loc });
end = osmNode({ id: 'nEnd', loc: context.map().mouseCoordinates() });
segment = osmWay({ id: 'wTemp',
segment = osmWay({
id: 'wTemp',
nodes: typeof index === 'undefined' ? [start.id, end.id] : [end.id, start.id],
tags: _clone(origWay.tags)
});
@@ -70,20 +73,11 @@ export function behaviorDrawWay(context, wayId, index, mode, startGraph) {
function move(datum) {
var loc;
if (datum.type === 'node' && datum.id !== end.id) {
loc = datum.loc;
} else if (datum.type === 'way') {
var dims = context.map().dimensions(),
mouse = context.mouse(),
pad = 5,
trySnap = mouse[0] > pad && mouse[0] < dims[0] - pad &&
mouse[1] > pad && mouse[1] < dims[1] - pad;
if (trySnap) {
loc = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection).loc;
}
loc = geoChooseEdge(context.childNodes(datum), context.mouse(), context.projection).loc;
}
if (!loc) {
@@ -110,8 +104,8 @@ export function behaviorDrawWay(context, wayId, index, mode, startGraph) {
function setActiveElements() {
var active = isArea ? [wayId, end.id] : [segment.id, start.id, end.id];
context.surface().selectAll(utilEntitySelector(active))
_activeIDs = isArea ? [wayId, end.id] : [segment.id, start.id, end.id];
context.surface().selectAll(utilEntitySelector(_activeIDs))
.classed('active', true);
}
@@ -326,6 +320,13 @@ export function behaviorDrawWay(context, wayId, index, mode, startGraph) {
};
drawWay.activeIDs = function() {
if (!arguments.length) return _activeIDs;
// no assign
return drawWay;
};
drawWay.tail = function(text) {
draw.tail(text);
return drawWay;

View File

@@ -255,6 +255,13 @@ export function coreContext() {
return [];
}
};
context.activeIDs = function() {
if (mode && mode.activeIDs) {
return mode.activeIDs();
} else {
return [];
}
};
/* Behaviors */

View File

@@ -123,7 +123,7 @@ export function modeDragNode(context) {
function datum() {
var event = d3_event && d3_event.sourceEvent;
if (!event || event.altKey) {
if (!event || event.altKey || !d3_select(event.target).classed('target')) {
return {};
} else {
return event.target.__data__ || {};
@@ -147,11 +147,8 @@ export function modeDragNode(context) {
if (d.type === 'node' && d.id !== entity.id) {
loc = d.loc;
// Snap to a way (not an area fill)
} else if (d.type === 'way' && !d3_select(d3_event.sourceEvent.target).classed('fill')) {
// var childNodes = context.childNodes(d);
// var childIDs = childNodes.map(function(node) { return node.id; });
// Snap to a way
} else if (d.type === 'way') {
var choice = geoChooseEdge(context.childNodes(d), context.mouse(), context.projection);
// (not along a segment adjacent to self)
if (entity.id !== d.nodes[choice.index - 1] && entity.id !== d.nodes[choice.index]) {
@@ -274,6 +271,7 @@ export function modeDragNode(context) {
context.map()
.on('drawn.drag-node', null);
_activeIDs = [];
context.surface()
.selectAll('.active')
.classed('active', false);
@@ -289,6 +287,13 @@ export function modeDragNode(context) {
};
mode.activeIDs = function() {
if (!arguments.length) return _activeIDs;
// no assign
return mode;
};
mode.restoreSelectedIDs = function(_) {
if (!arguments.length) return _restoreSelectedIDs;
_restoreSelectedIDs = _;

View File

@@ -20,8 +20,8 @@ export function modeDrawArea(context, wayId, startGraph) {
var addNode = behavior.addNode;
behavior.addNode = function(node) {
var length = way.nodes.length,
penultimate = length > 2 ? way.nodes[length - 2] : null;
var length = way.nodes.length;
var penultimate = length > 2 ? way.nodes[length - 2] : null;
if (node.id === way.first() || node.id === penultimate) {
behavior.finish();
@@ -43,6 +43,10 @@ export function modeDrawArea(context, wayId, startGraph) {
return [wayId];
};
mode.activeIDs = function() {
return (behavior && behavior.activeIDs()) || [];
};
return mode;
}

View File

@@ -12,15 +12,14 @@ export function modeDrawLine(context, wayId, startGraph, affix) {
mode.enter = function() {
var way = context.entity(wayId),
index = (affix === 'prefix') ? 0 : undefined,
headId = (affix === 'prefix') ? way.first() : way.last();
var way = context.entity(wayId);
var index = (affix === 'prefix') ? 0 : undefined;
var headId = (affix === 'prefix') ? way.first() : way.last();
behavior = behaviorDrawWay(context, wayId, index, mode, startGraph)
.tail(t('modes.draw_line.tail'));
var addNode = behavior.addNode;
behavior.addNode = function(node) {
if (node.id === headId) {
behavior.finish();
@@ -42,6 +41,9 @@ export function modeDrawLine(context, wayId, startGraph, affix) {
return [wayId];
};
mode.activeIDs = function() {
return (behavior && behavior.activeIDs()) || [];
};
return mode;
}

View File

@@ -199,8 +199,9 @@ export function rendererMap(context) {
supersurface
.call(context.background());
context.on('enter.map', function() {
context.on('enter.map', function() {
if (map.editable() && !transformed) {
// redraw immediately the objects that are affected by a chnage in selectedIDs.
var all = context.intersects(map.extent());
var filter = utilFunctor(true);
var graph = context.graph();
@@ -210,6 +211,9 @@ export function rendererMap(context) {
.call(drawVertices.drawSelected, graph, all, map.extent())
.call(drawMidpoints, graph, all, filter, map.trimmedExtent());
dispatch.call('drawn', this, { full: false });
// redraw everything else later
scheduleRedraw();
}
});

View File

@@ -44,10 +44,13 @@ export function svgAreas(projection, context) {
function drawTargets(selection, graph, entities, filter) {
var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
var getPath = svgPath(projection, graph);
var passive = entities.filter(function(d) {
return context.activeIDs().indexOf(d.id) === -1;
});
var targets = selection.selectAll('.area.target')
.filter(filter)
.data(entities, function key(d) { return d.id; });
.data(passive, function key(d) { return d.id; });
// exit
targets.exit()

View File

@@ -39,10 +39,13 @@ export function svgLines(projection, context) {
function drawTargets(selection, graph, entities, filter) {
var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
var getPath = svgPath(projection, graph);
var passive = entities.filter(function(d) {
return context.activeIDs().indexOf(d.id) === -1;
});
var targets = selection.selectAll('.line.target')
.filter(filter)
.data(entities, function key(d) { return d.id; });
.data(passive, function key(d) { return d.id; });
// exit
targets.exit()

View File

@@ -29,9 +29,13 @@ export function svgPoints(projection, context) {
function drawTargets(selection, graph, entities, filter) {
var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
var passive = entities.filter(function(d) {
return context.activeIDs().indexOf(d.id) === -1;
});
var targets = selection.selectAll('.point.target')
.filter(filter)
.data(entities, function key(d) { return d.id; });
.data(passive, function key(d) { return d.id; });
// exit
targets.exit()

View File

@@ -183,9 +183,13 @@ export function svgVertices(projection, context) {
function drawTargets(selection, graph, entities, filter) {
var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
var passive = entities.filter(function(d) {
return context.activeIDs().indexOf(d.id) === -1;
});
var targets = selection.selectAll('.vertex.target')
.filter(filter)
.data(entities, function key(d) { return d.id; });
.data(passive, function key(d) { return d.id; });
// exit
targets.exit()