blob: 82fbb0a8ee4c7543fc99252886080d0af40ef627 [file] [log] [blame]
/* Licensed under the Apache License, Version 2.0 (the "License") http://www.apache.org/licenses/LICENSE-2.0 */
var Player = (function() {
const player = {}, mainColor = '#ff6600', rad = 20;
let trg, circle, rectPause1, rectPause2, play, cProgress, progress;
function _sendStatus(g, _paused, _pos) {
g.status.paused = _paused;
g.status.pos = _pos;
OmUtil.wbAction({action: 'videoStatus', data: {
wbId: g.canvas.wbId
, uid: g.uid
, status: {
paused: _paused
, pos: _pos
}
}});
}
function _initControls(_o) {
trg = new fabric.Triangle({
left: 2.7 * rad
, top: _o.height - 2.5 * rad
, visible: _o.status.paused
, angle: 90
, width: rad
, height: rad
, stroke: mainColor
, fill: mainColor
});
rectPause1 = new fabric.Rect({
left: 1.6 * rad
, top: _o.height - 2.5 * rad
, visible: !_o.status.paused
, width: rad / 3
, height: rad
, stroke: mainColor
, fill: mainColor
});
rectPause2 = new fabric.Rect({
left: 2.1 * rad
, top: _o.height - 2.5 * rad
, visible: !_o.status.paused
, width: rad / 3
, height: rad
, stroke: mainColor
, fill: mainColor
});
circle = new fabric.Circle({
left: rad
, top: _o.height - 3 * rad
, radius: rad
, stroke: mainColor
, strokeWidth: 2
, fill: null
});
play = new fabric.Group([circle, trg, rectPause1, rectPause2]
, {
objectCaching: false
, visible: false
});
cProgress = new fabric.Rect({
left: 3.5 * rad
, top: _o.height - 1.5 * rad
, visible: false
, width: _o.width - 5 * rad
, height: rad / 2
, stroke: mainColor
, fill: null
, rx: 5
, ry: 5
});
progress = new fabric.Rect({
left: 3.5 * rad
, top: _o.height - 1.5 * rad
, visible: false
, width: 0
, height: rad / 2
, stroke: mainColor
, fill: mainColor
, rx: 5
, ry: 5
});
}
player.create = function(canvas, _o, wb) {
const vid = $('<video>').hide()
.attr('class', 'wb-video slide-' + canvas.slide)
.attr('id', 'wb-video-' + _o.uid)
.attr("width", _o.width)
.attr("height", _o.height)
.prop('controls', true)
.append($('<source>')
.attr('type', 'video/mp4')
.attr('src', _o._src));
$('#wb-tab-' + canvas.wbId).append(vid);
fabric.Image.fromURL(_o._poster, function(poster) {
poster.scaleX = poster.scaleY = _o.width / poster.getOriginalSize().width;
const video = new fabric.Image(vid[0], {visible: false, objectCaching: false});
vid[0].onseeked = function() {
canvas.requestRenderAll();
};
if (typeof(_o.status) === 'undefined') {
_o.status = {paused: true};
}
let playable = false;
_initControls(_o);
const isDone = function() {
return video.getElement().currentTime === video.getElement().duration;
};
const updateProgress = function() {
progress.set('width', (video.getElement().currentTime * cProgress.width) / video.getElement().duration);
canvas.requestRenderAll();
};
let request;
const opts = $.extend({
subTargetCheck: true
, objectCaching: false
, omType: 'Video'
, selectable: canvas.selection
}, ToolUtil.filter(_o, ['fileId', 'fileType', 'slide', 'uid', '_poster', '_src', 'width', 'height', 'status']));
const group = new fabric.Group([video, poster, play, progress, cProgress], opts);
const updateControls = function() {
video.visible = true;
poster.visible = false;
trg.visible = group.status.paused;
rectPause1.visible = !group.status.paused;
rectPause2.visible = !group.status.paused;
canvas.requestRenderAll();
};
const render = function () {
if (isDone()) {
_sendStatus(group, true, video.getElement().duration);
updateControls();
}
updateProgress();
if (group.status.paused) {
cancelAnimationFrame(request);
canvas.requestRenderAll();
} else {
request = fabric.util.requestAnimFrame(render);
}
};
cProgress.on({
'mousedown': function (evt) {
const _ptr = canvas.getPointer(evt.e, true)
, ptr = canvas._normalizePointer(group, _ptr)
, l = ptr.x - cProgress.aCoords.bl.x + group.width / 2;
_sendStatus(group, group.status.paused, l * video.getElement().duration / cProgress.width)
}
});
play.on({
'mouseover': function() {
circle.set({strokeWidth: 4});
canvas.requestRenderAll();
}
, 'mouseout': function() {
circle.set({strokeWidth: 2});
canvas.requestRenderAll();
}
, 'mousedown': function () {
play.set({
left: pos.left + 3
, top: pos.top + 3
});
canvas.requestRenderAll();
}
, 'mouseup': function () {
play.set({
left: pos.left
, top: pos.top
});
if (isDone()) {
video.getElement().currentTime = 0;
}
_sendStatus(group, !group.status.paused, video.getElement().currentTime)
updateControls();
}
});
group.on({
'mouseover': function() {
play.visible = playable;
cProgress.visible = playable;
progress.visible = playable;
canvas.requestRenderAll();
}
, 'mouseout': function() {
play.visible = false;
cProgress.visible = false;
progress.visible = false;
canvas.requestRenderAll();
}
});
group.setPlayable = function(_r) {
playable = _r !== NONE;
};
group.videoStatus = function(_status) {
group.status = _status;
updateControls();
video.getElement().currentTime = group.status.pos;
updateProgress();
if (group.status.paused) {
video.getElement().pause();
} else {
video.getElement().play()
.then(function() {
fabric.util.requestAnimFrame(render);
}).catch(function(err) {
if ('NotAllowedError' === err.name) {
VideoUtil.askPermission(function() {
video.getElement().play();
fabric.util.requestAnimFrame(render);
});
}
});
}
}
group.setPlayable(wb.getRole());
canvas.add(group);
canvas.requestRenderAll();
player.modify(group, _o);
const pos = {left: play.left, top: play.top};
});
};
player.modify = function(g, _o) {
const opts = $.extend({
angle: 0
, left: 10
, scaleX: 1
, scaleY: 1
, top: 10
}, ToolUtil.filter(_o, ['angle', 'left', 'scaleX', 'scaleY', 'top']));
g.set(opts).setCoords();
g.canvas.requestRenderAll();
};
return player;
})();