// `fn` will be called with context `context` if supplied (optional) function TimerControl(fn, context) { var epoch = 0; var running = false; // initialize, effectively fn.call(context || this, epoch); this.play = function() { if(running) return; running = true; d3.timer(function(t) { fn.call(context || this, epoch + t); if (!running) { epoch += t; return true; } return false; }) } this.pause = function() { running = false; } this.reset = function() { epoch = 0; fn.call(context || this, epoch); } }