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).
license: gpl-3.0 |
<!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> |