Skip to content

Instantly share code, notes, and snippets.

@jens-a-e
Last active September 12, 2016 20:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jens-a-e/94d00040766326e7a287a52abb2b4e32 to your computer and use it in GitHub Desktop.
Save jens-a-e/94d00040766326e7a287a52abb2b4e32 to your computer and use it in GitHub Desktop.
TickerService
import Ember from 'ember';
export default Ember.Controller.extend({
ticker: Ember.inject.service(),
appName: 'Ticker',
_autoStart: Ember.on('init', function() {
this.get('ticker').start();
console.log("Auto starting ticker");
}),
actions: {
start() {
this.get('ticker').start();
},
pause() {
this.get('ticker').pause();
},
stop() {
this.get('ticker').stop();
}
}
});
import Ember from 'ember';
const { computed } = Ember;
export default Ember.Service.extend(Ember.Evented, {
tickCount: computed('currentTime', 'interval', {
get() {
return Math.round(this.get('currentTime') / this.get('interval'));
}
}),
isActive: false,
_tempo: 120,
sixteenth: computed('tickCount', {
get() {
return (this.get('tickCount') % 4) + 1;
}
}),
beat: computed('sixteenth', {
get() {
return Math.floor((this.get('tickCount') / 4) % 4) + 1;
}
}),
bar: computed('beat', {
get() {
return Math.floor(this.get('tickCount') / 16) + 1;
}
}),
display: computed('tickCount', {
get() {
var bar = this.get('bar'),
beat = this.get('beat'),
sixteenth = this.get('sixteenth');
return `${bar}:${beat}:${sixteenth}`;
}
}),
tempo: computed('_tempo', {
set(k, value) {
const tempo = parseInt(value, 10);
console.debug(k, value, tempo);
if (tempo !== NaN) {
this.set('_tempo', Math.max(1,tempo));
}
},
get() { return this.get('_tempo'); }
}),
interval: computed('_tempo', {
get() {
return Math.round(1000 / (this.get('_tempo') / 60 * 4));
}
}),
_lastTick: -Infinity,
tick() {
if (this.get('isActive')) {
const now = Date.now();
let { interval, _lastTick, tickCount, startTime } = this.getProperties('interval','_lastTick', 'tickCount', 'startTime');
if (_lastTick === -Infinity) {
_lastTick = now-interval;
}
const diff = Math.abs(now-_lastTick);
const jitter = diff-interval;
this.setProperties({
currentTime: now-startTime,
_lastTick: now,
_jitter: jitter
});
Ember.run.later(this, this.tick, diff > interval ? interval-jitter : interval+jitter);
}
},
start() {
if(!this.get('isActive')) {
this.setProperties({
isActive: true,
startTime: Date.now()
});
}
this.tick();
},
pause() {
this.toggleProperty('isActive');
this.tick();
},
stop() {
this.setProperties({
startTime: 0,
isActive: false
});
}
});
<h1>Welcome to {{appName}}</h1>
<br>
{{ticker._tempo}},
{{ticker.interval}} |
{{ticker.display}} |
{{ticker._jitter}}
<br>
{{ticker.tickCount}}
<br>
<button {{action "start"}}>Start</button>
<button {{action "pause"}}>Pause</button>
<button {{action "stop"}}>Stop</button>
<br>
{{input type="range" value=(mut ticker.tempo) min="1" max="999"}}
<br>
{
"version": "0.10.4",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.7.0",
"ember-data": "2.7.0",
"ember-template-compiler": "2.7.0"
},
"addons": {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment