(function() {
'use strict';
var event = window.mheContpract.libs['event'].user;
var Video = function(section) {
this.section = section;
this.section.points_possible = 1;
this.section.points_earned = 0;
this.section.section_completed = false;
this.$container = this.section.jq.find('.video');
this.video = this.$container.find('video')[0];
this.showCaptions = false;
this.hasCaptions = true;
this.transcriptUrl = this.$container.data('transcript');
if ( this.transcriptUrl ) {
this.hasTranscripts = true;
}
else {
this.hasTranscripts = false;
}
this.timeDrag = false;
var captionsUrl = this.$container.data('captions');
var self = this;
$.getJSON(captionsUrl, function(data) {
self.captions = data.captions;
createHtml.call(self);
});
};
var createHtml = function() {
var captions = '
';
var transcript;
if ( this.transcriptUrl ) {
transcript = '-->
CC
' +
'';
this.$container.append(controlBar, captions);
initProgressBar.call(this);
initBtnPlay.call(this);
initButton.call(this, '.btnCaption', onCaptionBtnClick);
initButton.call(this, '.btnVolume', onPlayBtnVolume);
if ( this.hasTranscripts ) {
initButton.call(this, '.btnTranscript', onPlayBtnTranscript);
}
if ( this.hasCaptions ) {
var $captions = this.$container.find('.captions');
// Create all captions and hide them.
for (var i = 0; i < this.captions.length; i++) {
var captionData = this.captions[i];
var $caption = $('' + captionData.text + '
');
$captions.append($caption);
// save link to the jQuery element
captionData.$caption = $caption;
// hide all captions
$caption.css({ 'display': 'none' });
}
}
onCaptionBtnClick.call(this, this.$container.find('.btnCaption'));
};
var onPlayBtnTranscript = function() {
if ( this.transcriptUrl ) {
window.open(this.transcriptUrl, '_blank');
}
};
var onPlayBtnVolume = function($btn) {
this.video.volume = 1 - this.video.volume;
if ( this.video.volume ) {
$btn.removeClass('mute');
}
else {
$btn.addClass('mute');
}
};
var initButton = function(selector, callback) {
var $btn = this.$container.find(selector);
callback = callback.bind(this, $btn);
$btn.bind("keydown", function(e) {
var code = e.which;
if ( code === 13 || code === 32 ) { // 13 - enter, 32 - Space
callback();
}
}.bind(this));
$btn.bind(event.mousedown, callback);
};
var initProgressBar = function() {
var self = this;
var $btnSlider = this.$container.find('.btnSlider');
var $progressBar = this.$container.find('.progressBar');
var $progress = this.$container.find('.progressTime');
this.timeDrag = false;
$progressBar.bind(event.mousedown, function(e) {
self.timeDrag = true;
updateBar(e.pageX);
$btnSlider.addClass("active");
document.addEventListener(event.mouseup, onSliderDragStop);
document.addEventListener(event.mousemove, onSliderMove);
});
function updateBar(x) {
var maxDuration = self.video.duration; //Video duraiton
var position = x - $progressBar.offset().left; //Click pos
var minPosition = 0;
var maxPosition = $progressBar.width() - $btnSlider.width();
var sliderPosition = Math.min(Math.max((position - $btnSlider.width() / 2), minPosition), maxPosition);
var percentage = Math.round(100 * 100 * sliderPosition / (maxPosition - minPosition)) / 100;
percentage = Math.min(100, Math.max(percentage, 0));
$btnSlider.css('left', sliderPosition);
// Update progress bar and video currenttime
$progress.css('width', $progressBar.width() * percentage / 100);
self.video.currentTime = maxDuration * percentage / 100;
}
function onSliderDragStop(e) {
document.removeEventListener(event.mouseup, onSliderDragStop);
document.removeEventListener(event.mousemove, onSliderMove);
if ( self.timeDrag ) {
self.timeDrag = false;
$btnSlider.removeClass("active");
}
}
function onSliderMove(e) {
if ( self.timeDrag ) {
updateBar(e.pageX);
}
}
this.video.addEventListener('timeupdate', function(e) {
var currentTime = this.video.currentTime;
updateCaptions.call(this, currentTime);
if ( this.timeDrag ) {
return;
}
// Get video duration
var maxDuration = this.video.duration;
var percentage = 100 * currentTime / maxDuration; //in %
var progressWidth = $progressBar.width() - $btnSlider.width();
var position = progressWidth * percentage / 100;
var minPosition = 0;
var maxPosition = $progressBar.width() - $btnSlider.width();
var sliderPosition = Math.min(Math.max((position), minPosition), maxPosition);
$btnSlider.css('left', sliderPosition);
$progress.css('width', $progressBar.width() * percentage / 100);
}.bind(this));
};
var initBtnPlay = function() {
var $btnPlay = this.$container.find('.btnPlay');
$btnPlay.bind("keydown", function(e) {
var code = e.which;
if ( code === 13 || code === 32 ) { // 13 - enter, 32 - Space
this.onPlayBtnClick.call(this);
}
}.bind(this));
$btnPlay.bind('click', this.onPlayBtnClick.bind(this));
this.video.addEventListener('play', function() {
$btnPlay.addClass('playing');
});
this.video.addEventListener('pause', function() {
$btnPlay.removeClass('playing');
});
};
var onCaptionBtnClick = function($btn) {
if ( this.showCaptions ) {
$btn.removeClass('selected');
}
else {
$btn.addClass('selected');
}
this.showCaptions = !this.showCaptions;
updateCaptions.call(this, this.video.currentTime);
};
var updateCaptions = function(currentTime) {
if ( this.hasCaptions ) {
for (var i = 0; i < this.captions.length; i++) {
var captionData = this.captions[i];
if ( this.showCaptions ) {
if ( currentTime >= captionData.startTime && currentTime < captionData.endTime ) {
captionData.$caption.css({ 'display': 'table-cell' });
}
else {
captionData.$caption.css({ 'display': 'none' });
}
}
else {
// hide all captions
captionData.$caption.css({ 'display': 'none' });
}
}
}
};
Video.prototype.onPlayBtnClick = function(e) {
var currentTime, totalTime;
var self = this;
if ( this.video.paused ) {
this.video.play();
this.animationInterval = setInterval(function() {
currentTime = self.video.currentTime;
totalTime = self.video.duration;
if ( currentTime == totalTime ) {
self.finishSlide();
clearInterval(self.animationInterval);
}
}, 10);
}
else {
this.video.pause();
}
};
Video.prototype.update = function() {
var $controlBar = this.$container.find('.controlBar');
var $playBtn = this.$container.find('.btnPlay');
var $captionBtn = this.$container.find('.btnCaption');
var $volumeBtn = this.$container.find('.btnVolume');
var $transcriptBtn = this.$container.find('.btnTranscript');
var $progressBar = this.$container.find('.progressBar');
// calculate progressBar width
var trans;
var progressBarWidth = $controlBar.width() -
$playBtn.outerWidth() - 2 -
(this.hasCaptions ? $captionBtn.outerWidth() + 4 : 0) -
(this.hasTranscripts ? $transcriptBtn.outerWidth() + 4 : 0) -
$volumeBtn.outerWidth() - 2 -
parseFloat($progressBar.css('margin-left')) -
parseFloat($progressBar.css('margin-right'));
$progressBar.width(progressBarWidth);
};
Video.prototype.finishSlide = function() {
this.section.points_earned = this.section.points_possible;
this.section.section_completed = true;
player.activity.grade_activity();
player.update_section_status();
document.querySelector('.navigation_button.next_button').focus();
};
var slide;
window.mheContpract = window.mheContpract || {};
window.mheContpract['synapse_video'] = {
initialize: function(section) {
slide = new Video(section);
},
show: function() {
slide.update();
}
};
})();