fix vertical alignment
This commit is contained in:
parent
25222c7310
commit
cd89cca984
@ -278,7 +278,7 @@ class Resizer {
|
||||
}
|
||||
|
||||
if ([AspectRatioType.Reset, AspectRatioType.Initial].includes(ar.type)) {
|
||||
console.log('run level is UI only because aspect ratio type is', ar.type)
|
||||
// console.log('run level is UI only because aspect ratio type is', ar.type)
|
||||
this.eventBus.send('set-run-level', RunLevel.UIOnly);
|
||||
} else {
|
||||
this.eventBus.send('set-run-level', RunLevel.CustomCSSActive);
|
||||
@ -307,7 +307,7 @@ class Resizer {
|
||||
return;
|
||||
}
|
||||
|
||||
let stretchFactors: {xFactor: number, yFactor: number, arCorrectionFactor?: number, ratio?: number} | any;
|
||||
let stretchFactors: VideoDimensions | any;
|
||||
|
||||
// reset zoom, but only on aspect ratio switch. We also know that aspect ratio gets converted to
|
||||
// AspectRatioType.Fixed when zooming, so let's keep that in mind
|
||||
@ -419,10 +419,10 @@ class Resizer {
|
||||
);
|
||||
}
|
||||
|
||||
this.applyScaling(stretchFactors);
|
||||
this.applyScaling(stretchFactors as VideoDimensions);
|
||||
}
|
||||
|
||||
applyScaling(stretchFactors, options?: {noAnnounce?: boolean}) {
|
||||
applyScaling(stretchFactors: VideoDimensions, options?: {noAnnounce?: boolean, ar?: Ar}) {
|
||||
this.stretcher.chromeBugMitigation(stretchFactors);
|
||||
|
||||
// let the UI know
|
||||
@ -430,7 +430,7 @@ class Resizer {
|
||||
this.videoData.eventBus.send('announce-zoom', {x: stretchFactors.xFactor, y: stretchFactors.yFactor});
|
||||
}
|
||||
|
||||
let translate = this.computeOffsets(stretchFactors);
|
||||
let translate = this.computeOffsets(stretchFactors, options?.ar);
|
||||
this.applyCss(stretchFactors, translate);
|
||||
}
|
||||
|
||||
@ -457,7 +457,7 @@ class Resizer {
|
||||
if(!this.videoData.player || !this.videoData.player.element) {
|
||||
return;
|
||||
}
|
||||
// dont allow weird floats
|
||||
// don't allow weird floats
|
||||
this.videoAlignment.x = VideoAlignmentType.Center;
|
||||
|
||||
// because non-fixed aspect ratios reset panning:
|
||||
@ -501,14 +501,14 @@ class Resizer {
|
||||
setVideoAlignment(videoAlignmentX: VideoAlignmentType, videoAlignmentY?: VideoAlignmentType) {
|
||||
// if aspect ratio is unset or initial, CSS fixes are inactive by design.
|
||||
// because of that, we need to set a manual aspect ratio first.
|
||||
console.log('last aspect ratio:', this.lastAr);
|
||||
if (!this.lastAr) {
|
||||
console.warn('[Resizer.js::setVideoAlignment] Aspect ratio not set. This is illegal. This function will do nothing.');
|
||||
|
||||
if (!this.lastAr?.ratio) {
|
||||
this.setAr({
|
||||
type: AspectRatioType.Fixed,
|
||||
type: AspectRatioType.AutomaticUpdate,
|
||||
ratio: this.getFileAr()
|
||||
});
|
||||
}
|
||||
|
||||
if ([AspectRatioType.Reset, AspectRatioType.Initial].includes(this.lastAr.type)) {
|
||||
if (this.lastAr.ratio) {
|
||||
this.lastAr.type = AspectRatioType.Fixed;
|
||||
@ -659,36 +659,6 @@ class Resizer {
|
||||
}
|
||||
}
|
||||
|
||||
computeCroppedAreas(stretchFactors) {
|
||||
// PSA: offsetWidth and offsetHeight DO NOT INCLUDE
|
||||
// ZOOM APPLIED THROUGH THE MAGIC OF CSS TRANSFORMS
|
||||
const sourceWidth = this.videoData.video.offsetWidth;
|
||||
const sourceHeight = this.videoData.video.offsetHeight;
|
||||
|
||||
// this is the size of the video AFTER zooming was applied but does
|
||||
// not account for cropping. It may be bigger than the player in
|
||||
// both dimensions. It may be smaller than player in both dimensions
|
||||
const postZoomWidth = sourceWidth * stretchFactors.xFactor;
|
||||
const postZoomHeight = sourceHeight * stretchFactors.yFactor;
|
||||
|
||||
// this is the size of the video after crop is applied
|
||||
const displayedWidth = Math.min(this.videoData.player.dimensions.width, postZoomWidth);
|
||||
const displayedHeight = Math.min(this.videoData.player.dimensions.height, postZoomHeight);
|
||||
|
||||
// these two are cropped areas. Negative values mean additional
|
||||
// letterboxing or pillarboxing. We assume center alignment for
|
||||
// the time being - we will correct that later if need be
|
||||
const croppedX = (postZoomWidth - displayedWidth) * 0.5;
|
||||
const croppedY = (postZoomHeight - displayedHeight) * 0.5;
|
||||
|
||||
return {
|
||||
sourceVideoDimensions: {width: sourceWidth, height: sourceHeight},
|
||||
postZoomVideoDimensions: {width: postZoomWidth, height: postZoomHeight},
|
||||
displayedVideoDimensions: {width: displayedWidth, height: displayedHeight},
|
||||
crop: {left: croppedX, top: croppedY},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Sometimes, sites (e.g. new reddit) will guarantee that video fits width of its container
|
||||
* and let the browser figure out the height through the magic of height:auto. This is bad,
|
||||
@ -716,14 +686,12 @@ class Resizer {
|
||||
}
|
||||
|
||||
private _computeOffsetsRecursionGuard: boolean = false;
|
||||
computeOffsets(stretchFactors: VideoDimensions){
|
||||
computeOffsets(stretchFactors: VideoDimensions, ar?: Ar){
|
||||
this.logger.log('info', 'debug', "[Resizer::computeOffsets] <rid:"+this.resizerId+"> video will be aligned to ", this.videoAlignment);
|
||||
|
||||
const {realVideoWidth, realVideoHeight, marginX, marginY} = this.computeVideoDisplayedDimensions();
|
||||
|
||||
const {postZoomVideoDimensions, displayedVideoDimensions, crop} = this.computeCroppedAreas(stretchFactors);
|
||||
|
||||
// correct any remaining element size discrepencies (applicable only to certain crop strategies!)
|
||||
// correct any remaining element size discrepancies (applicable only to certain crop strategies!)
|
||||
// NOTE: it's possible that we might also need to apply a similar measure for CropPillarbox strategy
|
||||
// (but we'll wait for bug reports before doing so).
|
||||
// We also don't compensate for height:auto if height is provided via element style
|
||||
@ -732,7 +700,11 @@ class Resizer {
|
||||
stretchFactors.cropStrategy === CropStrategy.CropLetterbox
|
||||
&& (!stretchFactors.styleHeightCompensationFactor || stretchFactors.styleHeightCompensationFactor === 1)
|
||||
) {
|
||||
autoHeightCompensationFactor = this.computeAutoHeightCompensationFactor(realVideoWidth, realVideoHeight, this.videoData.player.dimensions.width, this.videoData.player.dimensions.height, 'height');
|
||||
autoHeightCompensationFactor = this.computeAutoHeightCompensationFactor(
|
||||
realVideoWidth, realVideoHeight,
|
||||
this.videoData.player.dimensions.width, this.videoData.player.dimensions.height,
|
||||
'height'
|
||||
);
|
||||
stretchFactors.xFactor *= autoHeightCompensationFactor;
|
||||
stretchFactors.yFactor *= autoHeightCompensationFactor;
|
||||
}
|
||||
@ -759,17 +731,21 @@ class Resizer {
|
||||
}
|
||||
} else {
|
||||
// correct horizontal alignment according to the settings
|
||||
if (this.videoAlignment.x == VideoAlignmentType.Left) {
|
||||
translate.x += alignXOffset;
|
||||
} else if (this.videoAlignment.x == VideoAlignmentType.Right) {
|
||||
translate.x -= alignXOffset
|
||||
if (!stretchFactors.preventAlignment?.x) {
|
||||
if (this.videoAlignment.x == VideoAlignmentType.Left) {
|
||||
translate.x += stretchFactors?.relativeCropLimits?.left ? (this.videoData.player.dimensions.width * stretchFactors.relativeCropLimits.left): alignXOffset;
|
||||
} else if (this.videoAlignment.x == VideoAlignmentType.Right) {
|
||||
translate.x -= stretchFactors?.relativeCropLimits?.left ? (this.videoData.player.dimensions.width * stretchFactors.relativeCropLimits.left): alignXOffset
|
||||
}
|
||||
}
|
||||
|
||||
// correct vertical alignment according to the settings
|
||||
if (this.videoAlignment.y == VideoAlignmentType.Top) {
|
||||
translate.y += alignYOffset;
|
||||
} else if (this.videoAlignment.y == VideoAlignmentType.Bottom) {
|
||||
translate.y -= alignYOffset;
|
||||
if (!stretchFactors.preventAlignment?.y) {
|
||||
if (this.videoAlignment.y == VideoAlignmentType.Top) {
|
||||
translate.y += stretchFactors?.relativeCropLimits?.top ? (this.videoData.player.dimensions.height * stretchFactors?.relativeCropLimits?.top): alignYOffset;
|
||||
} else if (this.videoAlignment.y == VideoAlignmentType.Bottom) {
|
||||
translate.y -= stretchFactors?.relativeCropLimits?.top ? (this.videoData.player.dimensions.height * stretchFactors?.relativeCropLimits?.top): alignYOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,14 @@ export type VideoDimensions = {
|
||||
styleHeightCompensationFactor?: number;
|
||||
actualWidth?: number;
|
||||
actualHeight?: number;
|
||||
relativeCropLimits?: {
|
||||
top: number;
|
||||
left: number;
|
||||
},
|
||||
preventAlignment?: {
|
||||
x: boolean,
|
||||
y: boolean
|
||||
}
|
||||
}
|
||||
|
||||
// does video size calculations for zooming/cropping
|
||||
@ -92,7 +100,7 @@ class Scaler {
|
||||
return null;
|
||||
}
|
||||
|
||||
calculateCrop(ar: {type: AspectRatioType, ratio?: number}) {
|
||||
calculateCrop(ar: {type: AspectRatioType, ratio?: number}): VideoDimensions | {error: string, [x: string]: any} {
|
||||
/**
|
||||
* STEP 1: NORMALIZE ASPECT RATIO
|
||||
*
|
||||
@ -142,7 +150,16 @@ class Scaler {
|
||||
}
|
||||
|
||||
if (ar.type === AspectRatioType.Reset){
|
||||
return {xFactor: arCorrectionFactor, yFactor: arCorrectionFactor, arCorrectionFactor: arCorrectionFactor};
|
||||
return {
|
||||
xFactor: arCorrectionFactor,
|
||||
yFactor: arCorrectionFactor,
|
||||
arCorrectionFactor: arCorrectionFactor,
|
||||
|
||||
relativeCropLimits: {
|
||||
top: 0,
|
||||
left: 0,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// handle fuckie-wuckies
|
||||
@ -175,7 +192,11 @@ class Scaler {
|
||||
actualWidth: 0, // width of the video (excluding pillarbox) when <video> tag height is equal to width
|
||||
actualHeight: 0, // height of the video (excluding letterbox) when <video> tag height is equal to height
|
||||
arCorrectionFactor: arCorrectionFactor,
|
||||
styleHeightCompensationFactor: heightCompensationFactor
|
||||
styleHeightCompensationFactor: heightCompensationFactor,
|
||||
relativeCropLimits: {
|
||||
top: 0,
|
||||
left: 0
|
||||
}
|
||||
}
|
||||
|
||||
this.calculateCropCore(videoDimensions, ar.ratio, streamAr, playerAr)
|
||||
@ -223,14 +244,24 @@ class Scaler {
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.log('info', 'scaler', "[Scaler::calculateCrop] Crop factor calculated — ", videoDimensions.xFactor);
|
||||
|
||||
// correct the scale factor
|
||||
if (videoDimensions.arCorrectionFactor) {
|
||||
videoDimensions.xFactor *= videoDimensions.arCorrectionFactor;
|
||||
videoDimensions.yFactor *= videoDimensions.arCorrectionFactor;
|
||||
}
|
||||
|
||||
// Add crop limits — needed for vertical alignment in order to
|
||||
const letterboxRatio = (1 - (playerAr / ar));
|
||||
|
||||
videoDimensions.relativeCropLimits = {
|
||||
top: ar > streamAr ? ( ar > playerAr ? (letterboxRatio * -0.5) : 0) : 0,
|
||||
left: ar < streamAr ? ( ar < playerAr ? (-0.5 / letterboxRatio) : 0) : 0,
|
||||
}
|
||||
videoDimensions.preventAlignment = {
|
||||
x: ar > playerAr, // video is wider than player, so it's full width already
|
||||
y: ar < playerAr, // video is narrower than player, so it's full height already
|
||||
}
|
||||
|
||||
return videoDimensions;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user