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 { RunLevel } from '../../enum/run-level.enum';
|
||||
import * as _ from 'lodash';
|
||||
import getElementStyles from '../../util/getElementStyles';
|
||||
|
||||
if(Debug.debug) {
|
||||
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);
|
||||
|
||||
const {realVideoWidth, realVideoHeight, marginX, marginY} = this.computeVideoDisplayedDimensions();
|
||||
const computedStyles = getComputedStyle(this.video);
|
||||
|
||||
// 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
|
||||
@ -716,10 +716,16 @@ class Resizer {
|
||||
// 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.
|
||||
const translate = {
|
||||
x: -Math.round(+ (computedStyles.left.replace('px', ''))),
|
||||
y: -Math.round(+ (computedStyles.top.replace('px', '')))
|
||||
x: 0,
|
||||
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.
|
||||
// TODO: FIXME:
|
||||
// (argument could be made that manual panning was also broken before)
|
||||
@ -889,6 +895,7 @@ class Resizer {
|
||||
if (stretchFactors) {
|
||||
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
|
||||
|
||||
// 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