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"},
       ...