Add Breathe behavior for interpolated select halos (closes #1814)

This commit is contained in:
Bryan Housel
2015-12-17 22:18:58 -05:00
parent edd19cbd0a
commit 882457a351
5 changed files with 103 additions and 6 deletions
-6
View File
@@ -43,12 +43,6 @@ path.shadow {
pointer-events: stroke;
}
.shadow {
-webkit-transition: 200ms;
-moz-transition: 200ms;
transition: 200ms;
}
/* points */
g.point .stroke {
+1
View File
@@ -178,6 +178,7 @@
<script src='js/id/behavior.js'></script>
<script src='js/id/behavior/add_way.js'></script>
<script src='js/id/behavior/breathe.js'></script>
<script src='js/id/behavior/copy.js'></script>
<script src='js/id/behavior/drag.js'></script>
<script src='js/id/behavior/draw.js'></script>
+100
View File
@@ -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;
};
+1
View File
@@ -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),
+1
View File
@@ -157,6 +157,7 @@
<script src='../js/id/behavior.js'></script>
<script src='../js/id/behavior/add_way.js'></script>
<script src='../js/id/behavior/breathe.js'></script>
<script src='../js/id/behavior/copy.js'></script>
<script src='../js/id/behavior/drag.js'></script>
<script src='../js/id/behavior/draw.js'></script>