add new timeline and find input to video player
This commit is contained in:
parent
ac2ea5f53d
commit
ce33d3650a
6 changed files with 326 additions and 162 deletions
|
@ -27,14 +27,15 @@ Ox.load('UI', {
|
|||
{'in': 5780.235, out: 5782.435},
|
||||
{'in': 5881.365, out: 5886.635}
|
||||
],
|
||||
timeline = 'http://next.0xdb.org/' + id + '/timeline.16.png',
|
||||
timeline = 'png/timeline.16.png',
|
||||
url = 'http://next.0xdb.org/' + id + '/96p.webm',
|
||||
videoSize = getVideoSize(),
|
||||
$videos = [
|
||||
Ox.VideoPlayer({
|
||||
controls: ['play', 'mute', 'fullscreen', 'scale', 'timeline', 'position'],
|
||||
enableFind: true,
|
||||
enableFullscreen: true,
|
||||
enableKeyboard: true,
|
||||
find: 'brick',
|
||||
focus: 'mouseenter',
|
||||
height: 192,
|
||||
'in': 3128.725,
|
||||
|
@ -47,7 +48,9 @@ Ox.load('UI', {
|
|||
showIconOnLoad: true,
|
||||
showProgress: false,
|
||||
subtitles: 'srt/' + id + '.srt',
|
||||
timeline: timeline,
|
||||
timeline: function(i) {
|
||||
return 'png/timeline.16.' + i + '.png';
|
||||
},
|
||||
title: '<b>Brick</b> - Rian Johnson - 2005',
|
||||
video: url + '?' + + Ox.random(1000000),
|
||||
width: 360
|
||||
|
|
BIN
demos/video/png/logo.png
Normal file
BIN
demos/video/png/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
|
@ -3,6 +3,7 @@ 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,
|
||||
getTimelineURL: null,
|
||||
|
@ -226,13 +227,15 @@ Ox.SmallVideoTimeline = function(options, self) {
|
|||
self.$positionMarker.css({
|
||||
left: self.interfaceLeft + Math.round(
|
||||
self.options.position * self.imageWidth / self.options.duration
|
||||
) - (self.options.type == 'editor' ? 4 : 0) + 'px',
|
||||
) - (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'
|
||||
});
|
||||
|
@ -252,10 +255,24 @@ Ox.SmallVideoTimeline = function(options, self) {
|
|||
}
|
||||
|
||||
self.setOption = function(key, value) {
|
||||
if (key == 'paused') {
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ Ox.SmallVideoTimelineImage = function(options, self) {
|
|||
type: 'player'
|
||||
})
|
||||
.options(options || {})
|
||||
.addClass('OxSmallVideoTimeline')
|
||||
.css({
|
||||
position: 'absolute',
|
||||
width: self.options.width + 'px'
|
||||
|
@ -84,6 +83,8 @@ Ox.SmallVideoTimelineImage = function(options, self) {
|
|||
.appendTo(that.$element);
|
||||
|
||||
function getImageURL(image, callback) {
|
||||
Ox.print(image == 'results' || image == 'selection' ?
|
||||
self.options.width : Math.ceil(self.options.duration))
|
||||
var width = image == 'results' || image == 'selection' ?
|
||||
self.options.width : Math.ceil(self.options.duration),
|
||||
height = self.imageHeight,
|
||||
|
@ -160,21 +161,33 @@ Ox.SmallVideoTimelineImage = function(options, self) {
|
|||
});
|
||||
});
|
||||
} else if (image == 'timeline') {
|
||||
var counter = 0,
|
||||
images = Math.ceil(self.options.duration / 3600),
|
||||
var $image, counter, images,
|
||||
top = self.options.type == 'player' ? 0 : 1;
|
||||
Ox.loop(images, function(i) {
|
||||
var $image = $('<img>')
|
||||
if (Ox.isString(self.options.timeline)) {
|
||||
$image = $('<img>')
|
||||
.attr({
|
||||
src: self.options.getTimelineURL(i)
|
||||
src: self.options.getTimelineURL(0)
|
||||
})
|
||||
.load(function() {
|
||||
context.drawImage($image[0], i * 3600, top);
|
||||
if (++counter == images) {
|
||||
callback(canvas.toDataURL());
|
||||
}
|
||||
context.drawImage($image[0])
|
||||
callback(canvas.toDataURL());
|
||||
});
|
||||
})
|
||||
} else {
|
||||
counter = 0;
|
||||
images = Math.ceil(self.options.duration / 3600);
|
||||
Ox.loop(images, function(i) {
|
||||
var $image = $('<img>')
|
||||
.attr({
|
||||
src: self.options.getTimelineURL(i)
|
||||
})
|
||||
.load(function() {
|
||||
context.drawImage($image[0], i * 3600, top);
|
||||
if (++counter == images) {
|
||||
callback(canvas.toDataURL());
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
if (image != 'timeline') {
|
||||
context.putImageData(imageData, 0, 0);
|
||||
|
|
|
@ -14,6 +14,8 @@ Ox.VideoPlayer <f> Generic Video Player
|
|||
is just empty space that separates left-aligned from right-aligned
|
||||
controls
|
||||
duration <n|-1> Duration (sec)
|
||||
enableFind <b|false> If true, enable find
|
||||
enableFullscreen <b|false> If true, enable fullscreen
|
||||
enableKeyboard <b|false> If true, enable keyboard controls
|
||||
externalControls <b|false> If true, controls are outside the video
|
||||
find <s|''> Query string
|
||||
|
@ -66,7 +68,9 @@ Ox.VideoPlayer = function(options, self) {
|
|||
.defaults({
|
||||
annotations: [],
|
||||
controls: [],
|
||||
duration: 86399,
|
||||
duration: 0,
|
||||
enableFind: false,
|
||||
enableFullscreen: false,
|
||||
enableKeyboard: false,
|
||||
externalControls: false,
|
||||
find: '',
|
||||
|
@ -135,6 +139,13 @@ Ox.VideoPlayer = function(options, self) {
|
|||
key_1: function() {
|
||||
toggleScale();
|
||||
},
|
||||
key_f: function() {
|
||||
// need timeout so the "f" doesn't appear in the input field
|
||||
setTimeout(self.$findInput.focusInput, 0);
|
||||
},
|
||||
key_g: function() {
|
||||
goToNextResult(1);
|
||||
},
|
||||
key_left: function() {
|
||||
setPosition(self.options.position - self.secondsPerFrame, true);
|
||||
},
|
||||
|
@ -145,7 +156,10 @@ Ox.VideoPlayer = function(options, self) {
|
|||
setPosition(self.options.position + self.secondsPerFrame, true);
|
||||
},
|
||||
key_shift_f: function() {
|
||||
toggleFullscreen(true);
|
||||
self.options.enableFullscreen && toggleFullscreen(true);
|
||||
},
|
||||
key_shift_g: function() {
|
||||
goToNextResult(-1);
|
||||
},
|
||||
key_space: function() {
|
||||
togglePaused(true);
|
||||
|
@ -196,15 +210,24 @@ Ox.VideoPlayer = function(options, self) {
|
|||
} else {
|
||||
Ox.get(self.options.subtitles, function(data) {
|
||||
self.options.subtitles = Ox.parseSRT(data);
|
||||
self.results = find(self.options.find);
|
||||
Ox.print('--setting results--', self.$timeline)
|
||||
if (self.options.duration) {
|
||||
self.$timeline && self.$timeline.options({
|
||||
results: self.results,
|
||||
subtitles: self.options.subtitles
|
||||
});
|
||||
} else {
|
||||
|
||||
}
|
||||
});
|
||||
//self.options.subtitles = [];
|
||||
self.options.subtitles = [];
|
||||
}
|
||||
}
|
||||
|
||||
self.results = find(self.options.find);
|
||||
|
||||
self.buffered = [];
|
||||
self.controlsTimeout;
|
||||
self.dragTimeout;
|
||||
|
||||
self.$videoContainer = $('<div>')
|
||||
.css({
|
||||
|
@ -304,7 +327,7 @@ Ox.VideoPlayer = function(options, self) {
|
|||
}
|
||||
}
|
||||
|
||||
if (self.options.subtitles.length) {
|
||||
if (self.options.subtitles.length || true) { // fixme
|
||||
self.$subtitle = $('<div>')
|
||||
//.addClass('OxSubtitle')
|
||||
.css({
|
||||
|
@ -339,6 +362,114 @@ Ox.VideoPlayer = function(options, self) {
|
|||
.appendTo(that.$element);
|
||||
}
|
||||
|
||||
if (self.options.enableFind) {
|
||||
|
||||
self.$find = $('<div>')
|
||||
.addClass('OxInterface')
|
||||
.css({
|
||||
position: 'absolute',
|
||||
right: '16px',
|
||||
top: (self.options.title ? 32 : 16) + 'px',
|
||||
width: '128px',
|
||||
borderRadius: '8px',
|
||||
opacity: 0
|
||||
})
|
||||
.css({
|
||||
backgroundImage: '-moz-linear-gradient(top, rgba(64, 64, 64, 0.5), rgba(0, 0, 0, 0.5))'
|
||||
})
|
||||
.css({
|
||||
backgroundImage: '-webkit-linear-gradient(top, rgba(64, 64, 64, 0.5), rgba(0, 0, 0, 0.5))'
|
||||
})
|
||||
.appendTo(that.$element);
|
||||
|
||||
self.$previousButton = Ox.Button({
|
||||
style: 'symbol',
|
||||
title: 'arrowLeft',
|
||||
tooltip: 'Previous [Shift+G]',
|
||||
type: 'image'
|
||||
})
|
||||
.css({float: 'left', opacity: 0.25})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
goToNextResult(-1);
|
||||
}
|
||||
})
|
||||
.appendTo(self.$find);
|
||||
|
||||
self.$nextButton = Ox.Button({
|
||||
style: 'symbol',
|
||||
title: 'arrowRight',
|
||||
tooltip: 'Next [G]',
|
||||
type: 'image'
|
||||
})
|
||||
.css({float: 'left', opacity: 0.25})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
goToNextResult(1);
|
||||
}
|
||||
})
|
||||
.appendTo(self.$find);
|
||||
|
||||
self.$findInput = Ox.Input({
|
||||
placeholder: 'Find',
|
||||
value: self.options.find,
|
||||
width: 86
|
||||
})
|
||||
.css({
|
||||
float: 'left',
|
||||
background: 'rgba(0, 0, 0, 0)',
|
||||
MozBoxShadow: '0 0 0',
|
||||
WebkitBoxShadow: '0 0 0'
|
||||
})
|
||||
.bindEvent({
|
||||
focus: function() {
|
||||
self.inputHasFocus = true;
|
||||
},
|
||||
blur: function() {
|
||||
self.inputHasFocus = false;
|
||||
submitFindInput();
|
||||
}
|
||||
})
|
||||
.appendTo(self.$find);
|
||||
|
||||
self.$findInput.children('input').css({
|
||||
width: (self.positionWidth - 6) + 'px',
|
||||
height: '16px',
|
||||
padding: '0 3px 0 3px',
|
||||
border: '0px',
|
||||
borderRadius: '8px',
|
||||
fontSize: '11px',
|
||||
color: 'rgb(255, 255, 255)'
|
||||
})
|
||||
.css({
|
||||
background: '-moz-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(64, 64, 64, 0.5))'
|
||||
})
|
||||
.css({
|
||||
background: '-webkit-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(64, 64, 64, 0.5))'
|
||||
});
|
||||
|
||||
self.$clearButton = Ox.Button({
|
||||
style: 'symbol',
|
||||
title: 'close',
|
||||
tooltip: 'Clear',
|
||||
type: 'image'
|
||||
})
|
||||
.css({float: 'left'})
|
||||
.bindEvent({
|
||||
click: function() {
|
||||
self.$findInput
|
||||
.options({value: ''})
|
||||
.focusInput();
|
||||
self.results = [];
|
||||
self.$timeline && self.$timeline.options({
|
||||
results: self.results
|
||||
});
|
||||
}
|
||||
})
|
||||
.appendTo(self.$find);
|
||||
|
||||
}
|
||||
|
||||
if (self.options.controls.length) {
|
||||
|
||||
self.$controls = Ox.Bar({
|
||||
|
@ -463,39 +594,9 @@ Ox.VideoPlayer = function(options, self) {
|
|||
.bindEvent('click', toggleSize)
|
||||
.appendTo(self.$controls);
|
||||
|
||||
}else if (control == 'timeline') {
|
||||
} else if (control == 'timeline') {
|
||||
|
||||
self.$timeline = Ox.Element()
|
||||
.addClass('timeline')
|
||||
.css({
|
||||
float: 'left',
|
||||
height: self.barHeight + 'px',
|
||||
background: 'rgba(0, 0, 0, 0.75)',
|
||||
borderRadius: self.barHeight / 2 + 'px'
|
||||
})
|
||||
.appendTo(self.$controls);
|
||||
|
||||
self.$timelineImages = Ox.Element()
|
||||
.addClass('timelineimages')
|
||||
.css({
|
||||
float: 'left',
|
||||
height: self.barHeight + 'px',
|
||||
marginLeft: self.barHeight / 2 + 'px'
|
||||
})
|
||||
.appendTo(self.$timeline);
|
||||
|
||||
self.$timelineImage = $('<img>')
|
||||
.addClass('timelineimage')
|
||||
.attr({
|
||||
src: self.options.timeline
|
||||
})
|
||||
.css({
|
||||
float: 'left',
|
||||
height: self.barHeight + 'px'
|
||||
})
|
||||
.appendTo(self.$timelineImages.$element);
|
||||
|
||||
///*
|
||||
/*
|
||||
if (self.options.showProgress) {
|
||||
self.$progress = $('<img>')
|
||||
.attr({
|
||||
|
@ -507,46 +608,18 @@ Ox.VideoPlayer = function(options, self) {
|
|||
})
|
||||
.appendTo(self.$timelineImages.$element);
|
||||
}
|
||||
//*/
|
||||
*/
|
||||
|
||||
self.$positionMarker = $('<div>')
|
||||
.css({
|
||||
float: 'left',
|
||||
width: '14px',
|
||||
height: '14px',
|
||||
border: '1px solid rgba(0, 0, 0, 0.5)',
|
||||
borderRadius: '8px'
|
||||
})
|
||||
.append(
|
||||
self.$positionMarkerRing = $('<div>')
|
||||
.css({
|
||||
width: '10px',
|
||||
height: '10px',
|
||||
border: '2px solid rgba(255, 255, 255, 0.5)',
|
||||
borderRadius: '7px',
|
||||
})
|
||||
.append(
|
||||
$('<div>')
|
||||
.css({
|
||||
width: '8px',
|
||||
height: '8px',
|
||||
border: '1px solid rgba(0, 0, 0, 0.5)',
|
||||
borderRadius: '5px',
|
||||
})
|
||||
)
|
||||
)
|
||||
.appendTo(self.$timeline.$element);
|
||||
|
||||
self.$timelineInterface = Ox.Element()
|
||||
.css({
|
||||
float: 'left',
|
||||
height: self.barHeight + 'px',
|
||||
})
|
||||
.appendTo(self.$controls);
|
||||
|
||||
self.$tooltip = Ox.Tooltip({
|
||||
animate: false
|
||||
});
|
||||
if (self.options.duration) {
|
||||
self.$timeline = getTimeline()
|
||||
} else {
|
||||
self.$timeline = Ox.Element()
|
||||
.css({
|
||||
float: 'left'
|
||||
})
|
||||
.html(' ');
|
||||
}
|
||||
self.$timeline.appendTo(self.$controls);
|
||||
|
||||
} else if (control == 'space') {
|
||||
|
||||
|
@ -659,6 +732,16 @@ Ox.VideoPlayer = function(options, self) {
|
|||
}
|
||||
}
|
||||
|
||||
function find(query) {
|
||||
query = query.toLowerCase();
|
||||
return query.length ? Ox.map(self.options.subtitles, function(subtitle) {
|
||||
return subtitle.text.toLowerCase().indexOf(query) > -1 ? {
|
||||
'in': subtitle['in'],
|
||||
out: subtitle.out
|
||||
} : null;
|
||||
}) : [];
|
||||
}
|
||||
|
||||
function formatPosition(position) {
|
||||
position = Ox.isUndefined(position) ? self.options.position : position;
|
||||
return Ox.formatDuration(position, self.options.showMilliseconds);
|
||||
|
@ -712,13 +795,6 @@ Ox.VideoPlayer = function(options, self) {
|
|||
padding: playIconPadding + 'px',
|
||||
borderRadius: Math.round(self.iconSize / 2) + 'px'
|
||||
};
|
||||
} else if (element == 'positionMarker') {
|
||||
var position = self.options.duration ?
|
||||
(self.options.position - self['in']) / self.options.duration : 0;
|
||||
css = {
|
||||
marginLeft: position * self.timelineImageWidth -
|
||||
self.timelineImageWidth - 8 + 'px',
|
||||
};
|
||||
} else if (element == 'poster' || element == 'video') {
|
||||
var playerWidth = self.width,
|
||||
playerHeight = self.height,
|
||||
|
@ -759,15 +835,6 @@ Ox.VideoPlayer = function(options, self) {
|
|||
css = {
|
||||
width: self.timelineWidth + 'px'
|
||||
};
|
||||
} else if (element == 'timelineImage' || element == 'timelineImages') {
|
||||
css = {
|
||||
width: self.timelineImageWidth + 'px'
|
||||
};
|
||||
} else if (element == 'timelineInterface') {
|
||||
css = {
|
||||
width: self.timelineWidth + 'px',
|
||||
marginLeft: -self.timelineWidth + 'px'
|
||||
};
|
||||
} else if (element == 'videoContainer') {
|
||||
css = {
|
||||
width: self.width + 'px',
|
||||
|
@ -841,6 +908,61 @@ Ox.VideoPlayer = function(options, self) {
|
|||
return subtitle;
|
||||
}
|
||||
|
||||
function getTimeline() {
|
||||
var $timeline = Ox.SmallVideoTimeline({
|
||||
_offset: getTimelineLeft(),
|
||||
duration: self.options.duration,
|
||||
getTimelineURL: Ox.isString(self.options.timeline) ?
|
||||
function() { return self.options.timeline; } :
|
||||
self.options.timeline,
|
||||
'in': self.options['in'],
|
||||
out: self.options.out,
|
||||
paused: self.options.paused,
|
||||
results: self.results,
|
||||
showMilliseconds: self.options.showMilliseconds,
|
||||
subtitles: self.options.subtitles,
|
||||
type: 'player',
|
||||
width: getTimelineWidth()
|
||||
})
|
||||
.css({
|
||||
float: 'left'
|
||||
})
|
||||
.bindEvent({
|
||||
position: function(data) {
|
||||
setPosition(data.position, true);
|
||||
}
|
||||
});
|
||||
//Ox.print('??', $timeline.find('.OxInterface'))
|
||||
$timeline.children().css({
|
||||
marginLeft: getTimelineLeft() + 'px'
|
||||
});
|
||||
$timeline.find('.OxInterface').css({
|
||||
marginLeft: getTimelineLeft() + 'px'
|
||||
});
|
||||
return $timeline;
|
||||
}
|
||||
|
||||
function getTimelineLeft() {
|
||||
var left = 0;
|
||||
Ox.forEach(self.options.controls, function(control) {
|
||||
if (control == 'timeline') {
|
||||
return false;
|
||||
}
|
||||
left += control == 'position' ? self.positionWidth : 16
|
||||
});
|
||||
return left;
|
||||
}
|
||||
|
||||
function getTimelineWidth() {
|
||||
return (self.options.fullscreen ? window.innerWidth : self.options.width) -
|
||||
self.options.controls.reduce(function(prev, curr) {
|
||||
return prev + (
|
||||
curr == 'timeline' || curr == 'space' ? 0 :
|
||||
curr == 'position' ? self.positionWidth : 16
|
||||
);
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function hideInterface() {
|
||||
Ox.print('hideInterface');
|
||||
self.interfaceTimeout = setTimeout(function() {
|
||||
|
@ -874,6 +996,8 @@ Ox.VideoPlayer = function(options, self) {
|
|||
|
||||
function loadedmetadata() {
|
||||
|
||||
var hadDuration = !!self.options.duration;
|
||||
|
||||
self.loaded = true;
|
||||
self.out = self.options.playInToOut &&
|
||||
self.options.out < self.video.duration ?
|
||||
|
@ -893,46 +1017,19 @@ Ox.VideoPlayer = function(options, self) {
|
|||
}
|
||||
}
|
||||
|
||||
if (self.$timeline) {
|
||||
if (!hadDuration) {
|
||||
self.$timeline.replaceWith(self.$timeline = getTimeline());
|
||||
}
|
||||
self.$timeline.options({
|
||||
duration: self.options.duration
|
||||
});
|
||||
}
|
||||
|
||||
if (self.options.enableKeyboard && self.options.focus == 'load') {
|
||||
that.gainFocus();
|
||||
}
|
||||
self.$timeline && self.$timelineInterface
|
||||
.bind({
|
||||
mousedown: mousedownTrack,
|
||||
mouseleave: mouseleaveTrack,
|
||||
mousemove: mousemoveTrack,
|
||||
})
|
||||
.bindEvent({
|
||||
drag: dragTrack,
|
||||
dragpause: dragpauseTrack,
|
||||
dragend: dragpauseTrack
|
||||
});
|
||||
}
|
||||
|
||||
function dragTrack(e) {
|
||||
setPosition(getPosition(e), true);
|
||||
if (self.dragTimeout) {
|
||||
clearTimeout(self.dragTimeout);
|
||||
self.dragTimeout = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function dragpauseTrack(e) {
|
||||
self.video.currentTime = self.options.position;
|
||||
}
|
||||
|
||||
function mousedownTrack(e) {
|
||||
setPosition(getPosition(e), true);
|
||||
}
|
||||
|
||||
function mouseleaveTrack(e) {
|
||||
self.$tooltip.hide();
|
||||
}
|
||||
|
||||
function mousemoveTrack(e) {
|
||||
self.$tooltip.options({
|
||||
title: formatPosition(getPosition(e))
|
||||
}).show(e);
|
||||
}
|
||||
|
||||
function parsePositionInput(str) {
|
||||
|
@ -1019,7 +1116,9 @@ Ox.VideoPlayer = function(options, self) {
|
|||
self.posterIsVisible = false;
|
||||
}
|
||||
self.$subtitle && setSubtitle();
|
||||
self.$timeline && self.$positionMarker.css(getCSS('positionMarker'));
|
||||
self.$timeline && self.$timeline.options({
|
||||
position: self.options.position
|
||||
});
|
||||
self.$position && self.$position.html(formatPosition());
|
||||
}
|
||||
|
||||
|
@ -1031,12 +1130,13 @@ Ox.VideoPlayer = function(options, self) {
|
|||
self.iconLeft = parseInt((self.width - self.iconSize) / 2),
|
||||
self.iconTop = parseInt((self.height - self.iconSize) / 2);
|
||||
if (self.$timeline || self.$space) {
|
||||
self.timelineWidth = self.width - self.options.controls.reduce(function(prev, curr) {
|
||||
return prev + (
|
||||
curr == 'timeline' || curr == 'space' ? 0 :
|
||||
curr == 'position' ? self.positionWidth : 16
|
||||
);
|
||||
}, 0);
|
||||
self.timelineWidth = self.width -
|
||||
self.options.controls.reduce(function(prev, curr) {
|
||||
return prev + (
|
||||
curr == 'timeline' || curr == 'space' ? 0 :
|
||||
curr == 'position' ? self.positionWidth : 16
|
||||
);
|
||||
}, 0);
|
||||
if (self.$timeline) {
|
||||
self.timelineImageWidth = self.timelineWidth - self.barHeight;
|
||||
}
|
||||
|
@ -1052,12 +1152,11 @@ Ox.VideoPlayer = function(options, self) {
|
|||
self.$title && self.$title.animate(getCSS('title'), ms);
|
||||
self.$controls && self.$controls.animate(getCSS('controls'), ms);
|
||||
if (self.$timeline) {
|
||||
self.$timeline.animate(getCSS('timeline'), ms);
|
||||
self.$timelineImages.animate(getCSS('timelineImages'), ms);
|
||||
self.$timelineImage.animate(getCSS('timelineImage'), ms);
|
||||
self.$progress && self.$progress.animate(getCSS('progress'), ms);
|
||||
self.$positionMarker.animate(getCSS('positionMarker'), ms);
|
||||
self.$timelineInterface.animate(getCSS('timelineInterface'), ms);
|
||||
self.$timeline.animate(getCSS('timeline'), ms, function() {
|
||||
self.$timeline.options({
|
||||
width: self.timelineWidth
|
||||
})
|
||||
});
|
||||
}
|
||||
self.$space && self.$space.animate(getCSS('space'), ms);
|
||||
}
|
||||
|
@ -1115,6 +1214,37 @@ Ox.VideoPlayer = function(options, self) {
|
|||
}).show();
|
||||
}
|
||||
|
||||
function submitFindInput() {
|
||||
self.options.find = self.$findInput.options('value');
|
||||
self.results = find(self.options.find);
|
||||
self.$timeline && self.$timeline.options({
|
||||
results: self.results
|
||||
});
|
||||
if (self.results.length) {
|
||||
setPosition(self.results[0]['in'] + self.secondsPerFrame, true);
|
||||
self.currentResult = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function goToNextResult(direction) {
|
||||
var found = false,
|
||||
position = 0;
|
||||
direction == -1 && self.results.reverse();
|
||||
Ox.forEach(self.results, function(v) {
|
||||
if (direction == 1 ? v['in'] > self.options.position : v['out'] < self.options.position) {
|
||||
position = v['in'];
|
||||
found = true;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
direction == -1 && self.results.reverse();
|
||||
if (!found) {
|
||||
position = self.results[direction == 1 ? 0 : self.results.length - 1]['in'];
|
||||
}
|
||||
Ox.print('>>', self.results, position)
|
||||
setPosition(position + self.secondsPerFrame, true);
|
||||
}
|
||||
|
||||
function submitPositionInput() {
|
||||
self.$positionInput.hide();
|
||||
self.$position.html('').show();
|
||||
|
@ -1211,8 +1341,8 @@ Ox.VideoPlayer = function(options, self) {
|
|||
|
||||
function togglePaused(toggleButton) {
|
||||
self.options.paused = !self.options.paused;
|
||||
self.$timeline && self.$positionMarkerRing.css({
|
||||
borderColor: 'rgba(255, 255, 255, ' + (self.options.paused ? 0.5 : 1) + ')'
|
||||
self.$timeline && self.$timeline.options({
|
||||
paused: self.options.paused
|
||||
});
|
||||
if (self.options.paused) {
|
||||
self.video.pause();
|
||||
|
|
|
@ -3864,11 +3864,12 @@ Ox.highlight <f> Highlight matches in a string
|
|||
> Ox.highlight('foobar', 'foo', 'match')
|
||||
'<span class="match">foo</span>bar'
|
||||
@*/
|
||||
// fixme: with regexp, special chars would have to be escaped
|
||||
Ox.highlight = function(txt, str, classname) {
|
||||
return txt.replace(
|
||||
return str.length ? txt.replace(
|
||||
new RegExp('(' + str + ')', 'ig'),
|
||||
'<span class="' + classname + '">$1</span>'
|
||||
);
|
||||
) : txt;
|
||||
};
|
||||
|
||||
/*@
|
||||
|
|
Loading…
Reference in a new issue