This is a fork of Interrupting Chained Transitions. It is showing the power of d3.dispatch for building reusable components.
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <style> | |
| body { | |
| position: relative; | |
| width: 960px; | |
| height: 500px; | |
| } | |
| button { | |
| position: absolute; | |
| cursor: pointer; | |
| top: 50%; | |
| left: 50%; | |
| margin-top: -1.75em; | |
| margin-left: -6em; | |
| width: 12em; | |
| padding: 1em 2em; | |
| background: #000; | |
| color: #fff; | |
| border-radius: 8px; | |
| border: solid 2px #fff; | |
| font: 16px "Helvetica Neue", sans-serif; | |
| } | |
| button:focus { | |
| outline: none; | |
| } | |
| button:hover { | |
| text-shadow: 0 1px 0 #000; | |
| background: #444; | |
| } | |
| button:active { | |
| background: #222; | |
| } | |
| </style> | |
| <button>Toggle The Music</button> | |
| <script src="http://d3js.org/d3.v3.min.js"></script> | |
| <script> | |
| function danceBoard() { | |
| var width = 960, | |
| height = 500, | |
| size = 80, | |
| color = d3.scale.ordinal() | |
| .range(["#333", "brown", "white", "green", "steelblue"]), | |
| dispatch = d3.dispatch("start", "stop"); | |
| function render(selection) { | |
| selection.each(function(data) { | |
| var svg = d3.select(this).selectAll('svg') | |
| .data([0]); | |
| svg.enter().append("svg") | |
| .attr("width", width) | |
| .attr("height", height) | |
| .append("g") | |
| .attr("transform", "translate(-40,-30)"); | |
| svg = svg.select("g"); | |
| var rect = svg.selectAll("rect") | |
| .data(data) | |
| .enter().append("rect") | |
| .attr("transform", function(d) { return "translate(" + d + ")"; }) | |
| .attr("width", size) | |
| .attr("height", size) | |
| .style("stroke", "black") | |
| .style("stroke-width", "2px") | |
| .style("fill", "#000"); | |
| dispatch.on("start.danceBoard", function() { | |
| rect.transition() | |
| .duration(0) | |
| .delay(function(d, i) { return i * 5; }) | |
| .each(pulse); | |
| }); | |
| dispatch.on("stop.danceBoard", function() { | |
| rect.transition() | |
| .duration(0) | |
| .delay(function(d, i) { return i * 5; }) | |
| .style("fill", "#333"); | |
| }); | |
| dispatch.start(); | |
| function pulse() { | |
| var rect = d3.select(this); | |
| (function loop() { | |
| rect = rect.transition() | |
| .duration(750) | |
| .style("fill", color(Math.random() * 5 | 0)) | |
| .each("end", function() { if (this.__transition__.count < 2) loop(); }); | |
| })(); | |
| } | |
| }); | |
| } | |
| // get/set these | |
| render.dispatch = dispatch; | |
| render.width = width; | |
| render.height = height; | |
| render.size = size; | |
| return render; | |
| } | |
| var dance = danceBoard(); | |
| d3.select("button") | |
| .on("click", function stop() { | |
| dance.dispatch.stop(); | |
| d3.select(this).on("click", function() { | |
| dance.dispatch.start(); | |
| d3.select(this).on("click", stop); | |
| }); | |
| }); | |
| var data = d3.merge(d3.range(0, dance.width + dance.size, dance.size).map(function(x) { | |
| return d3.range(0, dance.height + dance.size, dance.size).map(function(y) { | |
| return [x, y]; | |
| }); | |
| })); | |
| d3.select("body").datum(data).call(dance); | |
| </script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment