Created
January 23, 2015 16:29
-
-
Save hacst/9483fdb9b593b00f34a0 to your computer and use it in GitHub Desktop.
Tests animation of a signal on a line using paths with stroke-dasharray
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<style> | |
.line { | |
stroke: black; | |
fill: none; | |
stroke-width: 2px; | |
} | |
.signal { | |
stroke: red; | |
} | |
</style> | |
<body> | |
<svg id="schematic" width="10000px" height="10000px" /> | |
</body> | |
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
<script type="text/javascript"> | |
var px_per_ms = 0.2; | |
var lines = []; | |
function dt_next_toggle() { | |
return Math.random() * 2000; | |
} | |
function add_toggly_line(x,y, rest, length) { | |
var d = "M"+x+" "+y+" "+ rest; | |
var group = d3.select("#schematic").append("g") | |
.attr("class", "line"); | |
var line = group.append("path") | |
.attr("d", d); | |
var signal = group.append("path") | |
.attr("class", "signal") | |
.attr("d", d); | |
var data = {'signal': signal, | |
'impulses': [Number.NEGATIVE_INFINITY], | |
'state': false, | |
'length': length }; | |
lines.push(data); | |
function toggle() { | |
data.state = !data.state; | |
data.impulses.push(window.performance.now()) | |
setTimeout(toggle, dt_next_toggle()); | |
} | |
setTimeout(toggle, dt_next_toggle()); | |
return data; | |
} | |
for (var o = 0; o < 2; ++o) { | |
for (var i = 0; i < 100; ++i) { | |
add_toggly_line(1000 - i * 10 + 5 + o * 500, i * 10 + 5, "h 100 v 100 h 100 v 100", 400); | |
} | |
} | |
function dashes_for(timestamp, line) { | |
var dashes = []; | |
var cutoff = -1; | |
if (line.state == false) { | |
// If the state is false we need the first impulse to be interpreted as a gap | |
dashes.push(0); | |
} | |
var end_of_last_px = 0; | |
var max_runtime = line.length / px_per_ms; // Time for signal to traverse | |
for (var i = line.impulses.length - 1; i >= 0; --i) { | |
var dt = Math.max(0.0, timestamp - line.impulses[i]); // Workaround Chrome giving negative dt | |
if (dt > max_runtime) { | |
// Signal no longer relevant, can mark it and rest for deletion | |
cutoff = i; | |
break; | |
} | |
var till_px = dt * px_per_ms; | |
dashes.push(till_px - end_of_last_px); //TODO: Figure out of rounding here saves time | |
end_of_last_px = till_px; | |
} | |
dashes.push(line.length); // Simply make sure that whatever is at the end it extends the rest of the wire | |
if (cutoff > 50) { | |
// Amortized clean-up so we don't constantly shift the cheap vector | |
line.impulses.splice(0, cutoff + 1); | |
} | |
return dashes.join(','); | |
} | |
// Handle animation | |
function tick(timestamp) { | |
for (var i = 0; i < lines.length; ++i) { | |
// Animate all lines | |
var line = lines[i]; | |
if (line.impulses.length == 0) // Line is steady state. Skip | |
continue; | |
line.signal.attr('stroke-dasharray', dashes_for(timestamp, line)); | |
} | |
window.requestAnimationFrame(tick); | |
} | |
window.requestAnimationFrame(tick); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment