Skip to content

Instantly share code, notes, and snippets.

@steveharoz
Forked from mbostock/.block
Last active July 16, 2017 20:45
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 steveharoz/2da60f7a3bf44e10a35d99034172688c to your computer and use it in GitHub Desktop.
Save steveharoz/2da60f7a3bf44e10a35d99034172688c to your computer and use it in GitHub Desktop.
Epicyclic Gearing
license: gpl-3.0

Time the span between frames.

12 frames with an animated SVG are shown via d3.timer(). The elapsed time of each frame is put in an array, which is logged to the console after 150 runs (~1.5 minutes).

<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
path {
fill-rule: evenodd;
stroke: #333;
stroke-width: 2px;
fill: #6baed6;
}
</style>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var width = 960,
height = 500,
radius = 140;
var offset = 0,
speed = .1,
start = Date.now();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(.55)");
var frame = svg.append("g");
frame.append("g")
.attr("transform", "translate(-200, -200)")
.append("path")
.attr("d", gear(16, radius, radius/7));
frame.append("g")
.attr("transform", "translate(200, -200)")
.append("path")
.attr("d", gear(16, radius, radius/7));
frame.append("g")
.attr("transform", "translate(-200, 200)")
.append("path")
.attr("d", gear(16, radius, radius/7));
frame.append("g")
.attr("transform", "translate(200, 200)")
.append("path")
.attr("d", gear(16, radius, radius/7));
// get path for a gear
function gear(teethCount, radius, teethSize = 8) {
var r2 = Math.abs(radius),
r0 = r2 - teethSize,
r1 = r2 + teethSize,
da = Math.PI / teethCount,
a0 = -Math.PI / 2,
i = -1,
path = ["M", r0 * Math.cos(a0), ",", r0 * Math.sin(a0)];
while (++i < teethCount) path.push(
"A", r0, ",", r0, " 0 0,1 ", r0 * Math.cos(a0 += da), ",", r0 * Math.sin(a0),
"L", r2 * Math.cos(a0), ",", r2 * Math.sin(a0),
"L", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
"A", r1, ",", r1, " 0 0,1 ", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0),
"L", r2 * Math.cos(a0 += da / 3), ",", r2 * Math.sin(a0),
"L", r0 * Math.cos(a0), ",", r0 * Math.sin(a0));
path.push(",Z");
return path.join("");
}
var previous_elapsed = 0;
var frameTimes = new Array(12);
var frameIndex = 0;
var show = false;
var runCount = 0;
var outputString = "";
var mytimer = d3.timer(function(elapsed) {
// skip every other frame
// if (elapsed - previous_elapsed < 17)
// return;
// animate
var angle = (Date.now() - start) * speed,
transform = function(d) { return "rotate(" + angle + ")"; };
frame.selectAll("path").attr("transform", transform);
// store frame duration
frameTimes[frameIndex] = (elapsed - previous_elapsed).toFixed(2);
frameIndex++;
previous_elapsed = elapsed;
// log to console after some number of frames
if (frameIndex >= frameTimes.length) {
if (show)
outputString += frameTimes.join() + "\n";
runCount++;
if (runCount == 300) {
console.log(outputString);
outputString = "";
runCount = 0;
}
show = !show;
frame.attr('visibility', show ? 'visible' : 'hidden');
frameIndex = 0;
frameTimes = new Array(frameTimes.length);
}
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment