2017-09-24 01:54:46 +02:00
if ( Debug . debug )
console . log ( "Loading: Resizer.js" ) ;
2018-05-12 02:51:58 +02:00
var StretchMode = {
2018-05-13 21:05:11 +02:00
NO _STRETCH : 0 ,
2018-05-24 23:29:30 +02:00
BASIC : 1 ,
HYBRID : 2 ,
CONDITIONAL : 3
2018-05-12 02:51:58 +02:00
}
2018-05-08 23:35:16 +02:00
class Resizer {
2017-09-24 01:54:46 +02:00
2018-05-12 02:51:58 +02:00
constructor ( videoData ) {
this . conf = videoData ;
2018-05-08 23:35:16 +02:00
this . video = videoData . video ;
2018-05-12 02:51:58 +02:00
2018-05-18 23:26:20 +02:00
this . scaler = new Scaler ( this . conf ) ;
this . stretcher = new Stretcher ( this . conf ) ;
this . zoom = new Zoom ( this . conf ) ;
2018-05-12 02:51:58 +02:00
// load up default values
2018-05-13 15:22:28 +02:00
this . correctedVideoDimensions = { } ;
this . currentCss = { } ;
2018-05-12 02:51:58 +02:00
this . stretch = { mode : ExtensionConf . stretch . initialMode } ;
// restore watchdog. While true, applyCss() tries to re-apply new css until this value becomes false again
// value becomes false when width and height of <video> tag match with what we want to set. Only necessary when
// calling _res_restore() for some weird reason.
this . restore _wd = false ;
2018-05-13 15:22:28 +02:00
this . lastAr = { type : 'original' } ;
2018-05-16 23:26:47 +02:00
this . destroyed = false ;
2017-09-24 01:54:46 +02:00
}
2018-05-23 23:57:51 +02:00
start ( ) {
this . startCssWatcher ( ) ;
}
stop ( ) {
this . stopCssWatcher ( ) ;
}
2018-05-16 23:26:47 +02:00
destroy ( ) {
this . destroyed = true ;
this . stopCssWatcher ( ) ;
}
2018-05-13 15:22:28 +02:00
2018-05-24 23:29:30 +02:00
2018-05-12 02:51:58 +02:00
setAr ( ar , lastAr ) {
2018-05-08 23:35:16 +02:00
if ( Debug . debug ) {
console . log ( '[Resizer::setAr] trying to set ar. New ar:' , ar )
}
2017-09-24 01:54:46 +02:00
2018-05-12 02:51:58 +02:00
if ( lastAr ) {
this . lastAr = lastAr ;
} else {
2018-05-13 15:22:28 +02:00
if ( isNaN ( ar ) ) {
this . lastAr = { type : 'legacy' , ar : ar }
} else {
this . lastAr = { type : 'static' , ar : ar } ;
}
2018-05-12 02:51:58 +02:00
}
2018-05-01 23:09:58 +02:00
2018-05-08 23:35:16 +02:00
if ( ! this . video ) {
2018-05-16 20:26:55 +02:00
// console.log("No video detected.")
2018-05-16 23:26:47 +02:00
this . videoData . destroy ( ) ;
2018-05-08 23:35:16 +02:00
}
2018-05-01 23:09:58 +02:00
2018-05-16 20:26:55 +02:00
2018-05-24 23:29:30 +02:00
if ( this . stretch . mode === StretchMode . NO _STRETCH || this . stretch . mode === StretchMode . CONDITIONAL ) {
var stretchFactors = this . scaler . calculateCrop ( ar ) ;
if ( ! stretchFactors || stretchFactors . error ) {
if ( Debug . debug ) {
console . log ( "[Resizer::setAr] failed to set AR due to problem with calculating crop. Error:" , ( stretchFactors ? stretchFactors . error : stretchFactors ) ) ;
}
if ( dimensions . error === 'no_video' ) {
this . conf . destroy ( ) ;
}
return ;
2018-05-16 23:26:47 +02:00
}
2018-05-24 23:29:30 +02:00
if ( this . stretch . mode === StretchMode . CONDITIONAL ) {
2018-05-25 21:37:09 +02:00
this . stretcher . applyConditionalStretch ( stretchFactors , ar ) ;
2018-05-16 20:26:55 +02:00
}
2018-05-24 23:29:30 +02:00
} else if ( this . stretch . mode === StretchMode . HYBRID ) {
var stretchFactors = this . stretcher . calculateStretch ( ar ) ;
2018-05-16 20:26:55 +02:00
}
2018-05-24 23:29:30 +02:00
this . zoom . applyZoom ( stretchFactors ) ;
2018-05-02 17:52:25 +02:00
2018-05-24 23:29:30 +02:00
//TODO: correct these two
2018-05-25 21:37:09 +02:00
var translate = this . computeOffsets ( stretchFactors ) ;
this . applyCss ( stretchFactors , translate ) ;
2018-05-16 23:26:47 +02:00
2018-05-24 23:29:30 +02:00
// if(! this.destroyed)
// this.startCssWatcher();
2018-05-12 02:51:58 +02:00
}
2018-05-02 17:52:25 +02:00
2018-05-14 20:39:15 +02:00
setLastAr ( override ) {
this . lastAr = override ;
}
2018-05-15 21:40:53 +02:00
getLastAr ( ) {
return this . lastAr ;
}
2018-05-13 15:22:28 +02:00
setStretchMode ( stretchMode ) {
this . stretch . mode = stretchMode ;
2018-05-27 21:41:08 +02:00
this . restore ( ) ;
2018-05-13 15:22:28 +02:00
}
2018-05-02 17:52:25 +02:00
2018-05-13 15:22:28 +02:00
setPan ( relativeMousePosX , relativeMousePosY ) {
// relativeMousePos[X|Y] - on scale from 0 to 1, how close is the mouse to player edges.
// use these values: top, left: 0, bottom, right: 1
if ( ! this . pan ) {
this . pan = { } ;
}
2018-02-04 17:39:26 +01:00
2018-05-13 15:22:28 +02:00
this . pan . relativeOffsetX = relativeMousePosX * 2.5 - 1.25 ;
this . pan . relativeOffsetY = relativeMousePosY * 2.5 - 1.25 ;
}
2018-05-02 17:52:25 +02:00
2018-05-13 15:22:28 +02:00
startCssWatcher ( ) {
2018-05-16 23:26:47 +02:00
// this.haltCssWatcher = false;
if ( ! this . cssWatcherTimeout ) {
2018-05-24 22:49:32 +02:00
// if(Debug.debug)
// console.log("[Resizer.js] STARTING CSS WATCHER")
2018-05-16 23:26:47 +02:00
2018-05-24 22:49:32 +02:00
// this.cssWatcherTimeout = setInterval(this.cssWatcher, 200, this);
2018-05-16 23:26:47 +02:00
}
2018-05-13 15:22:28 +02:00
}
2017-09-24 01:54:46 +02:00
2018-05-13 15:22:28 +02:00
stopCssWatcher ( ) {
2018-05-16 23:26:47 +02:00
if ( Debug . debug ) console . log ( "[Resizer.js] STOPPING CSS WATCHER!" )
2018-05-13 15:22:28 +02:00
clearInterval ( this . cssWatcherTimeout ) ;
}
2018-05-02 17:52:25 +02:00
2018-05-13 15:22:28 +02:00
restore ( ) {
if ( Debug . debug ) {
console . log ( "[Resizer::restore] attempting to restore aspect ratio. this & settings:" , { 'this' : this , "settings" : Settings } ) ;
}
// this is true until we verify that css has actually been applied
this . restore _wd = true ;
if ( this . lastAr . type === 'original' ) {
this . setAr ( 'reset' ) ;
}
else {
this . setAr ( this . lastAr . ar , this . lastAr )
}
}
2018-05-02 17:52:25 +02:00
2018-05-13 15:22:28 +02:00
reset ( ) {
this . setStretchMode ( StretchMode . NO _STRETCH ) ;
this . zoom . setZoom ( 1 ) ;
this . resetPan ( ) ;
this . setAr ( 'reset' ) ;
2017-09-24 01:54:46 +02:00
}
2018-05-13 15:22:28 +02:00
resetPan ( ) {
this . pan = undefined ;
2017-09-24 01:54:46 +02:00
}
2018-05-13 15:22:28 +02:00
2018-05-24 20:50:37 +02:00
zoomStep ( step ) {
this . zoom . zoomStep ( step ) ;
}
2018-05-13 15:22:28 +02:00
resetZoom ( ) {
this . zoom . setZoom ( 1 ) ;
this . restore ( ) ;
2017-09-24 01:54:46 +02:00
}
2018-05-13 15:22:28 +02:00
resetCrop ( ) {
this . setAr ( 'reset' ) ;
2017-09-24 01:54:46 +02:00
}
2018-05-13 15:22:28 +02:00
resetStretch ( ) {
this . stretch . mode = StretchMode . NO _STRETCH ;
this . restore ( ) ;
2017-09-24 01:54:46 +02:00
}
2018-01-02 03:36:29 +01:00
2018-05-13 15:22:28 +02:00
// mostly internal stuff
2018-05-25 21:37:09 +02:00
computeOffsets ( stretchFactors ) {
2018-05-13 15:22:28 +02:00
if ( Debug . debug )
console . log ( "[Resizer::_res_computeOffsets] video will be aligned to " , ExtensionConf . miscFullscreenSettings . videoFloat ) ;
2018-01-02 03:36:29 +01:00
2018-05-25 21:37:09 +02:00
var actualWidth = this . conf . video . offsetWidth * stretchFactors . xFactor ;
var actualHeight = this . conf . video . offsetHeight * stretchFactors . yFactor ;
var translate = { x : 0 , y : 0 } ;
2018-04-22 14:35:40 +02:00
2018-05-13 15:22:28 +02:00
if ( this . pan ) {
2018-05-25 21:37:09 +02:00
// todo: calculate translate
2018-05-13 15:22:28 +02:00
} else {
2018-05-25 21:37:09 +02:00
if ( ExtensionConf . miscFullscreenSettings . videoFloat == "left" ) {
translate . x = ( this . conf . player . dimensions . width - actualWidth ) * - 0.5 ;
2018-05-13 15:22:28 +02:00
}
else if ( ExtensionConf . miscFullscreenSettings . videoFloat == "right" ) {
2018-05-25 21:37:09 +02:00
translate . x = ( this . conf . player . dimensions . width - actualWidth ) * 0.5 ;
2018-05-13 15:22:28 +02:00
}
}
2018-05-25 21:37:09 +02:00
return translate ;
2018-05-13 15:22:28 +02:00
}
2018-05-25 21:37:09 +02:00
applyCss ( stretchFactors , translate ) {
2018-05-13 15:22:28 +02:00
2018-05-16 23:26:47 +02:00
if ( ! this . video ) {
2018-04-22 14:35:40 +02:00
if ( Debug . debug )
2018-05-13 15:22:28 +02:00
console . log ( "[Resizer::_res_applyCss] Video went missing, doing nothing." ) ;
2018-05-16 23:26:47 +02:00
this . conf . destroy ( ) ;
2018-04-22 14:35:40 +02:00
return ;
}
2018-01-02 03:36:29 +01:00
2018-05-16 23:26:47 +02:00
// save stuff for quick tests (before we turn numbers into css values):
this . currentVideoSettings = {
validFor : this . conf . player . dimensions ,
2018-05-25 21:37:09 +02:00
// videoWidth: dimensions.width,
// videoHeight: dimensions.height
2018-05-16 23:26:47 +02:00
}
2018-05-13 15:22:28 +02:00
var styleArrayStr = this . video . getAttribute ( 'style' ) ;
2018-05-25 21:37:09 +02:00
if ( styleArrayStr ) {
2018-01-02 03:36:29 +01:00
2018-05-13 15:22:28 +02:00
var styleArray = styleArrayStr . split ( ";" ) ;
for ( var i in styleArray ) {
styleArray [ i ] = styleArray [ i ] . trim ( ) ;
2018-05-25 21:37:09 +02:00
if ( styleArray [ i ] . startsWith ( "transform:" ) ) {
delete styleArray [ i ] ;
2018-05-13 15:22:28 +02:00
}
2018-01-02 03:36:29 +01:00
}
}
else {
2018-05-13 15:22:28 +02:00
var styleArray = [ ] ;
}
// add remaining elements
if ( stretchFactors ) {
2018-05-25 21:37:09 +02:00
styleArray . push ( ` transform: scale( ${ stretchFactors . xFactor } , ${ stretchFactors . yFactor } ) translate( ${ translate . x } px, ${ translate . y } px) ` ) ;
2018-01-02 03:36:29 +01:00
}
2018-04-22 14:35:40 +02:00
2018-05-13 15:22:28 +02:00
// build style string back
var styleString = "" ;
for ( var i in styleArray )
2018-05-25 21:37:09 +02:00
if ( styleArray [ i ] )
2018-05-13 15:22:28 +02:00
styleString += styleArray [ i ] + "; " ;
this . setStyleString ( styleString ) ;
2018-05-16 23:26:47 +02:00
2018-04-22 14:35:40 +02:00
}
2018-05-13 15:22:28 +02:00
setStyleString ( styleString , count = 0 ) {
2018-05-15 21:40:53 +02:00
this . video . setAttribute ( "style" , styleString ) ;
2017-11-13 22:35:04 +01:00
2018-05-13 15:22:28 +02:00
if ( this . restore _wd ) {
2018-05-25 21:37:09 +02:00
if ( ! this . video ) {
2018-05-13 15:22:28 +02:00
if ( Debug . debug )
console . log ( "[Resizer::_res_setStyleString] Video element went missing, nothing to do here." )
return ;
2017-12-02 21:09:08 +01:00
}
2018-05-13 15:22:28 +02:00
2018-05-25 21:37:09 +02:00
// if(
// styleString.indexOf("width: " + this.video.style.width) == -1 ||
// styleString.indexOf("height: " + this.video.style.height) == -1) {
// // css ni nastavljen?
// // css not set?
// if(Debug.debug)
// console.log("[Resizer::_res_setStyleString] Style string not set ???");
2018-05-13 15:22:28 +02:00
2018-05-25 21:37:09 +02:00
// if(count < ExtensionConf.resizer.setStyleString.maxRetries){
// setTimeout( this.setStyleString, ExtensionConf.resizer.setStyleString.retryTimeout, count + 1);
// }
// else if(Debug.debug){
// console.log("[Resizer::_res_setStyleString] we give up. css string won't be set");
// }
// }
// else{
2018-05-13 15:22:28 +02:00
this . restore _wd = false ;
2018-05-25 21:37:09 +02:00
// }
2017-11-13 22:35:04 +01:00
}
2018-05-13 15:22:28 +02:00
else {
if ( Debug . debug )
console . log ( "[Resizer::_res_setStyleString] css applied. Style string:" , styleString ) ;
}
2017-11-13 22:35:04 +01:00
}
2018-04-25 20:39:52 +02:00
2018-05-16 23:26:47 +02:00
cssWatcher ( ths ) {
2018-05-13 15:22:28 +02:00
// this means we haven't set our CSS yet, or that we changed video.
2018-05-16 23:26:47 +02:00
if ( ! ths . currentCss . top )
2018-05-13 15:22:28 +02:00
return ;
2018-05-16 23:26:47 +02:00
// this means video went missing. videoData will be re-initialized when the next video is found
if ( ! ths . video ) {
ths . conf . destroy ( ) ;
2018-05-13 15:22:28 +02:00
return ;
2018-05-16 23:26:47 +02:00
}
2018-05-20 23:17:09 +02:00
console . log ( "css watcher running. video?" , ths . video )
2018-05-13 15:22:28 +02:00
// // our current css is fucky? Null, undefined and 0 are invalid values.
// if(! GlobalVars.currentCss.width || ! GlobalVars.currentCss.height )
// return;
2018-05-16 23:26:47 +02:00
// first, a quick test:
if ( ths . currentVideoSettings . validFor == ths . conf . player . dimensions ) {
if ( ths . currentVideoSettings . videoWidth != ths . video . offsetWidth ||
ths . currentVideoSettings . videoHeight != ths . video . offsetHeight ) {
ths . restore ( ) ;
return ;
}
}
2018-02-05 22:46:38 +01:00
2018-05-16 23:26:47 +02:00
var styleArrayStr = ths . video . getAttribute ( 'style' ) ;
2018-02-05 22:46:38 +01:00
2018-05-13 15:22:28 +02:00
if ( styleArrayStr ) {
var styleArray = styleArrayStr . split ( ";" ) ;
var stuffChecked = 0 ;
var stuffToCheck = 2 ;
2018-02-05 22:46:38 +01:00
2018-05-13 15:22:28 +02:00
for ( var i in styleArray ) {
styleArray [ i ] = styleArray [ i ] . trim ( ) ;
if ( styleArray [ i ] . startsWith ( "top:" ) ) {
// don't force css restore if currentCss.top is not defined
2018-05-16 23:26:47 +02:00
if ( ths . currentCss . top && styleArray [ i ] != ths . currentCss . top ) {
2018-05-13 15:22:28 +02:00
if ( Debug . debug ) {
console . log ( "[Resizer::_res_antiCssOverride] SOMEBODY TOUCHED MA SPAGHETT (our CSS got overriden, restoring our css)" ) ;
2018-05-16 23:26:47 +02:00
console . log ( "[Resizer::_res_antiCssOverride] MA SPAGHETT: top:" , ths . currentCss . top , "left:" , ths . currentCss . left , "thing that touched ma spaghett" , styleArrayStr ) ;
2018-05-13 15:22:28 +02:00
}
2018-05-16 23:26:47 +02:00
ths . restore ( ) ;
2018-05-13 15:22:28 +02:00
return ;
2018-02-05 22:46:38 +01:00
}
2018-05-13 15:22:28 +02:00
stuffChecked ++ ;
2018-02-05 22:46:38 +01:00
}
2018-05-13 15:22:28 +02:00
else if ( styleArray [ i ] . startsWith ( "left:" ) ) {
// don't force css restore if currentCss.left is not defined
2018-05-16 23:26:47 +02:00
if ( ths . currentCss . left && styleArray [ i ] != ths . currentCss . left ) {
2018-05-13 15:22:28 +02:00
if ( Debug . debug ) {
console . log ( "[Resizer::_res_antiCssOverride] SOMEBODY TOUCHED MA SPAGHETT (our CSS got overriden, restoring our css)" ) ;
2018-05-16 23:26:47 +02:00
console . log ( "[Resizer::_res_antiCssOverride] MA SPAGHETT: width:" , ths . currentCss . width , "height:" , ths . currentCss . height , "thing that touched ma spaghett" , styleArrayStr ) ;
2018-05-13 15:22:28 +02:00
}
2018-05-16 23:26:47 +02:00
ths . restore ( ) ;
2018-05-13 15:22:28 +02:00
return ;
2018-02-05 22:46:38 +01:00
}
2018-05-13 15:22:28 +02:00
stuffChecked ++ ;
}
if ( stuffChecked == stuffToCheck ) {
// if(Debug.debug){
// console.log("[Resizer::_res_antiCssOverride] My spaghett rests untouched. (nobody overrode our CSS, doing nothing)");
// }
2018-02-05 22:46:38 +01:00
return ;
}
}
}
}
}