JSFiddle - React, Tailwind, and code Playground
HTML
<script src="http://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.0/raphael-min.js"></script>
<div class="main">
<div id="canvas"></div>
<span>tempo: </span><input id="tempo" value='200' />
<span>ticks: </span><input id="ticks" value='20' />
<input type="button" id="startstop" value="start" />
</div>
<audio id="tick" src="http://experimentsinform.com/media/audio/tick.wav"></audio>
CSS
.main {
width: 400px;
margin: 5px;
padding: 10px;
}
#canvas {
width: 900px;
height: 240px;
margin-bottom: 5px;
}
#tempo {
width: 50px;
text-align: center;
}
#ticks {
width: 50px;
text-align: center;
}
body {
font-size: 12px;
}
JavaScript
var paper = Raphael("canvas", 300, 240);
var metronome = function(l, r) {
l = typeof l !== "undefined" ? l : 200; // length of metronome arm
r = typeof r !== "undefined" ? r : 20; //max angle from upright
var y0 = l * Math.cos(Math.PI * r / 180),
x0 = l * Math.sin(Math.PI * r / 180),
y = l + 10,
x = x0 + 10,
tick_count = 0,
width,
bars = paper.set();
var outline = paper.path("M"+x+","+y+"l-"+x0+",-"+y0+"a"+l+","+l+" "+2*r+" 0,1 "+2*x0+",0L"+x+","+y).attr({
fill: "#EEF",
'stroke-width': 0
});
var arm = paper.path("M" + x + "," + y + "v-" + l).attr({
'stroke-width': 5,
stroke: "#999"
}).data("id", "arm");
var weight = paper.path("M" + x + "," + (y-100) + "h12l-3,18h-18l-3-18h12").attr({
'stroke-width': 0,
fill: '#666'
}).data("id", "weight");
var vertex = paper.circle(x, y, 7).attr({
'stroke-width': 0,
fill: '#CCC'
}).data("id", "vertex");
var label = paper.text(x, y + 20, "").attr({
"text-anchor": "center",
"font-size": 14
});
var mn = paper.set(arm, weight);
Raphael.easing_formulas.sinoid = function(n) { return Math.sin(Math.PI * n / 2) };
function done() {
mn.attr("transform", "R0 " + x + "," + y);
$(this).val("start");
}
function tick(obj, repeats, callback) {
console.log(arguments);
//Raphael summons the callback on each of the three objects in the set, so we
//have to only call the sound once per iteration by associating it with one of the objects.
//doesn't matter which one
if (obj.data("id") === "arm") {
document.getElementById("tick").play();
tick_count += 1;
label.attr("text", tick_count);
if (callback && tick_count >= repeats) {
callback();
}
}
}
...