Ox.SmallVideoTimeline = function(options, self) { self = self || {}; var that = Ox.Element({}, self) .defaults({ _offset: 0, // hack for cases where all these position: absolute elements have to go into a float: left duration: 0, editing: false, 'in': 0, out: 0, paused: false, showMilliseconds: 0, timeline: '', type: 'player', width: 256 }) .options(options || {}) .addClass('OxSmallVideoTimeline') .css(Ox.extend({ width: self.options.width + 'px' }, self.options.type == 'player' ? { background: 'rgb(0, 0, 0)', borderRadius: '8px' } : {})); self.height = self.options.type == 'player' ? 16 : 24; self.imageLeft = self.options.type == 'player' ? 8 : 4; self.imageWidth = self.options.width - (self.options.type == 'player' ? 16 : 8) self.imageHeight = self.options.type == 'player' ? 16 : 18; self.interfaceLeft = self.options.type == 'player' ? 0 : 4; self.interfaceTop = self.options.type == 'player' ? 0 : 2; self.interfaceWidth = self.options.type == 'player' ? self.options.width : self.imageWidth; that.css({ height: self.height + 'px' }); self.$image = getTimelineImage().appendTo(that); self.$interface = Ox.Element() .addClass('OxInterface') .css({ position: 'absolute', left: self.interfaceLeft + 'px', top: self.interfaceTop + 'px', width: self.interfaceWidth + 'px', height: '20px', zIndex: 11 }) .bind({ mousedown: mousedown, mouseleave: mouseleave, mousemove: mousemove }) .bindEvent({ drag: function(event, e) { mousedown(e); } }) .appendTo(that); if (self.options.type == 'player') { self.$positionMarker = $('
') .css({ position: 'absolute', width: '14px', height: '14px', border: '1px solid rgba(0, 0, 0, 0.5)', borderRadius: '8px' }) .append( self.$positionMarkerRing = $('
') .css({ width: '10px', height: '10px', border: '2px solid rgba(255, 255, 255, ' + (self.options.paused ? 0.5 : 1) + ')', borderRadius: '7px', }) .append( $('
') .css({ width: '8px', height: '8px', border: '1px solid rgba(0, 0, 0, 0.5)', borderRadius: '5px', }) ) ) .appendTo(that.$element); } else { self.$positionMarker = $('') .attr({ src: Ox.UI.PATH + 'png/videoMarkerPlay.png' }) .css({ position: 'absolute', top: '2px', width: '9px', height: '5px', zIndex: 10 }) .appendTo(that.$element); } setPositionMarker(); if (self.options.type == 'editor') { self.$pointMarker = {}; ['in', 'out'].forEach(function(point) { var titleCase = Ox.toTitleCase(point); self.$pointMarker[point] = $('') .addClass('OxPointMarker' + titleCase) .attr({ src: Ox.UI.PATH + 'png/videoMarker' + titleCase + '.png' }) .css({ position: 'absolute', top: '16px', width: '6px', height: '6px', marginLeft: (point == 'in' ? -1 : 4) + 'px', zIndex: 10 }) .appendTo(that.$element); setPointMarker(point); }); } self.$tooltip = Ox.Tooltip({ animate: false }).css({ textAlign: 'center' }); function getPosition(e) { var position = ( (e.offsetX ? e.offsetX : e.clientX - $(e.target).offset().left) - (self.options.type == 'player' ? 8 : 0) ) * self.options.duration / self.imageWidth; return Ox.limit(position, 0, self.options.duration); } function getSubtitle(position) { var subtitle = ''; Ox.forEach(self.options.subtitles, function(v) { if (v['in'] <= position && v.out > position) { subtitle = v; return false; } }); return subtitle; } function getTimelineImage() { return Ox.SmallVideoTimelineImage({ duration: self.options.duration, editing: self.options.editing, 'in': self.options['in'], out: self.options.out, results: self.options.results, subtitles: self.options.subtitles, timeline: self.options.timeline, width: self.imageWidth, type: self.options.type }) .css({ position: 'absolute', left: self.imageLeft + 'px', width: self.imageWidth + 'px' }); } function mousedown(e) { if ($(e.target).is('.OxInterface')) { self.options.position = getPosition(e); setPositionMarker(); if (!self.triggered) { that.triggerEvent('position', { position: self.options.position }); self.triggered = true; setTimeout(function() { self.triggered = false; }, 250); } } } function mouseleave() { self.$tooltip.hide(); } function mousemove(e) { var position, subtitle; if ($(e.target).is('.OxInterface')) { position = getPosition(e); subtitle = getSubtitle(position); self.$tooltip.options({ title: subtitle ? '' + Ox.highlight(subtitle.text, self.options.find, 'OxHighlight').replace(/\n/g, '
') + '

' + Ox.formatDuration(subtitle['in'], self.options.showMilliseconds) + ' - ' + Ox.formatDuration(subtitle['out'], self.options.showMilliseconds) : Ox.formatDuration(position, self.options.showMilliseconds) }) .show(e.clientX, e.clientY); } else { self.$tooltip.hide(); } } function setPointMarker(point) { self.$pointMarker[point].css({ left: self.imageLeft + Math.round( self.options[point] * self.imageWidth / self.options.duration ) + 'px' }); } function setPositionMarker() { self.$positionMarker.css({ left: self.interfaceLeft + Math.round( self.options.position * self.imageWidth / self.options.duration ) - (self.options.type == 'editor' ? 4 : 0) + self.options._offset + 'px', }); } function setWidth() { self.imageWidth = self.options.width - (self.options.type == 'player' ? 16 : 8); self.interfaceWidth = self.options.type == 'player' ? self.options.width : self.imageWidth; that.css({ width: self.options.width + 'px' }); self.$image.options({ width: self.imageWidth }).css({ width: self.imageWidth + 'px' }); self.$interface.css({ width: self.interfaceWidth + 'px' }); setPositionMarker(); if (self.options.type == 'editor') { setPointMarker('in'); setPointMarker('out'); } } self.setOption = function(key, value) { if (key == 'duration') { self.$image.options({ duration: value }); } else if (key == 'paused') { self.$positionMarkerRing.css({ borderColor: 'rgba(255, 255, 255, ' + (self.options.paused ? 0.5 : 1) + ')' }) } else if (key == 'position') { setPositionMarker(); } else if (key == 'results') { self.$image.options({ results: value }); } else if (key == 'subtitles') { self.$image.options({ subtitles: value }); } else if (key == 'width') { setWidth(); } }; return that; };