Skip to content

Instantly share code, notes, and snippets.

@danfishgold
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danfishgold/a39bd793f017a93458f0 to your computer and use it in GitHub Desktop.
Save danfishgold/a39bd793f017a93458f0 to your computer and use it in GitHub Desktop.
Waves 2
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
width: 960px;
height: 500px;
position: relative;
}
svg circle.point {
fill: red;
}
svg circle.wave {
fill: none;
stroke: red;
stroke-width: 2;
}
</style>
<body></body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var w = 960,
h = 500;
var points = {};
var tag = 0;
var maxRadius = 500;
var waveDuration = 8400;
var svg = d3.select("body").append("svg")
.attr("width", w)
.attr("height", h);
var mouseUp = false;
var alreadyRippled = false;
svg.on("mousedown", function() {
mouseUp = false;
alreadyRippled = false;
var pt = d3.mouse(this);
var center = {x: pt[0], y: pt[1]};
center.dists = d3.values(points).map(function(d) { return dist(center, d); });
var timerFunc = function() {
if (!mouseUp) {
makeWave(center, 1);
alreadyRippled = true;
d3.timer(timerFunc, 1000);
};
return true;
}
d3.timer(timerFunc, 1000);
});
svg.on("mouseup", function() {
mouseUp = true;
if (!alreadyRippled) {
var pt = d3.mouse(this);
var newTag = tag++;
points[newTag] = {
x: pt[0],
y: pt[1],
dists: {}
};
d3.keys(points).forEach(function(k) {
var d = dist(points[newTag], points[k]);
points[newTag].dists[k] = d;
points[k].dists[newTag] = d;
});
addPoints();
};
});
function addPoints() {
svg.selectAll("circle.point")
.data(d3.entries(points))
.enter()
.append("circle")
.attr("class", "point")
.attr("cx", function(d) { return d.value.x; })
.attr("cy", function(d) { return d.value.y; })
.attr("r", 5)
.on("mousedown", function(d) {
makeWave(d.value, 1);
d3.event.stopPropagation();
}).on("mouseup", function(d) { d3.event.stopPropagation(); });
};
function makeWave(center, opacity) {
var dists = d3.entries(center.dists)
.filter(function(d) { return 0 < d.value && d.value < opacity*maxRadius; })
.forEach(function(d) {
d3.timer(function() {
makeWave(points[d.key], (opacity - d.value/maxRadius)*0.55);
return true;
}, d.value/maxRadius * waveDuration);
});
svg.append("circle")
.attr("class", "wave")
.attr("cx", center.x)
.attr("cy", center.y)
.attr("r", 0)
.style("stroke-opacity", opacity)
.transition()
.duration(waveDuration*opacity)
.ease("linear")
.attr("r", maxRadius*opacity)
.style("stroke-opacity", 0)
.remove();
}
function dist(a, b) {
return Math.sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment