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>