//vim: et:ts=4:sw=4:sts=4:ft=js Ox.VideoPanelPlayer = function(options, self) { var self = self || {}, that = new Ox.Element('div', self) .defaults({ annotationsSize: 256, duration: 0, height: 0, loop: false, muted: false, paused: false, playInToOut: false, points: [0, 0], position: 0, poster: '', showAnnotations: true, showControls: true, subtitles: [], videoHeight: 0, videoSize: 'fit', videoWidth: 0, videoURL: '', width: 0 }) .options(options || {}) .css({ height: self.options.height + 'px', width: self.options.width + 'px' }) .bindEvent({ resize: resizeElement, key_shift_a: function() { that.toggleAnnotations(); }, key_shift_c: function() { that.toggleControls(); }, key_shift_s: function() { that.toggleSize(); }, key_space: function() { that.togglePlay(); } }); $.extend(self, { fullscreen: false, videoCSS: getVideoCSS() }); //alert(JSON.stringify([self.playerHeight, self.playerWidth, self.videoCSS])) self.$player = new Ox.Element() .css({ overflowX: 'hidden', overflowY: 'hidden' }) .bind({ mousedown: that.gainFocus }) .bindEvent({ resize: resizeVideo }); self.$video = new Ox.VideoElement({ height: self.videoCSS.height, paused: true, points: self.options.points, position: self.options.position, url: self.options.videoURL, width: self.videoCSS.width }) .css(self.videoCSS) .bindEvent({ paused: paused, playing: playing }) .appendTo(self.$player); self.$controls = new Ox.Element() .bindEvent({ toggle: toggleControls }); self.$buttons = new Ox.Element() .css({ float: 'left', width: '16px', margin: '4px' }) .appendTo(self.$controls); self.$button = { play: new Ox.Button({ id: 'play', title: [ {id: 'play', title: 'play'}, {id: 'pause', title: 'pause'} ], tooltip: ['Play', 'Pause'], type: 'image' }) .bindEvent({ click: self.$video.togglePlay }), mute: new Ox.Button({ id: 'mute', title: [ {id: 'mute', title: 'mute'}, {id: 'unmute', title: 'unmute'} ], tooltip: ['Mute', 'Unmute'], type: 'image' }) .bindEvent({ click: self.$video.toggleMute }), size: new Ox.Button({ id: 'size', title: self.options.videoSize == 'fit' ? [ {id: 'fill', title: 'fill'}, {id: 'fit', title: 'fit'} ] : [ {id: 'fit', title: 'fit'}, {id: 'fill', title: 'fill'} ], tooltip: self.options.videoSize == 'fit' ? [ 'Fill Screen', 'Fit to Screen' ] : [ 'Fit to Screen', 'Fill Screen' ], type: 'image' }) .bindEvent({ click: toggleSize }), fullscreen: new Ox.Button({ id: 'size', title: [ {id: 'grow', title: 'grow'}, {id: 'shrink', title: 'shrink'} ], tooltip: [ 'Enter Fullscreen', 'Exit Fullscreen' ], type: 'image' }) .bindEvent({ click: toggleFullscreen }) } var i = 0; Ox.forEach(self.$button, function($button) { $button.css({ position: 'absolute', left: '8px', top: (8 + i++ * 24) + 'px' }) .appendTo(self.$buttons); }); self.$timelines = new Ox.Element() .css({ float: 'left', margin: '4px' }) .appendTo(self.$controls); self.$timeline = { large: new Ox.LargeTimeline({ duration: self.options.duration, position: self.options.position, subtitles: self.options.subtitles, videoId: self.options.videoId, width: getTimelineWidth() }) .css({ top: '4px' }) .bindEvent({ change: changeLargeTimeline }), small: new Ox.SmallTimeline({ duration: self.options.duration, position: self.options.position, subtitles: self.options.subtitles, videoId: self.options.videoId, width: getTimelineWidth() }) .css({ top: '76px' }) .bindEvent({ change: changeSmallTimeline }) }; Ox.forEach(self.$timeline, function($timeline) { $timeline.appendTo(self.$timelines); }); self.$panel = new Ox.SplitPanel({ elements: [ { element: self.$player }, { collapsed: !self.options.showControls, collapsible: true, element: self.$controls, size: 104 } ], orientation: 'vertical' }) .bindEvent({ resize: resizePanel }); self.$annotations = new Ox.Element() .bindEvent({ resize: resizeAnnotations, resizeend: resizeendAnnotations, toggle: toggleAnnotations }); that.$element = new Ox.SplitPanel({ elements: [ { element: self.$panel }, { collapsed: !self.options.showAnnotations, collapsible: true, element: self.$annotations, resizable: true, resize: [192, 256, 320, 384], size: self.options.annotationsSize } ], orientation: 'horizontal' }); function changeLargeTimeline(event, data) { self.options.position = data.position; self.$video.position(self.options.position); self.$timeline.small.options({ position: self.options.position }); } function changeSmallTimeline(event, data) { self.options.position = data.position; self.$video.position(self.options.position); self.$timeline.large.options({ position: self.options.position }); } function getPlayerHeight() { return self.options.height - self.options.showControls * 104 - 1; } function getPlayerWidth() { return self.options.width - (self.options.showAnnotations && !self.fullscreen) * self.options.annotationsSize - 1; } function getTimelineWidth() { return self.options.width - (self.options.showAnnotations && !self.fullscreen) * self.options.annotationsSize - 40 } function getVideoCSS() { var width = getPlayerWidth(), height = getPlayerHeight(), ratio = width / height, videoRatio = self.options.videoWidth / self.options.videoHeight, isWide = ratio < videoRatio; return self.options.videoSize == 'fit' ? { position: 'absolute', left: 0, right: 0, top: 0, bottom: 0, width: (isWide ? width : Math.round(height * videoRatio)) + 'px', height: (isWide ? Math.round(width / videoRatio) : height) + 'px', margin: 'auto' } : { width: (isWide ? Math.round(height * videoRatio) : width) + 'px', height: (isWide ? height : Math.round(width / videoRatio)) + 'px', margin: [ isWide ? '0' : Math.floor((height - width / videoRatio) / 2) + 'px', isWide ? Math.ceil((width - height * videoRatio) / 2) + 'px' : '0', isWide ? '0' : Math.ceil((height - width / videoRatio) / 2) + 'px', isWide ? Math.floor((width - height * videoRatio) / 2) + 'px' : '0' ].join(' ') }; } function paused() { } function playing(event, data) { self.options.position = data.position; self.$timeline.large.options({ position: self.options.position }); self.$timeline.small.options({ position: self.options.position }); } function resizeAnnotations(event, data) { self.options.annotationsSize = data; resizeVideoAndControls(); } function resizeendAnnotations(event, data) { self.options.annotationsSize = data; that.triggerEvent('change', { annotationsSize: self.options.annotationsSize }); } function resizeControls() { self.$timeline.large.options({ width: getTimelineWidth() }); self.$timeline.small.options({ width: getTimelineWidth() }); } function resizeElement(event, data) { // called on browser toggle self.options.height = data; resizeVideo(); } function resizePanel(event, data) { // called on annotations toggle resizeVideoAndControls(); } function resizeVideoAndControls() { resizeVideo(); resizeControls(); } function resizeVideo() { self.videoCSS = getVideoCSS(); self.$video.css(self.videoCSS); }; function toggleAnnotations(event, data) { self.options.showAnnotations = !data.collapsed; that.triggerEvent('change', { showAnnotations: self.options.showAnnotations }); } function toggleControls(event, data) { self.options.showControls = !data.collapsed; that.triggerEvent('change', { showControls: self.options.showControls }); } function toggleFullscreen() { self.fullscreen = !self.fullscreen; self.options.showAnnotations && that.$element.toggle(1); self.fullscreen && self.options.showControls && self.$panel.toggle(1); that.triggerEvent((self.fullscreen ? 'enter' : 'exit') + 'fullscreen', {}); } function toggleSize() { self.options.videoSize = self.options.videoSize == 'fit' ? 'fill' : 'fit'; resizeVideo(); that.triggerEvent('change', { videoSize: self.options.videoSize }); } self.onChange = function(key, value) { if (key == 'height') { resizeVideo(); } else if (key == 'position') { self.$video.position(value); } else if (key == 'width') { resizeVideoAndControls(); } } that.toggleAnnotations = function() { that.$element.toggle(1); //that.toggleAnnotations(null, !self.options.showAnnotations); }; that.toggleControls = function() { self.$panel.toggle(1); //that.toggleControls(null, !self.options.showControls); }; that.toggleMute = function() { self.$button.mute.trigger('click'); }; that.togglePlay = function() { self.$button.play.trigger('click'); }; that.toggleSize = function() { self.$button.size.trigger('click'); } return that; }