mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
More work on vertex drawing, add debug for touch targets
This commit is contained in:
@@ -11,9 +11,10 @@ use { pointer-events: none; }
|
||||
#turn-no-shape2, #turn-no-u-shape2 { fill: #E06D5F; } /* FF turn-no, turn-no-u */
|
||||
#turn-yes-shape2, #turn-yes-u-shape2 { fill: #8CD05F; } /* FF turn-yes, turn-yes-u */
|
||||
|
||||
g.point .shadow,
|
||||
g.vertex .shadow,
|
||||
g.midpoint .shadow {
|
||||
.layer-points-group * {
|
||||
pointer-events: none;
|
||||
}
|
||||
.layer-points-group.layer-points-targets * {
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
@@ -45,11 +46,11 @@ g.point.selected .shadow {
|
||||
stroke-opacity: 0.7;
|
||||
}
|
||||
|
||||
g.vertex.active, g.vertex.active *,
|
||||
/*g.vertex.active, g.vertex.active *,
|
||||
g.point.active, g.point.active * {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
*/
|
||||
g.point ellipse.stroke {
|
||||
display: none;
|
||||
}
|
||||
@@ -89,10 +90,10 @@ g.midpoint .shadow {
|
||||
fill-opacity: 0;
|
||||
}
|
||||
|
||||
/*debug*/
|
||||
.vertex.target {
|
||||
fill: #f00;
|
||||
fill-opacity: 0.5;
|
||||
.target {
|
||||
color: rgba(0,0,0,0);
|
||||
fill-opacity: 0.8;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
/*g.vertex.vertex-hover {
|
||||
@@ -120,7 +121,7 @@ g.midpoint .shadow {
|
||||
*/
|
||||
|
||||
g.vertex.related:not(.selected) .shadow,
|
||||
/*g.vertex.hover:not(.selected) .shadow,*/
|
||||
g.vertex.hover:not(.selected) .shadow,
|
||||
g.midpoint.related:not(.selected) .shadow,
|
||||
g.midpoint.hover:not(.selected) .shadow {
|
||||
fill-opacity: 0.5;
|
||||
|
||||
@@ -20,16 +20,16 @@ import { utilRebind } from '../util/rebind';
|
||||
have the .hover class.
|
||||
*/
|
||||
export function behaviorHover(context) {
|
||||
var dispatch = d3_dispatch('hover'),
|
||||
_selection = d3_select(null),
|
||||
newId = null,
|
||||
buttonDown,
|
||||
altDisables,
|
||||
target;
|
||||
var dispatch = d3_dispatch('hover');
|
||||
var _selection = d3_select(null);
|
||||
var _newId = null;
|
||||
var _buttonDown;
|
||||
var _altDisables;
|
||||
var _target;
|
||||
|
||||
|
||||
function keydown() {
|
||||
if (altDisables && d3_event.keyCode === d3_keybinding.modifierCodes.alt) {
|
||||
if (_altDisables && d3_event.keyCode === d3_keybinding.modifierCodes.alt) {
|
||||
_selection.selectAll('.hover')
|
||||
.classed('hover-suppressed', true)
|
||||
.classed('hover', false);
|
||||
@@ -43,7 +43,7 @@ export function behaviorHover(context) {
|
||||
|
||||
|
||||
function keyup() {
|
||||
if (altDisables && d3_event.keyCode === d3_keybinding.modifierCodes.alt) {
|
||||
if (_altDisables && d3_event.keyCode === d3_keybinding.modifierCodes.alt) {
|
||||
_selection.selectAll('.hover-suppressed')
|
||||
.classed('hover-suppressed', false)
|
||||
.classed('hover', true);
|
||||
@@ -51,14 +51,14 @@ export function behaviorHover(context) {
|
||||
_selection
|
||||
.classed('hover-disabled', false);
|
||||
|
||||
dispatch.call('hover', this, target ? target.id : null);
|
||||
dispatch.call('hover', this, _target ? _target.id : null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var hover = function(selection) {
|
||||
_selection = selection;
|
||||
newId = null;
|
||||
_newId = null;
|
||||
|
||||
_selection
|
||||
.on('mouseover.hover', mouseover)
|
||||
@@ -71,65 +71,65 @@ export function behaviorHover(context) {
|
||||
|
||||
|
||||
function mouseover() {
|
||||
if (buttonDown) return;
|
||||
var target = d3_event.target;
|
||||
enter(target ? target.__data__ : null);
|
||||
if (_buttonDown) return;
|
||||
var _target = d3_event.target;
|
||||
enter(_target ? _target.__data__ : null);
|
||||
}
|
||||
|
||||
|
||||
function mouseout() {
|
||||
if (buttonDown) return;
|
||||
var target = d3_event.relatedTarget;
|
||||
enter(target ? target.__data__ : null);
|
||||
if (_buttonDown) return;
|
||||
var _target = d3_event.relatedTarget;
|
||||
enter(_target ? _target.__data__ : null);
|
||||
}
|
||||
|
||||
|
||||
function mousedown() {
|
||||
buttonDown = true;
|
||||
_buttonDown = true;
|
||||
d3_select(window)
|
||||
.on('mouseup.hover', mouseup, true);
|
||||
}
|
||||
|
||||
|
||||
function mouseup() {
|
||||
buttonDown = false;
|
||||
_buttonDown = false;
|
||||
d3_select(window)
|
||||
.on('mouseup.hover', null, true);
|
||||
}
|
||||
|
||||
|
||||
function enter(d) {
|
||||
if (d === target) return;
|
||||
target = d;
|
||||
if (d === _target) return;
|
||||
_target = d;
|
||||
|
||||
_selection.selectAll('.hover')
|
||||
.classed('hover', false);
|
||||
_selection.selectAll('.hover-suppressed')
|
||||
.classed('hover-suppressed', false);
|
||||
|
||||
if (target instanceof osmEntity && target.id !== newId) {
|
||||
if (_target instanceof osmEntity && _target.id !== _newId) {
|
||||
|
||||
// If drawing a way, don't hover on a node that was just placed. #3974
|
||||
var mode = context.mode() && context.mode().id;
|
||||
if ((mode === 'draw-line' || mode === 'draw-area') && !newId && target.type === 'node') {
|
||||
newId = target.id;
|
||||
if ((mode === 'draw-line' || mode === 'draw-area') && !_newId && _target.type === 'node') {
|
||||
_newId = _target.id;
|
||||
return;
|
||||
}
|
||||
|
||||
var selector = '.' + target.id;
|
||||
var selector = '.' + _target.id;
|
||||
|
||||
if (target.type === 'relation') {
|
||||
target.members.forEach(function(member) {
|
||||
if (_target.type === 'relation') {
|
||||
_target.members.forEach(function(member) {
|
||||
selector += ', .' + member.id;
|
||||
});
|
||||
}
|
||||
|
||||
var suppressed = altDisables && d3_event && d3_event.altKey;
|
||||
var suppressed = _altDisables && d3_event && d3_event.altKey;
|
||||
|
||||
_selection.selectAll(selector)
|
||||
.classed(suppressed ? 'hover-suppressed' : 'hover', true);
|
||||
|
||||
dispatch.call('hover', this, !suppressed && target.id);
|
||||
dispatch.call('hover', this, !suppressed && _target.id);
|
||||
|
||||
} else {
|
||||
dispatch.call('hover', this, null);
|
||||
@@ -147,7 +147,6 @@ export function behaviorHover(context) {
|
||||
selection
|
||||
.classed('hover-disabled', false);
|
||||
|
||||
|
||||
selection
|
||||
.on('mouseover.hover', null)
|
||||
.on('mouseout.hover', null)
|
||||
@@ -160,8 +159,8 @@ export function behaviorHover(context) {
|
||||
|
||||
|
||||
hover.altDisables = function(_) {
|
||||
if (!arguments.length) return altDisables;
|
||||
altDisables = _;
|
||||
if (!arguments.length) return _altDisables;
|
||||
_altDisables = _;
|
||||
return hover;
|
||||
};
|
||||
|
||||
|
||||
@@ -310,11 +310,12 @@ export function coreContext() {
|
||||
|
||||
/* Debug */
|
||||
var debugFlags = {
|
||||
tile: false,
|
||||
collision: false,
|
||||
imagery: false,
|
||||
imperial: false,
|
||||
driveLeft: false
|
||||
tile: false, // tile boundaries
|
||||
collision: false, // label collision bounding boxes
|
||||
imagery: false, // imagery bounding polygons
|
||||
imperial: false, // imperial (not metric) bounding polygons
|
||||
driveLeft: false, // driveLeft bounding polygons
|
||||
target: false // touch targets
|
||||
};
|
||||
context.debugFlags = function() {
|
||||
return debugFlags;
|
||||
|
||||
@@ -21,12 +21,13 @@ export function svgDebug(projection, context) {
|
||||
}
|
||||
|
||||
function drawDebug(selection) {
|
||||
var showsTile = context.getDebug('tile'),
|
||||
showsCollision = context.getDebug('collision'),
|
||||
showsImagery = context.getDebug('imagery'),
|
||||
showsImperial = context.getDebug('imperial'),
|
||||
showsDriveLeft = context.getDebug('driveLeft'),
|
||||
path = d3_geoPath(projection);
|
||||
var showsTile = context.getDebug('tile');
|
||||
var showsCollision = context.getDebug('collision');
|
||||
var showsImagery = context.getDebug('imagery');
|
||||
var showsImperial = context.getDebug('imperial');
|
||||
var showsDriveLeft = context.getDebug('driveLeft');
|
||||
var showsTouchTargets = context.getDebug('target');
|
||||
var path = d3_geoPath(projection);
|
||||
|
||||
|
||||
var debugData = [];
|
||||
@@ -45,6 +46,9 @@ export function svgDebug(projection, context) {
|
||||
if (showsDriveLeft) {
|
||||
debugData.push({ class: 'green', label: 'driveLeft' });
|
||||
}
|
||||
if (showsTouchTargets) {
|
||||
debugData.push({ class: 'pink', label: 'touchTargets' });
|
||||
}
|
||||
|
||||
|
||||
var legend = d3_select('#content')
|
||||
@@ -84,14 +88,14 @@ export function svgDebug(projection, context) {
|
||||
.merge(layer);
|
||||
|
||||
|
||||
var extent = context.map().extent(),
|
||||
dataImagery = data.imagery || [],
|
||||
availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) {
|
||||
if (!source.polygon) return false;
|
||||
return source.polygon.some(function(polygon) {
|
||||
return geoPolygonIntersectsPolygon(polygon, extent, true);
|
||||
});
|
||||
}));
|
||||
var extent = context.map().extent();
|
||||
var dataImagery = data.imagery || [];
|
||||
var availableImagery = showsImagery && multipolygons(dataImagery.filter(function(source) {
|
||||
if (!source.polygon) return false;
|
||||
return source.polygon.some(function(polygon) {
|
||||
return geoPolygonIntersectsPolygon(polygon, extent, true);
|
||||
});
|
||||
}));
|
||||
|
||||
var imagery = layer.selectAll('path.debug-imagery')
|
||||
.data(showsImagery ? availableImagery : []);
|
||||
@@ -142,7 +146,8 @@ export function svgDebug(projection, context) {
|
||||
context.getDebug('collision') ||
|
||||
context.getDebug('imagery') ||
|
||||
context.getDebug('imperial') ||
|
||||
context.getDebug('driveLeft');
|
||||
context.getDebug('driveLeft') ||
|
||||
context.getDebug('target');
|
||||
} else {
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import _assign from 'lodash-es/assign';
|
||||
import _clone from 'lodash-es/clone';
|
||||
import _values from 'lodash-es/values';
|
||||
|
||||
@@ -20,10 +21,11 @@ export function svgVertices(projection, context) {
|
||||
fill: [1, 1.5, 1.5, 1.5]
|
||||
};
|
||||
|
||||
var _hover;
|
||||
var _currHover;
|
||||
var _currHoverSiblings = {};
|
||||
|
||||
|
||||
function draw(selection, vertices, klass, graph, siblings, filter) {
|
||||
function draw(selection, graph, vertices, klass, siblings, filter) {
|
||||
siblings = siblings || {};
|
||||
var icons = {};
|
||||
var directions = {};
|
||||
@@ -169,43 +171,9 @@ export function svgVertices(projection, context) {
|
||||
}
|
||||
|
||||
|
||||
function drawVertices(selection, graph, entities, filter, extent) {
|
||||
var wireframe = context.surface().classed('fill-wireframe');
|
||||
var zoom = ktoz(projection.scale());
|
||||
var siblings = getSiblingAndChildVertices(context.selectedIDs(), graph, extent, wireframe, zoom);
|
||||
|
||||
// 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') && renderAsVertex(entity, graph, wireframe, zoom)) {
|
||||
vertices[entity.id] = entity;
|
||||
|
||||
} else if ((geometry === 'vertex') &&
|
||||
(entity.hasInterestingTags() || entity.isEndpoint(graph) || entity.isConnected(graph)) ) {
|
||||
vertices[entity.id] = entity;
|
||||
}
|
||||
}
|
||||
|
||||
selection.selectAll('.layer-points .layer-points-vertices')
|
||||
.call(draw, _values(vertices), 'vertex-persistent', graph, siblings, filterWithSiblings);
|
||||
|
||||
drawTargets(selection, graph, _values(vertices), filter, extent);
|
||||
|
||||
}
|
||||
|
||||
|
||||
function drawTargets(selection, graph, entities, filter, extent) {
|
||||
// todo coming soon
|
||||
return;
|
||||
var layer = selection.selectAll('.layer-points .layer-points-targets');
|
||||
|
||||
var targets = layer.selectAll('g.vertex.target')
|
||||
function drawTargets(selection, graph, entities, filter) {
|
||||
var debugClass = 'pink';
|
||||
var targets = selection.selectAll('.target')
|
||||
.data(entities, osmEntity.key);
|
||||
|
||||
// exit
|
||||
@@ -218,7 +186,8 @@ return;
|
||||
.attr('r', radiuses.shadow[3]) // just use the biggest one for now
|
||||
.attr('class', function(d) { return 'node vertex target ' + d.id; })
|
||||
.merge(targets)
|
||||
.attr('transform', svgPointTransform(projection));
|
||||
.attr('transform', svgPointTransform(projection))
|
||||
.classed(debugClass, context.getDebug('target'));
|
||||
}
|
||||
|
||||
|
||||
@@ -280,16 +249,66 @@ return;
|
||||
}
|
||||
|
||||
|
||||
function drawVertices(selection, graph, entities, filter, extent) {
|
||||
var wireframe = context.surface().classed('fill-wireframe');
|
||||
var zoom = ktoz(projection.scale());
|
||||
|
||||
var selected = getSiblingAndChildVertices(context.selectedIDs(), graph, extent, wireframe, zoom);
|
||||
|
||||
// interesting vertices from the `entities` list..
|
||||
var interesting = {};
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var entity = entities[i];
|
||||
var geometry = entity.geometry(graph);
|
||||
|
||||
if ((geometry === 'point') && renderAsVertex(entity, graph, wireframe, zoom)) {
|
||||
interesting[entity.id] = entity;
|
||||
|
||||
} else if ((geometry === 'vertex') &&
|
||||
(entity.hasInterestingTags() || entity.isEndpoint(graph) || entity.isConnected(graph)) ) {
|
||||
interesting[entity.id] = entity;
|
||||
}
|
||||
}
|
||||
|
||||
// 3 sets of vertices to consider
|
||||
// - selected + siblings
|
||||
// - hovered + siblings
|
||||
// - interesting entities passed in
|
||||
var all = _assign(selected, interesting, _currHoverSiblings);
|
||||
|
||||
var filterWithSiblings = function(d) {
|
||||
return d.id in selected || d.id in _currHoverSiblings || filter(d);
|
||||
};
|
||||
selection.selectAll('.layer-points .layer-points-vertices')
|
||||
.call(draw, graph, _values(all), 'vertex-persistent', {}, filterWithSiblings);
|
||||
|
||||
|
||||
// draw touch targets for the hovered items only
|
||||
var filterWithHover = function(d) {
|
||||
return d.id in _currHoverSiblings || filter(d);
|
||||
};
|
||||
selection.selectAll('.layer-points .layer-points-targets')
|
||||
.call(drawTargets, graph, _values(_currHoverSiblings), filterWithHover);
|
||||
}
|
||||
|
||||
|
||||
drawVertices.drawHover = function(selection, graph, target, extent) {
|
||||
if (target === _hover) return;
|
||||
_hover = target;
|
||||
if (target === _currHover) return;
|
||||
|
||||
var wireframe = context.surface().classed('fill-wireframe');
|
||||
var zoom = ktoz(projection.scale());
|
||||
var hovered = _hover ? getSiblingAndChildVertices([_hover.id], graph, extent, wireframe, zoom) : {};
|
||||
var filter = function() { return true; };
|
||||
var prevHoverSiblings = _currHoverSiblings || {};
|
||||
var filter = function(d) { return d.id in prevHoverSiblings; };
|
||||
|
||||
drawTargets(selection, graph, _values(hovered), filter, extent);
|
||||
_currHover = target;
|
||||
|
||||
if (_currHover) {
|
||||
_currHoverSiblings = getSiblingAndChildVertices([_currHover.id], graph, extent, wireframe, zoom);
|
||||
} else {
|
||||
_currHoverSiblings = {};
|
||||
}
|
||||
|
||||
drawVertices(selection, graph, _values(prevHoverSiblings), filter, extent);
|
||||
};
|
||||
|
||||
return drawVertices;
|
||||
|
||||
Reference in New Issue
Block a user