mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-12 16:52:50 +00:00
Add touch targets for line/area
This commit is contained in:
@@ -14,17 +14,24 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Line/Area shadows and point/vertex targets are interactive */
|
||||
/* `.target` objects are interactive */
|
||||
/* They can be picked up, clicked, hovered, or things can connect to them */
|
||||
.layer-areas path.shadow,
|
||||
.layer-lines path.shadow {
|
||||
pointer-events: stroke;
|
||||
}
|
||||
.layer-points-targets * {
|
||||
pointer-events: all;
|
||||
.node.target {
|
||||
pointer-events: fill;
|
||||
fill-opacity: 0.8;
|
||||
fill: currentColor;
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
/* .active objects (currently being drawn or dragged) are not interactive */
|
||||
.way.target {
|
||||
pointer-events: stroke;
|
||||
fill: none;
|
||||
stroke-width: 10;
|
||||
stroke-opacity: 0.8;
|
||||
stroke: currentColor;
|
||||
}
|
||||
|
||||
/* `.active` objects (currently being drawn or dragged) are not interactive */
|
||||
/* This is important to allow the events to drop through to whatever is */
|
||||
/* below them on the map, so you can still hover and connect to other things. */
|
||||
.layer-osm .active {
|
||||
@@ -95,12 +102,6 @@ g.midpoint .shadow {
|
||||
fill-opacity: 0;
|
||||
}
|
||||
|
||||
.target {
|
||||
color: rgba(0,0,0,0);
|
||||
fill-opacity: 0.8;
|
||||
fill: currentColor;
|
||||
}
|
||||
|
||||
g.vertex.related:not(.selected) .shadow,
|
||||
g.vertex.hover:not(.selected) .shadow,
|
||||
g.midpoint.related:not(.selected) .shadow,
|
||||
|
||||
@@ -33,4 +33,5 @@
|
||||
.fill-partial path.area.fill {
|
||||
fill-opacity: 0;
|
||||
stroke-width: 60px;
|
||||
pointer-events: visibleStroke;
|
||||
}
|
||||
|
||||
@@ -2864,6 +2864,7 @@ img.tile-removing {
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
||||
.nocolor { color: rgba(0, 0, 0, 0); }
|
||||
.red { color: rgba(255, 0, 0, 0.75); }
|
||||
.green { color: rgba(0, 255, 0, 0.75); }
|
||||
.blue { color: rgba(0, 0, 255, 0.75); }
|
||||
|
||||
@@ -116,6 +116,9 @@ export function behaviorDraw(context) {
|
||||
|
||||
function click() {
|
||||
var d = datum();
|
||||
|
||||
// Try to snap..
|
||||
// See also: `modes/drag_node.js doMove()`
|
||||
if (d.type === 'way') {
|
||||
var dims = context.map().dimensions();
|
||||
var mouse = context.mouse();
|
||||
|
||||
@@ -131,8 +131,8 @@ export function modeDragNode(context) {
|
||||
|
||||
_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.
|
||||
// `.active` elements have `pointer-events: none`.
|
||||
// This prevents the node or vertex being dragged from trying to connect to itself.
|
||||
_activeIDs = context.graph().parentWays(entity)
|
||||
.map(function(parent) { return parent.id; });
|
||||
_activeIDs.push(entity.id);
|
||||
@@ -158,17 +158,25 @@ export function modeDragNode(context) {
|
||||
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) {
|
||||
// try to snap
|
||||
// If we're not nudging at the edge of the viewport, try to snap..
|
||||
// See also `behavior/draw.js click()`
|
||||
var d = datum();
|
||||
|
||||
// Snap to a node (not self)
|
||||
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; });
|
||||
if (childIDs.indexOf(entity.id) === -1) {
|
||||
loc = geoChooseEdge(childNodes, context.mouse(), context.projection).loc;
|
||||
|
||||
// var childNodes = context.childNodes(d);
|
||||
// var childIDs = childNodes.map(function(node) { return node.id; });
|
||||
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]) {
|
||||
loc = choice.loc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,29 @@ export function svgAreas(projection, context) {
|
||||
}
|
||||
|
||||
|
||||
return function drawAreas(selection, graph, entities, filter) {
|
||||
function drawTargets(selection, graph, entities, filter) {
|
||||
var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
|
||||
var getPath = svgPath(projection, graph);
|
||||
|
||||
var targets = selection.selectAll('.area.target')
|
||||
.filter(filter)
|
||||
.data(entities, function key(d) { return d.id; });
|
||||
|
||||
// exit
|
||||
targets.exit()
|
||||
.remove();
|
||||
|
||||
// enter/update
|
||||
targets.enter()
|
||||
.append('path')
|
||||
.merge(targets)
|
||||
.attr('d', getPath)
|
||||
.attr('class', function(d) { return 'way area target ' + fillClass + d.id; });
|
||||
}
|
||||
|
||||
|
||||
|
||||
function drawAreas(selection, graph, entities, filter) {
|
||||
var path = svgPath(projection, graph, true),
|
||||
areas = {},
|
||||
multipolygon;
|
||||
@@ -99,7 +121,7 @@ export function svgAreas(projection, context) {
|
||||
.attr('d', path);
|
||||
|
||||
|
||||
var layer = selection.selectAll('.layer-areas');
|
||||
var layer = selection.selectAll('.layer-areas .layer-areas-areas');
|
||||
|
||||
var areagroup = layer
|
||||
.selectAll('g.areagroup')
|
||||
@@ -145,5 +167,12 @@ export function svgAreas(projection, context) {
|
||||
})
|
||||
.call(svgTagClasses())
|
||||
.attr('d', path);
|
||||
};
|
||||
|
||||
|
||||
// touch targets
|
||||
selection.selectAll('.layer-areas .layer-areas-targets')
|
||||
.call(drawTargets, graph, data.stroke, filter);
|
||||
}
|
||||
|
||||
return drawAreas;
|
||||
}
|
||||
|
||||
@@ -36,13 +36,33 @@ export function svgLines(projection, context) {
|
||||
};
|
||||
|
||||
|
||||
function drawTargets(selection, graph, entities, filter) {
|
||||
var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
|
||||
var getPath = svgPath(projection, graph);
|
||||
|
||||
var targets = selection.selectAll('.line.target')
|
||||
.filter(filter)
|
||||
.data(entities, function key(d) { return d.id; });
|
||||
|
||||
// exit
|
||||
targets.exit()
|
||||
.remove();
|
||||
|
||||
// enter/update
|
||||
targets.enter()
|
||||
.append('path')
|
||||
.merge(targets)
|
||||
.attr('d', getPath)
|
||||
.attr('class', function(d) { return 'way line target ' + fillClass + d.id; });
|
||||
}
|
||||
|
||||
|
||||
function drawLines(selection, graph, entities, filter) {
|
||||
|
||||
|
||||
function waystack(a, b) {
|
||||
var selected = context.selectedIDs(),
|
||||
scoreA = selected.indexOf(a.id) !== -1 ? 20 : 0,
|
||||
scoreB = selected.indexOf(b.id) !== -1 ? 20 : 0;
|
||||
var selected = context.selectedIDs();
|
||||
var scoreA = selected.indexOf(a.id) !== -1 ? 20 : 0;
|
||||
var scoreB = selected.indexOf(b.id) !== -1 ? 20 : 0;
|
||||
|
||||
if (a.tags.highway) { scoreA -= highway_stack[a.tags.highway]; }
|
||||
if (b.tags.highway) { scoreB -= highway_stack[b.tags.highway]; }
|
||||
@@ -91,15 +111,15 @@ export function svgLines(projection, context) {
|
||||
}
|
||||
|
||||
|
||||
var getPath = svgPath(projection, graph),
|
||||
ways = [],
|
||||
pathdata = {},
|
||||
onewaydata = {},
|
||||
oldMultiPolygonOuters = {};
|
||||
var getPath = svgPath(projection, graph);
|
||||
var ways = [];
|
||||
var pathdata = {};
|
||||
var onewaydata = {};
|
||||
var oldMultiPolygonOuters = {};
|
||||
|
||||
for (var i = 0; i < entities.length; i++) {
|
||||
var entity = entities[i],
|
||||
outer = osmSimpleMultipolygonOuterMember(entity, graph);
|
||||
var entity = entities[i];
|
||||
var outer = osmSimpleMultipolygonOuterMember(entity, graph);
|
||||
if (outer) {
|
||||
ways.push(entity.mergeTags(outer.tags));
|
||||
oldMultiPolygonOuters[outer.id] = true;
|
||||
@@ -117,7 +137,7 @@ export function svgLines(projection, context) {
|
||||
});
|
||||
|
||||
|
||||
var layer = selection.selectAll('.layer-lines');
|
||||
var layer = selection.selectAll('.layer-lines .layer-lines-lines');
|
||||
|
||||
var layergroup = layer
|
||||
.selectAll('g.layergroup')
|
||||
@@ -164,8 +184,8 @@ export function svgLines(projection, context) {
|
||||
.selectAll('path')
|
||||
.filter(filter)
|
||||
.data(
|
||||
function() { return onewaydata[this.parentNode.__data__] || []; },
|
||||
function(d) { return [d.id, d.index]; }
|
||||
function data() { return onewaydata[this.parentNode.__data__] || []; },
|
||||
function key(d) { return [d.id, d.index]; }
|
||||
);
|
||||
|
||||
oneways.exit()
|
||||
@@ -181,6 +201,11 @@ export function svgLines(projection, context) {
|
||||
if (detected.ie) {
|
||||
oneways.each(function() { this.parentNode.insertBefore(this, this); });
|
||||
}
|
||||
|
||||
|
||||
// touch targets
|
||||
selection.selectAll('.layer-lines .layer-lines-targets')
|
||||
.call(drawTargets, graph, ways, filter);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ export function svgMidpoints(projection, context) {
|
||||
|
||||
|
||||
function drawTargets(selection, graph, entities, filter) {
|
||||
var debugClass = 'pink';
|
||||
var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
|
||||
var targets = selection.selectAll('.midpoint.target')
|
||||
.filter(filter)
|
||||
.data(entities, function key(d) { return d.id; });
|
||||
@@ -30,10 +30,9 @@ export function svgMidpoints(projection, context) {
|
||||
targets.enter()
|
||||
.append('circle')
|
||||
.attr('r', 12)
|
||||
.attr('class', function(d) { return 'midpoint target ' + d.id; })
|
||||
.merge(targets)
|
||||
.attr('transform', svgPointTransform(projection))
|
||||
.classed(debugClass, context.getDebug('target'));
|
||||
.attr('class', function(d) { return 'node midpoint target ' + fillClass + d.id; })
|
||||
.attr('transform', svgPointTransform(projection));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,6 +9,18 @@ export function svgOsm(projection, context, dispatch) {
|
||||
.append('g')
|
||||
.attr('class', function(d) { return 'layer-osm layer-' + d; });
|
||||
|
||||
selection.selectAll('.layer-areas').selectAll('.layer-areas-group')
|
||||
.data(['areas', 'targets'])
|
||||
.enter()
|
||||
.append('g')
|
||||
.attr('class', function(d) { return 'layer-areas-group layer-areas-' + d; });
|
||||
|
||||
selection.selectAll('.layer-lines').selectAll('.layer-lines-group')
|
||||
.data(['lines', 'targets'])
|
||||
.enter()
|
||||
.append('g')
|
||||
.attr('class', function(d) { return 'layer-lines-group layer-lines-' + d; });
|
||||
|
||||
selection.selectAll('.layer-points').selectAll('.layer-points-group')
|
||||
.data(['points', 'midpoints', 'vertices', 'turns', 'targets'])
|
||||
.enter()
|
||||
|
||||
@@ -22,7 +22,7 @@ export function svgPoints(projection, context) {
|
||||
|
||||
|
||||
function drawTargets(selection, graph, entities, filter) {
|
||||
var debugClass = 'pink';
|
||||
var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
|
||||
var targets = selection.selectAll('.point.target')
|
||||
.filter(filter)
|
||||
.data(entities, function key(d) { return d.id; });
|
||||
@@ -34,14 +34,13 @@ export function svgPoints(projection, context) {
|
||||
// enter/update
|
||||
targets.enter()
|
||||
.append('rect')
|
||||
.attr('x', -15)
|
||||
.attr('y', -30)
|
||||
.attr('width', 30)
|
||||
.attr('height', 36)
|
||||
.attr('class', function(d) { return 'node point target ' + d.id; })
|
||||
.attr('x', -10)
|
||||
.attr('y', -26)
|
||||
.attr('width', 20)
|
||||
.attr('height', 30)
|
||||
.merge(targets)
|
||||
.attr('transform', svgPointTransform(projection))
|
||||
.classed(debugClass, context.getDebug('target'));
|
||||
.attr('class', function(d) { return 'node point target ' + fillClass + d.id; })
|
||||
.attr('transform', svgPointTransform(projection));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -171,7 +171,7 @@ export function svgVertices(projection, context) {
|
||||
|
||||
|
||||
function drawTargets(selection, graph, entities, filter) {
|
||||
var debugClass = 'pink';
|
||||
var fillClass = context.getDebug('target') ? 'pink ' : 'nocolor ';
|
||||
var targets = selection.selectAll('.vertex.target')
|
||||
.filter(filter)
|
||||
.data(entities, function key(d) { return d.id; });
|
||||
@@ -184,10 +184,9 @@ export function svgVertices(projection, context) {
|
||||
targets.enter()
|
||||
.append('circle')
|
||||
.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))
|
||||
.classed(debugClass, context.getDebug('target'));
|
||||
.attr('class', function(d) { return 'node vertex target ' + fillClass + d.id; })
|
||||
.attr('transform', svgPointTransform(projection));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user