2011-11-05 16:46:53 +00:00
|
|
|
'use strict';
|
|
|
|
|
2011-05-17 08:58:03 +00:00
|
|
|
/*@
|
2012-05-31 10:32:54 +00:00
|
|
|
Ox.LargeVideoTimeline <f> LargeTimeline Object
|
2011-05-17 08:58:03 +00:00
|
|
|
options <o> Options object
|
2012-07-04 11:29:18 +00:00
|
|
|
self <o> Shared private variable
|
|
|
|
([options[, self]]) -> <o:Ox.Element> LargeTimeline Object
|
|
|
|
position <!> position
|
2011-05-17 08:58:03 +00:00
|
|
|
@*/
|
|
|
|
|
|
|
|
Ox.LargeVideoTimeline = function(options, self) {
|
|
|
|
|
2011-06-19 17:48:32 +00:00
|
|
|
self = self || {};
|
|
|
|
var that = Ox.Element({}, self)
|
2011-05-17 08:58:03 +00:00
|
|
|
.defaults({
|
2014-02-06 13:31:53 +00:00
|
|
|
chapters: [],
|
2011-05-17 08:58:03 +00:00
|
|
|
cuts: [],
|
2013-02-25 05:32:18 +00:00
|
|
|
disabled: false,
|
2011-05-17 08:58:03 +00:00
|
|
|
duration: 0,
|
|
|
|
find: '',
|
|
|
|
getImageURL: null,
|
|
|
|
'in': 0,
|
|
|
|
matches: [],
|
|
|
|
out: 0,
|
|
|
|
position: 0,
|
2013-02-20 10:57:38 +00:00
|
|
|
showInToOut: false,
|
2011-05-17 08:58:03 +00:00
|
|
|
subtitles: [],
|
2012-04-18 07:43:32 +00:00
|
|
|
type: '',
|
2011-05-17 08:58:03 +00:00
|
|
|
width: 0
|
|
|
|
})
|
|
|
|
.options(options || {})
|
2012-05-28 19:35:41 +00:00
|
|
|
.update({
|
|
|
|
find: setSubtitles,
|
|
|
|
'in': function() {
|
|
|
|
setPointMarker('in');
|
|
|
|
},
|
|
|
|
out: function() {
|
|
|
|
setPointMarker('out');
|
|
|
|
},
|
|
|
|
position: setPosition,
|
|
|
|
subtitles: setSubtitles,
|
2012-06-15 13:20:07 +00:00
|
|
|
type: setType,
|
2012-05-28 19:35:41 +00:00
|
|
|
width: setWidth
|
|
|
|
})
|
2012-12-29 16:43:32 +00:00
|
|
|
.addClass('OxLargeVideoTimeline OxMedia')
|
2013-12-06 20:43:00 +00:00
|
|
|
.on({
|
|
|
|
mouseleave: mouseleave,
|
|
|
|
mousemove: mousemove
|
|
|
|
});
|
2013-02-25 05:32:18 +00:00
|
|
|
|
|
|
|
if (!self.options.disabled) {
|
|
|
|
that.bindEvent({
|
|
|
|
anyclick: click,
|
|
|
|
dragstart: dragstart,
|
2013-07-19 08:42:25 +00:00
|
|
|
drag: drag,
|
|
|
|
dragend: dragend
|
2013-02-25 05:32:18 +00:00
|
|
|
});
|
|
|
|
}
|
2011-05-17 08:58:03 +00:00
|
|
|
|
2012-06-15 13:20:07 +00:00
|
|
|
self.$cuts = [];
|
|
|
|
self.$pointMarker = {};
|
|
|
|
self.$tiles = {};
|
|
|
|
self.$tooltip = Ox.Tooltip({animate: false});
|
|
|
|
self.center = Math.floor(self.options.width / 2);
|
|
|
|
self.fps = 25;
|
|
|
|
self.height = 64;
|
2013-07-13 13:58:52 +00:00
|
|
|
self.isAsync = self.options.getImageURL.length == 3;
|
2012-06-15 13:29:06 +00:00
|
|
|
self.tileWidth = 1500;
|
2011-05-17 08:58:03 +00:00
|
|
|
self.tiles = self.options.duration * self.fps / self.tileWidth;
|
|
|
|
|
|
|
|
self.$timeline = $('<div>')
|
2012-06-15 13:20:07 +00:00
|
|
|
.css({left: self.center + 'px'})
|
2013-03-06 12:26:57 +00:00
|
|
|
.appendTo(that);
|
2011-05-17 08:58:03 +00:00
|
|
|
|
2014-02-02 18:48:45 +00:00
|
|
|
setTimeout(setSubtitles);
|
2011-05-17 08:58:03 +00:00
|
|
|
|
2013-02-20 10:57:38 +00:00
|
|
|
if (self.options.showInToOut) {
|
|
|
|
if (self.options['in']) {
|
|
|
|
$('<div>')
|
|
|
|
.addClass('OxOverlay')
|
|
|
|
.css({
|
|
|
|
left: 0,
|
|
|
|
width: self.options['in'] * self.fps + 'px',
|
|
|
|
})
|
|
|
|
.appendTo(self.$timeline);
|
|
|
|
}
|
|
|
|
if (self.options.out) {
|
|
|
|
$('<div>')
|
|
|
|
.addClass('OxOverlay')
|
|
|
|
.css({
|
|
|
|
left: self.options.out * self.fps + 'px',
|
|
|
|
width: (self.options.duration - self.options.out) * self.fps + 'px',
|
|
|
|
})
|
|
|
|
.appendTo(self.$timeline);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-02 18:48:45 +00:00
|
|
|
setTimeout(function() {
|
2014-02-06 13:39:05 +00:00
|
|
|
var chapters = self.options.chapters.slice(1).map(function(chapter) {
|
|
|
|
return chapter.position;
|
|
|
|
});
|
2014-02-06 13:31:53 +00:00
|
|
|
Ox.unique(chapters.concat(self.options.cuts)).forEach(function(v, i) {
|
2014-02-02 18:48:45 +00:00
|
|
|
self.$cuts[i] = $('<img>')
|
2014-02-06 13:31:53 +00:00
|
|
|
.addClass(Ox.contains(chapters, v) ? 'OxChapter' : 'OxCut')
|
2014-02-02 18:48:45 +00:00
|
|
|
.css({left: (v * self.fps) + 'px'})
|
|
|
|
.appendTo(self.$timeline);
|
|
|
|
});
|
2014-02-04 09:32:50 +00:00
|
|
|
// performs better
|
2014-02-06 13:31:53 +00:00
|
|
|
self.$timeline.find('.OxChapter').attr({src: Ox.UI.getImageURL('markerChapter')});
|
2014-02-02 18:48:45 +00:00
|
|
|
self.$timeline.find('.OxCut').attr({src: Ox.UI.getImageURL('markerCut')});
|
2011-05-17 08:58:03 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
self.$markerPosition = $('<img>')
|
|
|
|
.addClass('OxMarkerPosition')
|
2012-06-15 13:20:07 +00:00
|
|
|
.attr({src: Ox.UI.getImageURL('markerPosition')})
|
|
|
|
.appendTo(that);
|
|
|
|
|
2011-05-17 08:58:03 +00:00
|
|
|
setMarker();
|
|
|
|
|
|
|
|
['in', 'out'].forEach(function(point) {
|
|
|
|
var titlecase = Ox.toTitleCase(point);
|
2011-05-18 18:30:58 +00:00
|
|
|
self.$pointMarker[point] = $('<img>')
|
2011-05-17 08:58:03 +00:00
|
|
|
.addClass('OxMarkerPoint' + titlecase)
|
2012-06-15 13:20:07 +00:00
|
|
|
.attr({src: Ox.UI.getImageURL('marker' + titlecase)})
|
2011-05-17 08:58:03 +00:00
|
|
|
.appendTo(self.$timeline);
|
2011-05-18 18:30:58 +00:00
|
|
|
setPointMarker(point);
|
2011-05-17 08:58:03 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
setWidth();
|
|
|
|
setPosition();
|
|
|
|
|
2011-09-17 11:49:29 +00:00
|
|
|
function click(data) {
|
2011-09-17 07:09:17 +00:00
|
|
|
self.options.position = Ox.round(Ox.limit(
|
2011-09-17 11:49:29 +00:00
|
|
|
getPosition(data), 0, self.options.duration
|
2011-09-17 07:09:17 +00:00
|
|
|
), 3);
|
2011-05-17 08:58:03 +00:00
|
|
|
setPosition();
|
2013-08-27 11:38:01 +00:00
|
|
|
that.triggerEvent('position', {position: self.options.position});
|
2011-05-17 08:58:03 +00:00
|
|
|
}
|
|
|
|
|
2011-09-17 11:49:29 +00:00
|
|
|
function dragstart(data) {
|
2013-07-19 08:42:25 +00:00
|
|
|
Ox.$body.addClass('OxDragging');
|
2011-09-17 11:49:29 +00:00
|
|
|
self.drag = {x: data.clientX};
|
2011-05-17 08:58:03 +00:00
|
|
|
}
|
|
|
|
|
2011-09-17 11:49:29 +00:00
|
|
|
function drag(data) {
|
2011-09-17 07:09:17 +00:00
|
|
|
self.options.position = Ox.round(Ox.limit(
|
2011-09-17 11:49:29 +00:00
|
|
|
self.options.position + (self.drag.x - data.clientX) / self.fps,
|
2011-05-17 08:58:03 +00:00
|
|
|
0, self.options.duration
|
2011-09-17 07:09:17 +00:00
|
|
|
), 3);
|
2011-09-17 11:49:29 +00:00
|
|
|
self.drag.x = data.clientX;
|
2011-05-17 08:58:03 +00:00
|
|
|
setPosition();
|
2013-08-27 11:38:01 +00:00
|
|
|
that.triggerEvent('positioning', {position: self.options.position});
|
2011-05-17 08:58:03 +00:00
|
|
|
}
|
|
|
|
|
2013-07-19 08:42:25 +00:00
|
|
|
function dragend() {
|
|
|
|
Ox.$body.removeClass('OxDragging');
|
2013-08-27 11:38:01 +00:00
|
|
|
that.triggerEvent('position', {position: self.options.position});
|
2013-07-19 08:42:25 +00:00
|
|
|
}
|
|
|
|
|
2013-07-13 13:58:52 +00:00
|
|
|
function getImageURL(i, callback) {
|
|
|
|
if (!self.isAsync) {
|
|
|
|
callback(self.options.getImageURL(self.options.type, i));
|
|
|
|
} else {
|
|
|
|
self.options.getImageURL(self.options.type, i, callback);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-05-17 08:58:03 +00:00
|
|
|
function getPosition(e) {
|
2012-06-15 13:20:07 +00:00
|
|
|
return self.options.position + (
|
|
|
|
e.clientX - that.offset().left - self.center - 1
|
|
|
|
) / self.fps;
|
2011-05-17 08:58:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function mouseleave(e) {
|
|
|
|
self.clientX = 0;
|
|
|
|
self.clientY = 0;
|
|
|
|
self.$tooltip.hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
function mousemove(e) {
|
|
|
|
self.clientX = e.clientX;
|
|
|
|
self.clientY = e.clientY;
|
|
|
|
updateTooltip();
|
|
|
|
}
|
|
|
|
|
|
|
|
function setMarker() {
|
2012-06-15 13:20:07 +00:00
|
|
|
self.$markerPosition.css({left: self.center + 'px'});
|
2011-05-17 08:58:03 +00:00
|
|
|
}
|
|
|
|
|
2011-05-18 18:30:58 +00:00
|
|
|
function setPointMarker(point) {
|
|
|
|
self.$pointMarker[point].css({
|
|
|
|
left: (self.options[point] * self.fps) + 'px'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-05-17 08:58:03 +00:00
|
|
|
function setPosition() {
|
2012-06-13 08:28:21 +00:00
|
|
|
self.tile = Math.floor(self.options.position * self.fps / self.tileWidth);
|
2011-05-17 08:58:03 +00:00
|
|
|
self.$timeline.css({
|
|
|
|
marginLeft: (-self.options.position * self.fps) + 'px'
|
|
|
|
});
|
|
|
|
Ox.loop(
|
|
|
|
Math.max(self.tile - 1, 0),
|
|
|
|
Math.min(self.tile + 2, self.tiles),
|
|
|
|
function(i) {
|
|
|
|
if (!self.$tiles[i]) {
|
2013-07-13 13:58:52 +00:00
|
|
|
if (self.isAsync) {
|
|
|
|
self.$tiles[i] = true;
|
|
|
|
}
|
|
|
|
getImageURL(i, function(url) {
|
|
|
|
self.$tiles[i] = $('<img>')
|
|
|
|
.attr({src: url})
|
|
|
|
.css({left: (i * self.tileWidth) + 'px'})
|
|
|
|
.appendTo(self.$timeline);
|
|
|
|
});
|
2011-05-17 08:58:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
);
|
|
|
|
if (self.clientX && self.clientY) {
|
|
|
|
updateTooltip();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function setSubtitles() {
|
2012-02-19 18:26:57 +00:00
|
|
|
that.find('.OxSubtitle').remove();
|
2011-05-17 08:58:03 +00:00
|
|
|
self.$subtitles = [];
|
|
|
|
self.options.subtitles.forEach(function(subtitle, i) {
|
2012-01-02 14:05:14 +00:00
|
|
|
var found = self.options.find
|
|
|
|
&& subtitle.text.toLowerCase().indexOf(self.options.find.toLowerCase()) > -1;
|
2011-05-17 08:58:03 +00:00
|
|
|
self.$subtitles[i] = $('<div>')
|
2011-05-19 18:34:53 +00:00
|
|
|
.addClass('OxSubtitle' + (found ? ' OxHighlight' : ''))
|
2011-05-17 08:58:03 +00:00
|
|
|
.css({
|
2013-08-06 18:18:08 +00:00
|
|
|
left: Math.round(subtitle['in'] * self.fps) + 'px',
|
|
|
|
width: Math.round(((subtitle.out - subtitle['in']) * self.fps) - 2) + 'px'
|
2011-05-17 08:58:03 +00:00
|
|
|
})
|
2012-06-03 08:41:18 +00:00
|
|
|
.html(Ox.highlight(
|
2012-06-15 16:26:18 +00:00
|
|
|
subtitle.text, self.options.find, 'OxHighlight', true
|
2012-06-03 08:41:18 +00:00
|
|
|
))
|
2011-06-19 17:48:32 +00:00
|
|
|
.appendTo(self.$timeline);
|
2011-05-17 08:58:03 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2012-06-15 13:20:07 +00:00
|
|
|
function setType() {
|
|
|
|
Ox.forEach(self.$tiles, function($tile, i) {
|
2013-07-13 13:58:52 +00:00
|
|
|
getImageURL(i, function(url) {
|
|
|
|
$tile.attr({src: url});
|
|
|
|
});
|
2012-06-15 13:20:07 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-05-17 08:58:03 +00:00
|
|
|
function setWidth() {
|
2012-06-13 08:28:21 +00:00
|
|
|
self.center = Math.floor(self.options.width / 2);
|
2011-05-17 08:58:03 +00:00
|
|
|
that.css({
|
|
|
|
width: self.options.width + 'px'
|
|
|
|
});
|
|
|
|
self.$timeline.css({
|
|
|
|
left: self.center + 'px'
|
|
|
|
});
|
|
|
|
setMarker();
|
|
|
|
}
|
|
|
|
|
|
|
|
function triggerPositionEvent() {
|
2012-06-15 13:20:07 +00:00
|
|
|
that.triggerEvent('position', {position: self.options.position});
|
2011-05-17 08:58:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function updateTooltip() {
|
|
|
|
var position = getPosition(self);
|
|
|
|
if (position >= 0 && position <= self.options.duration) {
|
|
|
|
self.$tooltip
|
|
|
|
.options({
|
|
|
|
title: Ox.formatDuration(position, 3)
|
|
|
|
})
|
|
|
|
.show(self.clientX, self.clientY);
|
|
|
|
} else {
|
|
|
|
self.$tooltip.hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return that;
|
|
|
|
|
|
|
|
};
|