diff --git a/css/map.css b/css/map.css index 3ae325a63..53b6bca07 100644 --- a/css/map.css +++ b/css/map.css @@ -22,7 +22,7 @@ g.marker.active circle { /* interactive elements */ circle.handle { cursor: move; - stroke-width: 3; + stroke-width: 2; fill:#000; stroke:#FFF694; } diff --git a/index.html b/index.html index 32d27cc25..3bc776320 100755 --- a/index.html +++ b/index.html @@ -38,6 +38,7 @@ + diff --git a/js/iD/actions/actions.js b/js/iD/actions/actions.js index 4a12dfb9d..e090e58ca 100644 --- a/js/iD/actions/actions.js +++ b/js/iD/actions/actions.js @@ -26,8 +26,8 @@ iD.actions.AddPlace = { .append('g').attr('id', 'addplace'); teaser.append('circle') - .attr('class', 'teaser-point') - .attr('r', 10); + .attr('class', 'handle') + .attr('r', 3); surface.on('mousemove.addplace', function() { teaser.attr('transform', function() { @@ -80,8 +80,8 @@ iD.actions.AddRoad = { .append('g').attr('id', 'addroad'); teaser.append('circle') - .attr('class', 'teaser-point') - .attr('r', 10); + .attr('class', 'handle') + .attr('r', 3); surface.on('mousemove.addroad', function() { teaser.attr('transform', function() { @@ -155,6 +155,7 @@ iD.actions.DrawRoad = function(way) { exit: function() { this.map.surface.on('mousemove.drawroad', null); this.map.surface.on('click.drawroad', null); + this.map.surface.on('dblclick.drawroad', null); d3.select(document).on('.drawroad', null); d3.selectAll('#drawroad').remove(); } @@ -162,15 +163,117 @@ iD.actions.DrawRoad = function(way) { }; iD.actions.AddArea = { + way: function(ll) { + return iD.Entity({ + type: 'way', + nodes: [], + tags: { + building: 'yes' + }, + modified: true, + id: iD.Util.id('way') + }); + }, enter: function() { d3.selectAll('button').classed('active', false); d3.selectAll('button#area').classed('active', true); + + var surface = this.map.surface; + var teaser = surface.selectAll('g#temp-g') + .append('g').attr('id', 'addroad'); + + teaser.append('circle') + .attr('class', 'handle') + .attr('r', 3); + + surface.on('mousemove.addroad', function() { + teaser.attr('transform', function() { + var off = d3.mouse(surface.node()); + return 'translate(' + off + ')'; + }); + }); + + surface.on('click.addroad', function() { + var ll = this.map.projection.invert( + d3.mouse(surface.node())); + + var way = this.way(); + var node = iD.actions._node(ll); + way.nodes.push(node.id); + + this.map.operate(iD.operations.changeWayNodes(way, node)); + this.map.selectClick(way); + this.controller.go(iD.actions.DrawArea(way)); + }.bind(this)); + + d3.select(document).on('keydown.addroad', function() { + if (d3.event.keyCode === 27) this.exit(); + }.bind(this)); }, exit: function() { + this.map.surface.on('click.addarea', null); + this.map.surface.on('mousemove.addarea', null); + d3.select(document).on('keydown.addarea', null); + d3.selectAll('#addroad').remove(); d3.selectAll('button#area').classed('active', false); } }; +iD.actions.DrawArea = function(way) { + return { + enter: function() { + var surface = this.map.surface; + + var lastNode = this.map.history.graph().entity(way.nodes[way.nodes.length - 1]); + var firstNode = this.map.history.graph().entity(way.nodes[0]); + + this.nextnode = iD.actions._node([lastNode.lon, lastNode.lat]); + + way.nodes.push(this.nextnode.id); + way.nodes.push(firstNode.id); + this.map.operate(iD.operations.changeWayNodes(way, this.nextnode)); + this.map.operate(iD.operations.changeWayNodes(way, firstNode)); + + surface.on('mousemove.drawarea', function() { + var ll = this.map.projection.invert(d3.mouse(surface.node())); + this.map.history.replace(iD.operations.move(this.nextnode, ll)); + this.map.update(); + }.bind(this)); + + surface.on('click.drawarea', function() { + d3.event.stopPropagation(); + way.nodes.pop(); + way.nodes.pop(); + var ll = this.map.projection.invert(d3.mouse(surface.node())); + var node = iD.actions._node(ll); + way.nodes.push(node.id); + this.map.operate(iD.operations.changeWayNodes(way, node)); + this.controller.go(iD.actions.DrawRoad(way)); + }.bind(this)); + + surface.on('dblclick.drawarea', function() { + d3.event.stopPropagation(); + var a = this.map.history.graph().entity(way.nodes.pop()); + var b = this.map.history.graph().entity(way.nodes.pop()); + this.map.operate(iD.operations.changeWayNodes(way, a)); + this.map.operate(iD.operations.remove(a)); + this.map.operate(iD.operations.remove(b)); + way.nodes.push(way.nodes[0]); + var closeNode = this.map.history.graph().entity(way.nodes[0]); + this.map.operate(iD.operations.changeWayNodes(way, closeNode)); + this.exit(); + }.bind(this)); + }, + exit: function() { + this.map.surface.on('mousemove.drawarea', null); + this.map.surface.on('click.drawarea', null); + this.map.surface.on('dblclick.drawarea', null); + d3.select(document).on('.drawarea', null); + d3.selectAll('#drawarea').remove(); + } + }; +}; + iD.actions.Move = { enter: function() { d3.selectAll('button').classed('active', false); diff --git a/js/iD/renderer/Map.js b/js/iD/renderer/Map.js index ff181cf54..9498fd777 100755 --- a/js/iD/renderer/Map.js +++ b/js/iD/renderer/Map.js @@ -27,6 +27,7 @@ iD.Map = function(elem) { inspector = iD.Inspector(history), parent = d3.select(elem), selection = null, + // clickCancel = clickCancelProvider(), projection = d3.geo.mercator() .scale(512).translate([512, 512]), // behaviors @@ -76,7 +77,12 @@ iD.Map = function(elem) { // The map uses SVG groups in order to restrict // visual and event ordering - fills below casings, casings below // strokes, and so on. - var surface = parent.append('svg').call(zoombehavior); + var surface = parent.append('svg') + .call(zoombehavior); + // .call(clickCancel); + + // Don't use the default double click handler. + // surface.on('dblclick.zoom', null); surface.append('defs').append('clipPath') .attr('id', 'clip') @@ -148,7 +154,8 @@ iD.Map = function(elem) { // Casings casings.exit().remove(); - casings.enter().append('path'); + casings.enter().append('path') + .on('click', selectClick); casings.order() .attr('d', function(d) { return d._line; }) .attr('class', class_casing) @@ -170,9 +177,7 @@ iD.Map = function(elem) { .on('click', selectClick) .call(dragbehavior); marker.append('circle') - .attr('r', 10) - .attr('cx', 8) - .attr('cy', 8); + .attr({ r: 10, cx: 8, cy: 8 }); marker.append('image') .attr({ width: 16, height: 16 }) .attr('xlink:href', iD.Style.markerimage); @@ -190,7 +195,7 @@ iD.Map = function(elem) { handles.exit().remove(); handles.enter().append('circle') .attr('class', 'handle') - .attr('r', 5) + .attr('r', 3) .call(dragbehavior); handles.attr('transform', function(entity) { return 'translate(' + projection(ll2a(entity)) + ')'; @@ -220,7 +225,6 @@ iD.Map = function(elem) { selection = null; drawVector(); d3.select('.inspector-wrap').style('display', 'none'); - d3.event.stopPropagation(); } function selectClick(d) { @@ -230,7 +234,6 @@ iD.Map = function(elem) { d3.select('.inspector-wrap') .style('display', 'block') .datum(d).call(inspector); - d3.event.stopPropagation(); } inspector.on('change', function(d, tags) {