Merge pull request #2879 from openstreetmap/breathe-behavior

Add Breathe behavior for interpolated select halos
This commit is contained in:
Bryan Housel
2015-12-21 09:16:01 -05:00
5 changed files with 113 additions and 10 deletions

View File

@@ -43,11 +43,6 @@ path.shadow {
pointer-events: stroke;
}
.shadow {
-webkit-transition: 200ms;
-moz-transition: 200ms;
transition: 200ms;
}
/* points */
@@ -133,11 +128,11 @@ g.vertex.vertex-hover {
g.vertex.hover:not(.selected) .shadow,
g.midpoint.hover:not(.selected) .shadow {
fill-opacity: 0.3;
fill-opacity: 0.5;
}
g.vertex.selected .shadow {
fill-opacity: 0.5;
fill-opacity: 0.7;
}
.mode-draw-area g.midpoint,
@@ -172,7 +167,7 @@ path.shadow {
}
path.shadow.hover:not(.selected) {
stroke-opacity: 0.3;
stroke-opacity: 0.4;
}
path.shadow.selected {
@@ -1566,10 +1561,10 @@ text.gpx {
}
.fill-wireframe path.shadow.hover:not(.selected) {
stroke-opacity: 0.2;
stroke-opacity: 0.4;
}
.fill-wireframe path.shadow.selected {
stroke-opacity: 0.4;
stroke-opacity: 0.6;
}
.fill-wireframe .point,

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>

105
js/id/behavior/breathe.js Normal file
View File

@@ -0,0 +1,105 @@
iD.behavior.Breathe = function() {
var duration = 800,
selector = '.selected.shadow, .selected .shadow',
selected = d3.select(null),
classed = [],
params = {},
done;
function reset(selection) {
selection
.style('stroke-opacity', null)
.style('stroke-width', null)
.style('fill-opacity', null)
.style('r', null);
}
function setAnimationParams(transition, fromTo) {
transition
.style('stroke-opacity', function(d) { return params[d.id][fromTo].opacity; })
.style('stroke-width', function(d) { return params[d.id][fromTo].width; })
.style('fill-opacity', function(d) { return params[d.id][fromTo].opacity; })
.style('r', function(d) { return params[d.id][fromTo].width; });
}
function calcAnimationParams(selection) {
selection
.call(reset)
.each(function(d) {
var s = d3.select(this),
tag = s.node().tagName,
p = {'from': {}, 'to': {}},
opacity, width;
// determine base opacity and 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 from/to interpolation params..
p.tag = tag;
p.from.opacity = opacity * 0.6;
p.to.opacity = opacity * 1.25;
p.from.width = width * 0.9;
p.to.width = width * (tag === 'circle' ? 1.5 : 1.25);
params[d.id] = p;
});
}
function run(surface, fromTo) {
var toFrom = (fromTo === 'from' ? 'to': 'from'),
currSelected = surface.selectAll(selector),
currClassed = Array.prototype.slice.call(surface.node().classList),
n = 0;
if (done || currSelected.empty()) {
selected.call(reset);
return;
}
if (!_.isEqual(currSelected, selected) || !_.isEqual(currClassed, classed)) {
selected.call(reset);
classed = _.clone(currClassed);
selected = currSelected.call(calcAnimationParams);
}
selected
.transition()
.call(setAnimationParams, fromTo)
.duration(duration)
.each(function() { ++n; })
.each('end', function() {
if (!--n) { // call once
surface.call(run, toFrom);
}
});
}
var breathe = function(surface) {
done = false;
d3.timer(function() {
if (done) return true;
var currSelected = surface.selectAll(selector);
if (currSelected.empty()) return false;
surface.call(run, 'from');
return true;
}, 200);
};
breathe.off = function(surface) {
done = true;
d3.timer.flush();
selected
.transition()
.call(reset)
.duration(0);
};
return breathe;
};

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),

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>