Skip to content

Instantly share code, notes, and snippets.

@hacst
Created January 23, 2015 16:29
Show Gist options
  • Save hacst/9483fdb9b593b00f34a0 to your computer and use it in GitHub Desktop.
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
<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