mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-12 16:52:50 +00:00
WIP to render vertices while dragging
(re: #3003 / #4602) For now, drawHover is commented out. Still not sure what I will do with it. This means that things flicker a bit when dragging, also connecting nodes (and closing lines) does not currently work. There was lot going on preventing the vertices from rendering while dragging. 1. `modeDragNode` needed a proper `selectedIDs()` function that works like other modes.. Many other places in iD (including the vertex renderer) call `context.selectedIDs()`.. This means that `modeDragNode` needs a new function `restoreSelectedIDs()` to do what `selectedIDs()` was previously doing (a place to store selectedIDs so that we can reselect those entities after the user is done dragging a node in select mode) 2. Just so many things in svg/vertices.js - siblingAndChildVertices was missing some things for points that we render as vertices (points in wireframe, points with directions) - the sibling vertices weren't being included in the `filter` function, so would disappear when doing differenced/extent redraws - probably some other things
This commit is contained in:
@@ -88,7 +88,7 @@ g.midpoint .shadow {
|
||||
fill-opacity: 0;
|
||||
}
|
||||
|
||||
g.vertex.vertex-hover {
|
||||
/*g.vertex.vertex-hover {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ g.vertex.vertex-hover {
|
||||
.mode-drag-node .hover-disabled g.vertex.vertex-hover {
|
||||
display: none;
|
||||
}
|
||||
|
||||
*/
|
||||
g.vertex.related:not(.selected) .shadow,
|
||||
g.vertex.hover:not(.selected) .shadow,
|
||||
g.midpoint.related:not(.selected) .shadow,
|
||||
@@ -126,7 +126,7 @@ g.vertex.selected .shadow {
|
||||
.mode-add-area g.midpoint,
|
||||
.mode-add-line g.midpoint,
|
||||
.mode-add-point g.midpoint {
|
||||
display: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* lines */
|
||||
|
||||
@@ -38,12 +38,12 @@
|
||||
|
||||
/* Modes */
|
||||
|
||||
.mode-draw-line .vertex.active,
|
||||
/*.mode-draw-line .vertex.active,
|
||||
.mode-draw-area .vertex.active,
|
||||
.mode-drag-node .vertex.active {
|
||||
display: none;
|
||||
}
|
||||
|
||||
*/
|
||||
.mode-draw-line .way.active,
|
||||
.mode-draw-area .way.active,
|
||||
.mode-drag-node .active {
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import _map from 'lodash-es/map';
|
||||
|
||||
import {
|
||||
event as d3_event,
|
||||
select as d3_select
|
||||
@@ -36,15 +34,16 @@ export function modeDragNode(context) {
|
||||
id: 'drag-node',
|
||||
button: 'browse'
|
||||
};
|
||||
var hover = behaviorHover(context).altDisables(true).on('hover', context.ui().sidebar.hover);
|
||||
var edit = behaviorEdit(context);
|
||||
|
||||
var nudgeInterval,
|
||||
activeIDs,
|
||||
wasMidpoint,
|
||||
isCancelled,
|
||||
lastLoc,
|
||||
selectedIDs = [],
|
||||
hover = behaviorHover(context).altDisables(true).on('hover', context.ui().sidebar.hover),
|
||||
edit = behaviorEdit(context);
|
||||
var _nudgeInterval;
|
||||
var _restoreSelectedIDs = [];
|
||||
var _activeIDs = [];
|
||||
var _wasMidpoint = false;
|
||||
var _isCancelled = false;
|
||||
var _dragEntity;
|
||||
var _lastLoc;
|
||||
|
||||
|
||||
function vecSub(a, b) {
|
||||
@@ -52,9 +51,9 @@ export function modeDragNode(context) {
|
||||
}
|
||||
|
||||
function edge(point, size) {
|
||||
var pad = [80, 20, 50, 20], // top, right, bottom, left
|
||||
x = 0,
|
||||
y = 0;
|
||||
var pad = [80, 20, 50, 20]; // top, right, bottom, left
|
||||
var x = 0;
|
||||
var y = 0;
|
||||
|
||||
if (point[0] > size[0] - pad[1])
|
||||
x = -10;
|
||||
@@ -74,8 +73,8 @@ export function modeDragNode(context) {
|
||||
|
||||
|
||||
function startNudge(entity, nudge) {
|
||||
if (nudgeInterval) window.clearInterval(nudgeInterval);
|
||||
nudgeInterval = window.setInterval(function() {
|
||||
if (_nudgeInterval) window.clearInterval(_nudgeInterval);
|
||||
_nudgeInterval = window.setInterval(function() {
|
||||
context.pan(nudge);
|
||||
doMove(entity, nudge);
|
||||
}, 50);
|
||||
@@ -83,9 +82,9 @@ export function modeDragNode(context) {
|
||||
|
||||
|
||||
function stopNudge() {
|
||||
if (nudgeInterval) {
|
||||
window.clearInterval(nudgeInterval);
|
||||
nudgeInterval = null;
|
||||
if (_nudgeInterval) {
|
||||
window.clearInterval(_nudgeInterval);
|
||||
_nudgeInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,19 +105,19 @@ export function modeDragNode(context) {
|
||||
|
||||
|
||||
function start(entity) {
|
||||
wasMidpoint = entity.type === 'midpoint';
|
||||
_wasMidpoint = entity.type === 'midpoint';
|
||||
var hasHidden = context.features().hasHiddenConnections(entity, context.graph());
|
||||
isCancelled = d3_event.sourceEvent.shiftKey || hasHidden;
|
||||
_isCancelled = d3_event.sourceEvent.shiftKey || hasHidden;
|
||||
|
||||
|
||||
if (isCancelled) {
|
||||
if (_isCancelled) {
|
||||
if (hasHidden) {
|
||||
uiFlash().text(t('modes.drag_node.connected_to_hidden'))();
|
||||
}
|
||||
return behavior.cancel();
|
||||
}
|
||||
|
||||
if (wasMidpoint) {
|
||||
if (_wasMidpoint) {
|
||||
var midpoint = entity;
|
||||
entity = osmNode();
|
||||
context.perform(actionAddMidpoint(midpoint, entity));
|
||||
@@ -130,10 +129,13 @@ export function modeDragNode(context) {
|
||||
context.perform(actionNoop());
|
||||
}
|
||||
|
||||
_dragEntity = entity;
|
||||
|
||||
// activeIDs generate no pointer events. This prevents the node or vertex
|
||||
// being dragged from trying to connect to itself or its parent element.
|
||||
activeIDs = _map(context.graph().parentWays(entity), 'id');
|
||||
activeIDs.push(entity.id);
|
||||
_activeIDs = context.graph().parentWays(entity)
|
||||
.map(function(parent) { return parent.id; });
|
||||
_activeIDs.push(entity.id);
|
||||
setActiveElements();
|
||||
|
||||
context.enter(mode);
|
||||
@@ -153,12 +155,12 @@ export function modeDragNode(context) {
|
||||
function doMove(entity, nudge) {
|
||||
nudge = nudge || [0, 0];
|
||||
|
||||
var currPoint = (d3_event && d3_event.point) || context.projection(lastLoc),
|
||||
currMouse = vecSub(currPoint, nudge),
|
||||
loc = context.projection.invert(currMouse),
|
||||
d = datum();
|
||||
var currPoint = (d3_event && d3_event.point) || context.projection(_lastLoc);
|
||||
var currMouse = vecSub(currPoint, nudge);
|
||||
var loc = context.projection.invert(currMouse);
|
||||
var d = datum();
|
||||
|
||||
if (!nudgeInterval) {
|
||||
if (!_nudgeInterval) {
|
||||
if (d.type === 'node' && d.id !== entity.id) {
|
||||
loc = d.loc;
|
||||
} else if (d.type === 'way' && !d3_select(d3_event.sourceEvent.target).classed('fill')) {
|
||||
@@ -171,14 +173,15 @@ export function modeDragNode(context) {
|
||||
moveAnnotation(entity)
|
||||
);
|
||||
|
||||
lastLoc = loc;
|
||||
_lastLoc = loc;
|
||||
}
|
||||
|
||||
|
||||
function move(entity) {
|
||||
if (isCancelled) return;
|
||||
if (_isCancelled) return;
|
||||
|
||||
d3_event.sourceEvent.stopPropagation();
|
||||
lastLoc = context.projection.invert(d3_event.point);
|
||||
_lastLoc = context.projection.invert(d3_event.point);
|
||||
|
||||
doMove(entity);
|
||||
var nudge = edge(d3_event.point, context.map().dimensions());
|
||||
@@ -191,7 +194,7 @@ export function modeDragNode(context) {
|
||||
|
||||
|
||||
function end(entity) {
|
||||
if (isCancelled) return;
|
||||
if (_isCancelled) return;
|
||||
|
||||
var d = datum();
|
||||
|
||||
@@ -208,7 +211,7 @@ export function modeDragNode(context) {
|
||||
connectAnnotation(d)
|
||||
);
|
||||
|
||||
} else if (wasMidpoint) {
|
||||
} else if (_wasMidpoint) {
|
||||
context.replace(
|
||||
actionNoop(),
|
||||
t('operations.add.annotation.vertex')
|
||||
@@ -221,7 +224,7 @@ export function modeDragNode(context) {
|
||||
);
|
||||
}
|
||||
|
||||
var reselection = selectedIDs.filter(function(id) {
|
||||
var reselection = _restoreSelectedIDs.filter(function(id) {
|
||||
return context.graph().hasEntity(id);
|
||||
});
|
||||
|
||||
@@ -240,7 +243,7 @@ export function modeDragNode(context) {
|
||||
|
||||
|
||||
function setActiveElements() {
|
||||
context.surface().selectAll(utilEntitySelector(activeIDs))
|
||||
context.surface().selectAll(utilEntitySelector(_activeIDs))
|
||||
.classed('active', true);
|
||||
}
|
||||
|
||||
@@ -287,9 +290,16 @@ export function modeDragNode(context) {
|
||||
};
|
||||
|
||||
|
||||
mode.selectedIDs = function(_) {
|
||||
if (!arguments.length) return selectedIDs;
|
||||
selectedIDs = _;
|
||||
mode.selectedIDs = function() {
|
||||
if (!arguments.length) return _dragEntity ? [_dragEntity.id] : [];
|
||||
// no assign
|
||||
return mode;
|
||||
};
|
||||
|
||||
|
||||
mode.restoreSelectedIDs = function(_) {
|
||||
if (!arguments.length) return _restoreSelectedIDs;
|
||||
_restoreSelectedIDs = _;
|
||||
return mode;
|
||||
};
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
behaviorHover(context),
|
||||
behaviorSelect(context),
|
||||
behaviorLasso(context),
|
||||
modeDragNode(context).selectedIDs(selectedIDs).behavior
|
||||
modeDragNode(context).restoreSelectedIDs(selectedIDs).behavior
|
||||
],
|
||||
inspector,
|
||||
editMenu,
|
||||
|
||||
@@ -178,38 +178,38 @@ export function rendererMap(context) {
|
||||
})
|
||||
.on('mousemove.map', function() {
|
||||
mousemove = d3_event;
|
||||
})
|
||||
.on('mouseover.vertices', function() {
|
||||
if (map.editable() && !transformed) {
|
||||
var hover = d3_event.target.__data__;
|
||||
surface.selectAll('.data-layer-osm')
|
||||
.call(drawVertices.drawHover, context.graph(), hover, map.extent());
|
||||
dispatch.call('drawn', this, {full: false});
|
||||
}
|
||||
})
|
||||
.on('mouseout.vertices', function() {
|
||||
if (map.editable() && !transformed) {
|
||||
var hover = d3_event.relatedTarget && d3_event.relatedTarget.__data__;
|
||||
surface.selectAll('.data-layer-osm')
|
||||
.call(drawVertices.drawHover, context.graph(), hover, map.extent());
|
||||
dispatch.call('drawn', this, {full: false});
|
||||
}
|
||||
});
|
||||
// .on('mouseover.vertices', function() {
|
||||
// if (map.editable() && !transformed) {
|
||||
// var hover = d3_event.target.__data__;
|
||||
// surface.selectAll('.data-layer-osm')
|
||||
// .call(drawVertices.drawHover, context.graph(), hover, map.extent());
|
||||
// dispatch.call('drawn', this, { full: false });
|
||||
// }
|
||||
// })
|
||||
// .on('mouseout.vertices', function() {
|
||||
// if (map.editable() && !transformed) {
|
||||
// var hover = d3_event.relatedTarget && d3_event.relatedTarget.__data__;
|
||||
// surface.selectAll('.data-layer-osm')
|
||||
// .call(drawVertices.drawHover, context.graph(), hover, map.extent());
|
||||
// dispatch.call('drawn', this, { full: false });
|
||||
// }
|
||||
// });
|
||||
|
||||
supersurface
|
||||
.call(context.background());
|
||||
|
||||
context.on('enter.map', function() {
|
||||
if (map.editable() && !transformed) {
|
||||
var all = context.intersects(map.extent()),
|
||||
filter = utilFunctor(true),
|
||||
graph = context.graph();
|
||||
var all = context.intersects(map.extent());
|
||||
var filter = utilFunctor(true);
|
||||
var graph = context.graph();
|
||||
|
||||
all = context.features().filter(all, graph);
|
||||
surface.selectAll('.data-layer-osm')
|
||||
.call(drawVertices, graph, all, filter, map.extent())
|
||||
.call(drawMidpoints, graph, all, filter, map.trimmedExtent());
|
||||
dispatch.call('drawn', this, {full: false});
|
||||
dispatch.call('drawn', this, { full: false });
|
||||
}
|
||||
});
|
||||
|
||||
@@ -265,10 +265,11 @@ export function rendererMap(context) {
|
||||
|
||||
|
||||
function drawVector(difference, extent) {
|
||||
var graph = context.graph(),
|
||||
features = context.features(),
|
||||
all = context.intersects(map.extent()),
|
||||
data, filter;
|
||||
var graph = context.graph();
|
||||
var features = context.features();
|
||||
var all = context.intersects(map.extent());
|
||||
var data;
|
||||
var filter;
|
||||
|
||||
if (difference) {
|
||||
var complete = difference.complete(map.extent());
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import _clone from 'lodash-es/clone';
|
||||
import _values from 'lodash-es/values';
|
||||
|
||||
import { select as d3_select } from 'd3-selection';
|
||||
@@ -13,55 +14,16 @@ function ktoz(k) { return Math.log(k * TAU) / Math.LN2 - 8; }
|
||||
|
||||
export function svgVertices(projection, context) {
|
||||
var radiuses = {
|
||||
// z16-, z17, z18+, tagged
|
||||
shadow: [6, 7.5, 7.5, 11.5],
|
||||
stroke: [2.5, 3.5, 3.5, 7],
|
||||
fill: [1, 1.5, 1.5, 1.5]
|
||||
// z16-, z17, z18+, tagged
|
||||
shadow: [6, 7.5, 7.5, 11.5],
|
||||
stroke: [2.5, 3.5, 3.5, 7],
|
||||
fill: [1, 1.5, 1.5, 1.5]
|
||||
};
|
||||
|
||||
var _hover;
|
||||
|
||||
|
||||
function siblingAndChildVertices(ids, graph, extent) {
|
||||
var vertices = {};
|
||||
|
||||
function addChildVertices(entity) {
|
||||
if (!context.features().isHiddenFeature(entity, graph, entity.geometry(graph))) {
|
||||
var i;
|
||||
if (entity.type === 'way') {
|
||||
for (i = 0; i < entity.nodes.length; i++) {
|
||||
addChildVertices(graph.entity(entity.nodes[i]));
|
||||
}
|
||||
} else if (entity.type === 'relation') {
|
||||
for (i = 0; i < entity.members.length; i++) {
|
||||
var member = context.hasEntity(entity.members[i].id);
|
||||
if (member) {
|
||||
addChildVertices(member);
|
||||
}
|
||||
}
|
||||
} else if (entity.intersects(extent, graph)) {
|
||||
vertices[entity.id] = entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ids.forEach(function(id) {
|
||||
var entity = context.hasEntity(id);
|
||||
if (entity && entity.type === 'node') {
|
||||
vertices[entity.id] = entity;
|
||||
context.graph().parentWays(entity).forEach(function(entity) {
|
||||
addChildVertices(entity);
|
||||
});
|
||||
} else if (entity) {
|
||||
addChildVertices(entity);
|
||||
}
|
||||
});
|
||||
|
||||
return vertices;
|
||||
}
|
||||
|
||||
|
||||
function draw(selection, vertices, klass, graph, siblings) {
|
||||
function draw(selection, vertices, klass, graph, siblings, filter) {
|
||||
siblings = siblings || {};
|
||||
var icons = {};
|
||||
var directions = {};
|
||||
@@ -127,7 +89,8 @@ export function svgVertices(projection, context) {
|
||||
}
|
||||
|
||||
|
||||
var groups = selection
|
||||
var groups = selection.selectAll('.vertex.' + klass)
|
||||
.filter(filter)
|
||||
.data(vertices, osmEntity.key);
|
||||
|
||||
// exit
|
||||
@@ -178,7 +141,7 @@ export function svgVertices(projection, context) {
|
||||
// Directional vertices get viewfields
|
||||
var dgroups = groups.filter(function(d) { return getDirections(d); })
|
||||
.selectAll('.viewfieldgroup')
|
||||
.data(function(d) { return klass === 'vertex-hover' ? [] : [d]; }, osmEntity.key);
|
||||
.data(function(d) { return /*klass === 'vertex-hover' ? [] : */[d]; }, osmEntity.key);
|
||||
|
||||
// exit
|
||||
dgroups.exit()
|
||||
@@ -209,53 +172,104 @@ export function svgVertices(projection, context) {
|
||||
|
||||
|
||||
function drawVertices(selection, graph, entities, filter, extent) {
|
||||
var siblings = siblingAndChildVertices(context.selectedIDs(), graph, extent);
|
||||
var wireframe = context.surface().classed('fill-wireframe');
|
||||
var vertices = [];
|
||||
|
||||
var siblings = {};
|
||||
getSiblingAndChildVertices(context.selectedIDs(), graph, extent);
|
||||
|
||||
// always render selected and sibling vertices..
|
||||
var vertices = _clone(siblings);
|
||||
var filterWithSiblings = function(d) { return d.id in siblings || filter(d); };
|
||||
|
||||
// also render important vertices from the `entities` list..
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var entity = entities[i];
|
||||
var geometry = entity.geometry(graph);
|
||||
|
||||
if ((geometry === 'point') && (wireframe || entity.directions(graph, projection).length)) {
|
||||
vertices.push(entity);
|
||||
continue;
|
||||
}
|
||||
if ((geometry === 'point') && renderAsVertex(entity)) {
|
||||
vertices[entity.id] = entity;
|
||||
|
||||
if (geometry !== 'vertex')
|
||||
continue;
|
||||
|
||||
if (entity.id in siblings ||
|
||||
entity.hasInterestingTags() ||
|
||||
entity.isEndpoint(graph) ||
|
||||
entity.isConnected(graph)) {
|
||||
vertices.push(entity);
|
||||
} else if ((geometry === 'vertex') &&
|
||||
(entity.hasInterestingTags() || entity.isEndpoint(graph) || entity.isConnected(graph)) ) {
|
||||
vertices[entity.id] = entity;
|
||||
}
|
||||
}
|
||||
|
||||
var layer = selection.selectAll('.layer-hit');
|
||||
layer.selectAll('g.vertex.vertex-persistent')
|
||||
.filter(filter)
|
||||
.call(draw, vertices, 'vertex-persistent', graph, siblings);
|
||||
|
||||
drawHover(selection, graph, extent);
|
||||
selection.selectAll('.layer-hit')
|
||||
.call(draw, _values(vertices), 'vertex-persistent', graph, siblings, filterWithSiblings);
|
||||
|
||||
// drawHover(selection, graph, extent, true);
|
||||
|
||||
|
||||
function renderAsVertex(entity) {
|
||||
var geometry = entity.geometry(graph);
|
||||
return (geometry === 'vertex') ||
|
||||
(geometry === 'point' && (wireframe || entity.directions(graph, projection).length));
|
||||
}
|
||||
|
||||
|
||||
function getSiblingAndChildVertices(ids, graph, extent) {
|
||||
|
||||
function addChildVertices(entity) {
|
||||
var geometry = entity.geometry(graph);
|
||||
if (!context.features().isHiddenFeature(entity, graph, geometry)) {
|
||||
var i;
|
||||
if (entity.type === 'way') {
|
||||
for (i = 0; i < entity.nodes.length; i++) {
|
||||
var child = context.hasEntity(entity.nodes[i]);
|
||||
if (child) {
|
||||
addChildVertices(child);
|
||||
}
|
||||
}
|
||||
} else if (entity.type === 'relation') {
|
||||
for (i = 0; i < entity.members.length; i++) {
|
||||
var member = context.hasEntity(entity.members[i].id);
|
||||
if (member) {
|
||||
addChildVertices(member);
|
||||
}
|
||||
}
|
||||
} else if (renderAsVertex(entity) && entity.intersects(extent, graph)) {
|
||||
siblings[entity.id] = entity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ids.forEach(function(id) {
|
||||
var entity = context.hasEntity(id);
|
||||
if (!entity) return;
|
||||
|
||||
if (entity.type === 'node') {
|
||||
if (renderAsVertex(entity)) {
|
||||
siblings[entity.id] = entity;
|
||||
graph.parentWays(entity).forEach(function(entity) {
|
||||
addChildVertices(entity);
|
||||
});
|
||||
}
|
||||
} else { // way, relation
|
||||
addChildVertices(entity);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function drawHover(selection, graph, extent) {
|
||||
var hovered = _hover ? siblingAndChildVertices([_hover.id], graph, extent) : {};
|
||||
var layer = selection.selectAll('.layer-hit');
|
||||
|
||||
layer.selectAll('g.vertex.vertex-hover')
|
||||
.call(draw, _values(hovered), 'vertex-hover', graph);
|
||||
}
|
||||
|
||||
|
||||
drawVertices.drawHover = function(selection, graph, target, extent) {
|
||||
if (target === _hover) return;
|
||||
_hover = target;
|
||||
drawHover(selection, graph, extent);
|
||||
};
|
||||
// function drawHover(selection, graph, extent, follow) {
|
||||
// var hovered = _hover ? siblingAndChildVertices([_hover.id], graph, extent) : {};
|
||||
// var wireframe = context.surface().classed('fill-wireframe');
|
||||
// var layer = selection.selectAll('.layer-hit');
|
||||
//
|
||||
// layer.selectAll('g.vertex.vertex-hover')
|
||||
// .call(draw, _values(hovered), 'vertex-hover', graph, {}, false);
|
||||
// }
|
||||
//
|
||||
//
|
||||
// drawVertices.drawHover = function(selection, graph, target, extent) {
|
||||
// if (target === _hover) return;
|
||||
// _hover = target;
|
||||
// drawHover(selection, graph, extent);
|
||||
// };
|
||||
|
||||
return drawVertices;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user