An expansion of Self-adjusting setTimeout loop in javascript
Uses a self-adjusting timeout loop to trigger events, at somewhat consistent intervals, to drive animation.
Uncorrected loops shows a setTimeout with a fixed delay, the same delay as the adjusted setTimeout target.
Metronome drawn with Sketch
adapted from:
xxxxxxxxxx
<html>
<head>
<meta charset="utf-8">
<title>disco lights</title>
<style>
body {
font-family: sans-serif;
margin: 0;
min-height: 500px;
}
svg { margin: 10px; }
.x.axis, y.axis, .plot-line {
stroke: white;
fill: white;
}
.black-bg { background: hsl(0, 0%, 0%); }
.axis { font-size: 12px; }
.axis path, .axis line, .tick line {
fill: none;
stroke: lawngreen;
shape-rendering: crispEdges;
stroke-width: 1.5px;
}
.plot text {
fill: #dadada;
stroke: none;
}
.tick text {
fill: lawngreen;
stroke: none;
}
.dot {
stroke: none;
r: 2;
}
.dot.beat { fill: lawngreen; }
.dot.measure { fill: crimson; }
.ctrl {
background: #dadada;
border-radius: 6px;
display: inline-block;
margin: 0 0 0 10px;
padding: 6px;
}
#play-icon {
border-top: 14px solid transparent;
border-bottom: 14px solid transparent;
border-left: 24px solid #777;
margin: 2px 2px 2px 6px;
width: 0;
height: 0;
}
#pause-left, #pause-right, #stop-icon {
background: #777;
}
#pause-left, #pause-right {
float: left;
margin-top: 4px;
margin-bottom: 4px;
width: 8px;
height: 24px;
}
#pause-left {
margin-left: 6px;
margin-right: 4px;
}
#pause-right {
margin-right: 6px;
}
#play-pause-ctrl.play #pause-icon { display: none; }
#play-pause-ctrl.pause #play-icon { display: none; }
#stop-icon {
border-radius: 3px;
margin: 6px;
width: 20px;
height: 20px;
}
#logs {
display:inline-block;
vertical-align: top;
}
.log {
margin: 0 0 4px 40px;
}
#adjusted {
margin-left: 65px;
}
.log div {
display: inline-block;
text-align: right;
}
.log .label {
margin-left: 20px;
}
.log .num {
width: 45px;
}
</style>
</head>
<body>
<svg>
<defs>
<clipPath id="plot-clip"><rect></rect></clipPath>
</defs>
<g id="lights-grp"></g>
<g id="metronome" style="opacity:0">
<path id="arc-weight" fill="none" stroke="none" d="M108.975346,35.3880198 C94.4537153,26.878235 77.5460263,22 59.4989645,22 C41.4425468,22 24.5266835,26.8832943 10,35.4012576"></path>
<path id="arc-pendulum" fill="none" stroke="none" d="M117.930342,20.6200429 C100.924281,10.6899236 81.1395384,5 60.0258433,5 C38.8619106,5 19.0332625,10.7170328 2,20.6909975"></path>
<polygon id="metro-body" fill="darkgoldenrod" points="45 5 60 0 75 5 85 190 35 190"></polygon>
<path id="pendulum" stroke="crimson" stroke-width="2" stroke-linecap="round" d="M2,21 L60,120"></path>
<circle id="weight" stroke="#979797" stroke-width="0.5" fill="white" cx="10" cy="35" r="5"></circle>
</g>
</svg>
<div>
<div id="play-pause-ctrl" class="play ctrl">
<div id="play-icon"></div>
<div id="pause-icon">
<div id="pause-left"></div>
<div id="pause-right"></div>
</div>
</div>
<div id="stop-ctrl" class="ctrl">
<div id="stop-icon"></div>
</div>
<div id="logs">
<div id="uncorrected" class="log">
Uncorrected loops: <div class="count num">0</div><div class="label">deviation: </div><div class="dev num">0</div>ms<div class="label">max: </div><div class="max num">0</div>ms
</div>
<div id="adjusted" class="log">
Adjusted loops: <div class="count num">0</div><div class="label">deviation: </div><div class="dev num">0</div>ms<div class="label">max: </div><div class="max num">0</div>ms
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script src="beats.js"></script>
</script>
</body>
</html>
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js