function animateActiveCells(lastRow = -1) {
      let rowToAnimate = lastRow;
      const currentTime = model.audio.currentTime;

      // if a queued beat has played...
      while (model.beatsInQueue.length && model.beatsInQueue[0].time < currentTime) {

        // ... set its row to be animated, and remove it from queue
        rowToAnimate = model.beatsInQueue[0].beat;
        model.beatsInQueue.splice(0, 1);
      }

      // if the while loop updated row to be animated, animate the row
      if (lastRow !== rowToAnimate) {
        const row = `.sequence-row:nth-child(${rowToAnimate + 1})`;
        view.animateActiveCells(`${row} > .sequence-cell`);

        // update last row that was animated
        lastRow = rowToAnimate;
      }
      requestAnimFrame(animateActiveCells.bind(this, lastRow));
    }
/**
     * animateActiveCells() continuously checks if any scheduled beats have played,
     * and animates the coresponding grid row as needed. default lastRow = -1
     * means no rows have been animated yet
     */
animateActiveCells() continuously checks if any scheduled beats have played,
and animates the coresponding grid row as needed. default lastRow = -1
means no rows have been animated yet
animateActiveCells () continuously checks if any scheduled beats have played and animates the coresponding grid row as needed . default lastRow = - 1 means no rows have been animated yet
function animateActiveCells(lastRow = -1) {
      let rowToAnimate = lastRow;
      const currentTime = model.audio.currentTime;
      while (model.beatsInQueue.length && model.beatsInQueue[0].time < currentTime) {
        rowToAnimate = model.beatsInQueue[0].beat;
        model.beatsInQueue.splice(0, 1);
      }
      if (lastRow !== rowToAnimate) {
        const row = `.sequence-row:nth-child(${rowToAnimate + 1})`;
        view.animateActiveCells(`${row} > .sequence-cell`);
        lastRow = rowToAnimate;
      }
      requestAnimFrame(animateActiveCells.bind(this, lastRow));
    }
function animateActiveCells ( lastRow = - 1 ) { let rowToAnimate = lastRow ; const currentTime = model . audio . currentTime ; while ( model . beatsInQueue . length && model . beatsInQueue [ 0 ] . time < currentTime ) { rowToAnimate = model . beatsInQueue [ 0 ] . beat ; model . beatsInQueue . splice ( 0 , 1 ) ; } if ( lastRow !== rowToAnimate ) { const row = ` ${ rowToAnimate + 1 } ` ; view . animateActiveCells ( ` ${ row } ` ) ; lastRow = rowToAnimate ; } requestAnimFrame ( animateActiveCells . bind ( this , lastRow ) ) ; }
animateActiveCells() continuously checks if any scheduled beats have played,
 and animates the coresponding grid row as needed.
animateActiveCells () continuously checks if any scheduled beats have played and animates the coresponding grid row as needed .
// if a queued beat has played... // ... set its row to be animated, and remove it from queue // if the while loop updated row to be animated, animate the row // update last row that was animated