From cd3129061c5f08b7fd22e6771aff0a03bc2d31f2 Mon Sep 17 00:00:00 2001 From: Tom MacWright Date: Thu, 6 Dec 2012 17:33:02 -0500 Subject: [PATCH] Refactor dragging, include latedrag --- index.html | 1 + js/id/modes/browse.js | 34 ++++++++++++++++++++++++++++++ js/id/modes/select.js | 4 +++- js/id/renderer/map.js | 48 ++++++++----------------------------------- js/lib/d3.latedrag.js | 22 ++++++++++++++++++++ 5 files changed, 69 insertions(+), 40 deletions(-) create mode 100644 js/lib/d3.latedrag.js diff --git a/index.html b/index.html index 38a17504b..9cf8c269f 100644 --- a/index.html +++ b/index.html @@ -20,6 +20,7 @@ + diff --git a/js/id/modes/browse.js b/js/id/modes/browse.js index 0e6789f77..01eae38c9 100644 --- a/js/id/modes/browse.js +++ b/js/id/modes/browse.js @@ -6,7 +6,41 @@ iD.modes.Browse = function() { description: 'Pan and zoom the map' }; + var dragging; + + var dragbehavior = d3.behavior.drag() + .origin(function(entity) { + var p = mode.map.projection(entity.loc); + return { x: p[0], y: p[1] }; + }) + .on('drag', function(entity) { + d3.event.sourceEvent.stopPropagation(); + if (!dragging) { + if (entity.accuracy) { + var way = history.graph().entity(entity.way), + index = entity.index; + entity = iD.Node(entity); + mode.history.perform(iD.actions.AddWayNode(way, entity, index)); + } + dragging = iD.util.trueObj([entity.id].concat( + _.pluck(mode.history.graph().parentWays(entity.id), 'id'))); + mode.history.perform(iD.actions.Noop()); + } + var to = mode.map.projection.invert([d3.event.x, d3.event.y]); + mode.history.replace(iD.actions.Move(entity, to)); + }) + .on('dragend', function () { + if (!dragging) return; + dragging = undefined; + }); + mode.enter = function() { + mode.map.surface + .call(dragbehavior) + .call(d3.latedrag() + .filter(function(d) { + return d.type === 'node'; + })); mode.map.surface.on('click.browse', function () { var datum = d3.select(d3.event.target).datum(); if (datum instanceof iD.Entity) { diff --git a/js/id/modes/select.js b/js/id/modes/select.js index fe18dba6d..d4ad71c74 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -23,7 +23,9 @@ iD.modes.Select = function (entity) { entity.nodes.forEach(function(node) { var start = mode.map.projection(node.loc); - var end = mode.map.projection.invert([start[0] + d3.event.dx, start[1] + d3.event.dy]); + var end = mode.map.projection.invert([ + start[0] + d3.event.dx, + start[1] + d3.event.dy]); node.loc = end; mode.history.replace(iD.actions.Move(node, end)); }); diff --git a/js/id/renderer/map.js b/js/id/renderer/map.js index 4e678aefa..545c5db89 100644 --- a/js/id/renderer/map.js +++ b/js/id/renderer/map.js @@ -13,37 +13,8 @@ iD.Map = function() { .on('zoom', zoomPan), dblclickEnabled = true, dragEnabled = true, + dragging = false, fastEnabled = true, - dragging, - dragbehavior = d3.behavior.drag() - .origin(function(entity) { - if (!dragEnabled) return { x: 0, y: 0 }; - var p = projection(entity.loc); - return { x: p[0], y: p[1] }; - }) - .on('drag', function(entity) { - d3.event.sourceEvent.stopPropagation(); - - if (!dragging) { - if (entity.accuracy) { - var way = history.graph().entity(entity.way), - index = entity.index; - entity = iD.Node(entity); - history.perform(iD.actions.AddWayNode(way, entity, index)); - } - - dragging = iD.util.trueObj([entity.id].concat( - _.pluck(history.graph().parentWays(entity.id), 'id'))); - history.perform(iD.actions.Noop()); - } - - var to = projection.invert([d3.event.x, d3.event.y]); - history.replace(iD.actions.Move(entity, to)); - }) - .on('dragend', function () { - if (!dragEnabled || !dragging) return; - dragging = undefined; - }), background = iD.Background() .projection(projection), class_stroke = iD.Style.styleClasses('stroke'), @@ -90,7 +61,7 @@ iD.Map = function() { .attr('clip-path', 'url(#clip)'); g = ['fill', 'casing', 'stroke', 'text', 'hit', 'temp'].reduce(function(mem, i) { - return (mem[i] = r.append('g').attr('class', 'layer-g')) && mem; + return (mem[i] = r.append('g').attr('class', 'layer-g layer-' + i)) && mem; }, {}); var arrow = surface.append('text').text('►----'); @@ -175,10 +146,11 @@ iD.Map = function() { } handles.exit().remove(); handles.enter().append('image') - .attr({ width: 6, height: 6, 'class': 'handle', 'xlink:href': 'css/handle.png' }) - .each(function(d) { - if (d.tags && d.tags.elastic) return; - d3.select(this).call(dragbehavior); + .attr({ + width: 6, + height: 6, + 'class': 'handle', + 'xlink:href': 'css/handle.png' }); handles.attr('transform', function(entity) { var p = projection(entity.loc); @@ -193,8 +165,7 @@ iD.Map = function() { .data(waynodes, key); handles.exit().remove(); handles.enter().append('circle') - .attr({ r: 2, 'class': 'accuracy-handle' }) - .call(dragbehavior); + .attr({ r: 2, 'class': 'accuracy-handle' }); handles.attr('transform', function(entity) { var p = projection(entity.loc); return 'translate(' + [~~p[0], ~~p[1]] + ')'; @@ -236,8 +207,7 @@ iD.Map = function() { .data(points, key); markers.exit().remove(); var marker = markers.enter().append('g') - .attr('class', 'marker') - .call(dragbehavior); + .attr('class', 'marker'); marker.append('circle') .attr({ r: 10, cx: 8, cy: 8 }); marker.append('image') diff --git a/js/lib/d3.latedrag.js b/js/lib/d3.latedrag.js new file mode 100644 index 000000000..06970bca1 --- /dev/null +++ b/js/lib/d3.latedrag.js @@ -0,0 +1,22 @@ +d3.latedrag = function() { + var filter = d3.functor(true); + + function latedrag(selection) { + var mousedown = selection.on('mousedown.drag'); + selection.on('mousedown.drag', null); + selection.on('mousedown.latedrag', function() { + var datum = d3.select(d3.event.target).datum(); + if (datum && filter(datum)) { + mousedown.apply(d3.event.target, [datum]); + } + }); + } + + latedrag.filter = function(_) { + if (!arguments.length) return filter; + filter = _; + return latedrag; + }; + + return latedrag; +};