More work on vertex drawing, add debug for touch targets

This commit is contained in:
Bryan Housel
2017-12-15 00:26:37 -05:00
parent b9e48d1682
commit ba5b3eee9c
5 changed files with 131 additions and 106 deletions

View File

@@ -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;

View File

@@ -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;
};

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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;