FOR REALS account for offset applied by sites that use top:50%/transformY:-50% to center elements
This commit is contained in:
parent
d981e4c2c6
commit
9f10c0dcf4
@ -19,6 +19,7 @@ import Settings from '../Settings';
|
|||||||
import { Ar } from '../../../common/interfaces/ArInterface';
|
import { Ar } from '../../../common/interfaces/ArInterface';
|
||||||
import { RunLevel } from '../../enum/run-level.enum';
|
import { RunLevel } from '../../enum/run-level.enum';
|
||||||
import * as _ from 'lodash';
|
import * as _ from 'lodash';
|
||||||
|
import getElementStyles from '../../util/getElementStyles';
|
||||||
|
|
||||||
if(Debug.debug) {
|
if(Debug.debug) {
|
||||||
console.log("Loading: Resizer.js");
|
console.log("Loading: Resizer.js");
|
||||||
@ -692,7 +693,6 @@ class Resizer {
|
|||||||
this.logger.log('info', 'debug', "[Resizer::computeOffsets] <rid:"+this.resizerId+"> video will be aligned to ", this.videoAlignment);
|
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 {realVideoWidth, realVideoHeight, marginX, marginY} = this.computeVideoDisplayedDimensions();
|
||||||
const computedStyles = getComputedStyle(this.video);
|
|
||||||
|
|
||||||
// correct any remaining element size discrepancies (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
|
// NOTE: it's possible that we might also need to apply a similar measure for CropPillarbox strategy
|
||||||
@ -716,10 +716,16 @@ class Resizer {
|
|||||||
// we only need to compensate if alignment is set to anything other than center center
|
// we only need to compensate if alignment is set to anything other than center center
|
||||||
// compensation is equal to half the difference between (zoomed) video size and player size.
|
// compensation is equal to half the difference between (zoomed) video size and player size.
|
||||||
const translate = {
|
const translate = {
|
||||||
x: -Math.round(+ (computedStyles.left.replace('px', ''))),
|
x: 0,
|
||||||
y: -Math.round(+ (computedStyles.top.replace('px', '')))
|
y: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const problemStats = getElementStyles(this.video, ['top', 'left', 'transform']);
|
||||||
|
if (problemStats.left?.css && problemStats.top?.css && problemStats.transform?.css?.includes(`translate(-${problemStats.left.css}, -${problemStats.top.css})`)) {
|
||||||
|
translate.x -= ~~problemStats.left.pxValue;
|
||||||
|
translate.y -= ~~problemStats.top.pxValue;
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: manual panning is probably broken now.
|
// NOTE: manual panning is probably broken now.
|
||||||
// TODO: FIXME:
|
// TODO: FIXME:
|
||||||
// (argument could be made that manual panning was also broken before)
|
// (argument could be made that manual panning was also broken before)
|
||||||
@ -889,6 +895,7 @@ class Resizer {
|
|||||||
if (stretchFactors) {
|
if (stretchFactors) {
|
||||||
styleArray.push(`transform: translate(${Math.round(translate.x)}px, ${Math.round(translate.y)}px) scale(${stretchFactors.xFactor}, ${stretchFactors.yFactor}) !important;`);
|
styleArray.push(`transform: translate(${Math.round(translate.x)}px, ${Math.round(translate.y)}px) scale(${stretchFactors.xFactor}, ${stretchFactors.yFactor}) !important;`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const styleString = `${this.buildStyleString(styleArray)}${extraStyleString || ''}`; // string returned by buildStyleString() should end with ; anyway
|
const styleString = `${this.buildStyleString(styleArray)}${extraStyleString || ''}`; // string returned by buildStyleString() should end with ; anyway
|
||||||
|
|
||||||
// build style string back
|
// build style string back
|
||||||
|
98
src/ext/util/getElementStyles.ts
Normal file
98
src/ext/util/getElementStyles.ts
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
export type ProcessedElementStyles = {
|
||||||
|
[x: string]: {
|
||||||
|
css: string,
|
||||||
|
pxValue: number
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note that this function is written _very_ dangerously
|
||||||
|
* and includes absolutely no error handling
|
||||||
|
*/
|
||||||
|
function getPixelValue(value: string, element?: HTMLElement, prop?: string) {
|
||||||
|
if (value === undefined || value === null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.endsWith('px')) {
|
||||||
|
// console.log('value ends in px:', value)
|
||||||
|
return parseFloat(value);
|
||||||
|
}
|
||||||
|
if (value.endsWith('%')) {
|
||||||
|
// console.log('value ends in %:', value)
|
||||||
|
// This allegedly doesn't work for certain types of properties, allegedly.
|
||||||
|
const parent = element?.parentElement;
|
||||||
|
if (parent && prop) {
|
||||||
|
const parentDimensions = parent.getBoundingClientRect();
|
||||||
|
return (parseFloat(value) * 0.01) * (prop.includes('height') || ['top', 'bottom'].includes(prop) ? parentDimensions.height : parentDimensions.width);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.endsWith("vw")) {
|
||||||
|
const viewportWidth = window.innerWidth;
|
||||||
|
return (parseFloat(value) / 100) * viewportWidth;
|
||||||
|
}
|
||||||
|
if (value.endsWith("vh")) {
|
||||||
|
const viewportHeight = window.innerHeight;
|
||||||
|
return (parseFloat(value) / 100) * viewportHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.endsWith("rem")) {
|
||||||
|
const rootFontSize = parseFloat(getComputedStyle(document.documentElement).fontSize);
|
||||||
|
return rootFontSize * parseFloat(value);
|
||||||
|
}
|
||||||
|
if (value.endsWith("em")) {
|
||||||
|
const fontSize = parseFloat(getComputedStyle(element).fontSize);
|
||||||
|
return fontSize * parseFloat(value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function getElementStyles(element: HTMLElement, props: string[]): ProcessedElementStyles {
|
||||||
|
const stylesheets = document.styleSheets;
|
||||||
|
const computedStyles = getComputedStyle(element);
|
||||||
|
const stylesOut = {};
|
||||||
|
|
||||||
|
for (const stylesheet of stylesheets) {
|
||||||
|
// console.log('——————————————— processing stylesheet:', stylesheet);
|
||||||
|
try {
|
||||||
|
for (const rule of stylesheet?.cssRules) {
|
||||||
|
if (rule instanceof CSSStyleRule) {
|
||||||
|
if (element.matches(rule.selectorText)) {
|
||||||
|
// console.log('element matches rule:', rule);
|
||||||
|
|
||||||
|
for (const property in rule.style) {
|
||||||
|
if (!props.includes(property)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const cssValue = rule.style.getPropertyValue(property);
|
||||||
|
const actualValue = computedStyles.getPropertyValue(property);
|
||||||
|
|
||||||
|
const theory = getPixelValue(cssValue, element, property);
|
||||||
|
const practice = getPixelValue(actualValue, element, property);
|
||||||
|
|
||||||
|
if (theory === practice) {
|
||||||
|
stylesOut[property] = {
|
||||||
|
css: cssValue,
|
||||||
|
pxValue: theory
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
// Cross-origin styles amy cause problems
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return stylesOut;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user