Here is the relevant part of the code. Enjoy!
$( function()
{
var _canvas = document.getElementById( 'output-canvas' );
var _context = _canvas.getContext( '2d' );
var _videoFrames = [];
var _numLag = 24;
var _mouse = { x: 0, y: 0 };
var _lag = [];
var render = function()
{
var w = _canvas.width;
var h = _canvas.height;
var maxFrames = _videoFrames.length - 1;
var maxLag = _lag.length - 1;
var x = _mouse.x;
var y = _mouse.y;
var c = y / h;
var gradient = _context.createLinearGradient( 0, 0, 0, h );
gradient.addColorStop( Math.max( c - 0.5, 0.0 ), "#fff" );
gradient.addColorStop( ( c <= 0.0 ? 0.0 : c >= 1.0 ? 1.0 : c ), "#000" );
gradient.addColorStop( Math.min( c + 0.5, 1.0 ), "#fff" );
_context.clearRect( 0, 0, w, h );
_context.beginPath();
_context.fillStyle = gradient;
_context.rect( 0, 0, w, h );
_context.fill();
// compute lag
_lag.forEach( function( point, index )
{
point.x = x;
point.y = y;
var nextPoint = _lag[ index + 1 ] || _lag[ 0 ];
x += ( nextPoint.x - point.x ) * .6542;
y += ( nextPoint.y - point.y ) * .6542;
} );
// frame slices
for( var row = 0; row < h; ++row )
{
// the offset force
var o = _context.getImageData( 0, row, 1, 1 ).data[ 0 ] / 255.0;
// the index in the lag array
var l = Math.floor( o * maxLag );
// the x pos at index in lag array, mapped to frames length
var i = Math.floor( ( _lag[ l ].x / w ) * maxFrames );
_context.putImageData( _videoFrames[ ( i <= 0 ? 0 : i >= maxFrames ? maxFrames : i ) ].data, 0, 0, 0, row, w, 1 );
}
requestAnimationFrame( render );
};
} );