contra-highlight.js

// Automatically highlight dance moves in synchrony with a video. Requires jquery (2.0.3) and
// the iframe Youtube API.

function clearMoves() { $(‘.move’).removeClass(‘current-move’); }

function checkTimeFunction(player, moveTiming) /* The function returned is intended to run
periodically; if the current move (as specified by moveTiming) changes, it will alter the highlighting
appropriately. */ {
var currentMoveId;
return function() {
var time = player.getCurrentTime();

function moveHappensAtTime(t1, t2, moveId) /* Call this for each move, each time through
the dance; t1 and t2 give approximate start and end times of the move (to the
nearest second). */ {
if (time > t1 && time <= t2 && currentMoveId != moveId) { clearMoves(); currentMoveId = moveId; $(moveId).addClass('current-move'); } } function makeHighlight(moveTimingA) /* uses moveTimingA[i].id/startTimes; all startTimes attributes should be arrays of numbers (giving time in seconds at which each move starts); if any number is repeated among these arrays, results might be unpredictable. */ { var moveStarts = []; for (var i = 0; i < moveTimingA.length; i++) { for (var j = 0; j < moveTimingA[i].startTimes.length; j++) { moveStarts.push({ move: moveTimingA[i].id, time: moveTimingA[i].startTimes[j] }); } } moveStarts.sort(function(a, b) { return a.time - b.time; }); for (var i = 0; i < moveStarts.length - 1; i++) { moveHappensAtTime(moveStarts[i].time, moveStarts[i + 1].time, moveStarts[i].move); } var lastMove = moveStarts[moveStarts.length - 1]; moveHappensAtTime(lastMove.time, player.getDuration(), lastMove.move); } makeHighlight(moveTiming); } }