From 882457a351afe45cd72344263de44f5843a3b1b3 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Thu, 17 Dec 2015 22:18:58 -0500 Subject: [PATCH] Add Breathe behavior for interpolated select halos (closes #1814) --- css/map.css | 6 --- index.html | 1 + js/id/behavior/breathe.js | 100 ++++++++++++++++++++++++++++++++++++++ js/id/modes/select.js | 1 + test/index.html | 1 + 5 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 js/id/behavior/breathe.js diff --git a/css/map.css b/css/map.css index 4a537591f..8087008e1 100644 --- a/css/map.css +++ b/css/map.css @@ -43,12 +43,6 @@ path.shadow { pointer-events: stroke; } -.shadow { - -webkit-transition: 200ms; - -moz-transition: 200ms; - transition: 200ms; -} - /* points */ g.point .stroke { diff --git a/index.html b/index.html index 42522a2bf..e51b6ef9b 100644 --- a/index.html +++ b/index.html @@ -178,6 +178,7 @@ + diff --git a/js/id/behavior/breathe.js b/js/id/behavior/breathe.js new file mode 100644 index 000000000..954b8bfa9 --- /dev/null +++ b/js/id/behavior/breathe.js @@ -0,0 +1,100 @@ +iD.behavior.Breathe = function() { + var duration = 1000, + selector = '.selected.shadow, .selected .shadow', + params = {}, + done, selection; + + function reset(selection) { + return selection + .style('fill-opacity', null) + .style('r', null) + .style('stroke-opacity', null) + .style('stroke-width', null); + } + + function reselect(surface) { + return function() { + if (done) return true; + var currSelection = surface.selectAll(selector); + if (_.isEqual(currSelection, selection)) return false; // no change + + selection = currSelection; + if (selection.empty()) return false; + + // reset styles, calculate animation params + selection + .call(reset) + .each(function calcAnimationParams(d) { + if (params.hasOwnProperty(d.id)) return; + + // determine default opacity and width + var s = d3.select(this), + tag = s.node().tagName, + p = {}, + opacity, width; + + if (tag === 'circle') { + opacity = parseFloat(s.style('fill-opacity') || 0.5); + width = parseFloat(s.style('r') || 15.5); + } else { + opacity = parseFloat(s.style('stroke-opacity') || 0.7); + width = parseFloat(s.style('stroke-width') || 10); + } + + // calculate min/max interpolation params based on defaults.. + p.tag = tag; + p.opacity0 = Math.max(opacity - 0.4, 0.1); + p.opacity1 = Math.min(opacity + 0.2, 1.0); + p.width0 = Math.max(width - (tag === 'circle' ? 1 : 2), 4); + p.width1 = width + 2; + params[d.id] = p; + }); + + inhale(); + }; + } + + function inhale() { + if (done || selection.empty()) { + selection.call(reset); + return; + } + selection + .transition() + .style('stroke-opacity', function(d) { return params[d.id].opacity1; }) + .style('stroke-width', function(d) { return params[d.id].width1; }) + .style('fill-opacity', function(d) { return params[d.id].opacity1; }) + .style('r', function(d) { return params[d.id].width1; }) + .duration(duration) + .each('end', exhale); + } + + function exhale() { + if (done || selection.empty()) { + selection.call(reset); + return; + } + selection + .transition() + .style('stroke-opacity', function(d) { return params[d.id].opacity0; }) + .style('stroke-width', function(d) { return params[d.id].width0; }) + .style('fill-opacity', function(d) { return params[d.id].opacity0; }) + .style('r', function(d) { return params[d.id].width0; }) + .duration(duration) + .each('end', inhale); + } + + var breathe = function(surface) { + done = false; + d3.timer(reselect(surface), 200); + }; + + breathe.off = function() { + done = true; + if (selection) { + selection.call(reset); + } + }; + + return breathe; +}; diff --git a/js/id/modes/select.js b/js/id/modes/select.js index db821f137..f016f5b92 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -9,6 +9,7 @@ iD.modes.Select = function(context, selectedIDs) { behaviors = [ iD.behavior.Copy(context), iD.behavior.Paste(context), + iD.behavior.Breathe(context), iD.behavior.Hover(context), iD.behavior.Select(context), iD.behavior.Lasso(context), diff --git a/test/index.html b/test/index.html index d551f6667..1fa6301c8 100644 --- a/test/index.html +++ b/test/index.html @@ -157,6 +157,7 @@ +