Animation Frame sync
by amindunited
HTML
<button id="playButton">Play</button>
<br/>
<div class="testTrack">
<div class="bar">1</div>
<div class="bar">2</div>
<div class="bar">3</div>
<div class="bar">4</div>
<div class="bar">5</div>
<div class="bar">6</div>
<div class="bar">7</div>
<div class="bar">8</div>
</div>
<br/>
<div class="testTrack">
<div class="bar">1</div>
<div class="bar">2</div>
<div class="bar">3</div>
<div class="bar">4</div>
<div class="bar">5</div>
<div class="bar">6</div>
<div class="bar">7</div>
<div class="bar">8</div>
</div>
<br/>
<div class="testTrack">
<div class="bar">1</div>
<div class="bar">2</div>
<div class="bar">3</div>
<div class="bar">4</div>
<div class="bar">5</div>
<div class="bar">6</div>
<div class="bar">7</div>
<div class="bar">8</div>
</div>
<br/>
<div class="testTrack">
<div class="bar">1</div>
<div class="bar">2</div>
<div class="bar">3</div>
<div class="bar">4</div>
<div class="bar">5</div>
<div class="bar">6</div>
<div class="bar">7</div>
<div class="bar">8</div>
</div>
<br/>
<script type="text/x-handlebars" data-template-name="application">
<h1>App Name</h1>
{{web-daw}}
</script>
<script type="text/x-handlebars" data-template-name="components/web-daw">
<h2>Daw</h2>
{{arranger-scroll}}
</script>
<script type="text/x-handlebars" data-template-name="components/arranger-scroll">
<h3>Arranger</h3>
{{#each track in tracks}}
{{arranger-scroll-track track=track}}
{{/each}}
</script>
<script type="text/x-handlebars" data-template-name="components/arranger-scroll-track">
{{track.name}}
{{#each tick in track.bars}}
<div class="bar">
</div>
{{/each}}
</script>
<!--
JS LIBS
-->
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script...
CSS
* {
box-sizing: border-box;
}
#playButton {
clear: both;
}
.testTrack {
float: left;
clear: left;
}
.bar {
width: 20px;
height: 20px;
background-color: yellow;
border: solid 1px orange;
float: left;
text-align: center;
}
.bar.current {
background-color: red;
}
JavaScript
var isPlaying = false;
var time;
var currentIndex = 0;
function draw() {
if (isPlaying) { return; }
requestAnimationFrame(draw);
var now = new Date().getTime(),
dt = now - (time || now);
time = now;
// Drawing code goes here... for example updating an 'x' position:
$('.testTrack').each(function(){
$('.bar.current', this).removeClass('current');
});
$('.testTrack').each(function(){
//$('.bar', this).get(currentIndex).addClass('current');
$($('.bar', this).get(currentIndex)).addClass('current');
//console.log("....", $('.bar', this).get(currentIndex))//.addClass('current');
});
currentIndex++;
if (currentIndex >= $('.testTrack .bar').length) {
currentIndex = 0;
}
console.log($('.testTrack .bar')[currentIndex], currentIndex);
//this.x += 10 * dt; // Increase 'x' by 10 units per millisecond
}
$('#playButton').click(function(e){
if (isPlaying) {
isPlaying = false;
}
else {
isPlaying = true;
}
draw();
});
$(function(){
//draw();
});
App = Em.Application.create({});
App.WebDawComponent = Em.Component.extend({
isPlaying: false,
currentTick: 0, // where we are in the playback
tempo: 120.0,
lookahead: 25.0, // How long (ms) between calls to the shedule
bufferSize: 100, // How many ms to hold in the buffer
nextNoteTime: 0.0, //when the next note is due
//Should be on each block/note
noteResolution: 32, // number of ticks per beat
noteLength: 0.05, //how long the note is held for ?do we need this? - cant it just be on/off
lastNoteDrawn: -1, // in
notesInQueue: [],
timer: null, // the object that handles timing events
});
App.ArrangerScrollComponent = Em.Component.extend({
tracks: [
{name: "track 1", bars: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]},
{name: "track 2"},
...