@remotion/player
Version:
React component for embedding a Remotion preview into your app
145 lines (144 loc) • 5.12 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.useElementSize = exports.updateAllElementsSizes = void 0;
const react_1 = require("react");
let elementSizeHooks = [];
const updateAllElementsSizes = () => {
for (const listener of elementSizeHooks) {
listener();
}
};
exports.updateAllElementsSizes = updateAllElementsSizes;
const useElementSize = (ref, options) => {
const [size, setSize] = (0, react_1.useState)(() => {
if (!ref.current) {
return null;
}
const rect = ref.current.getClientRects();
if (!rect[0]) {
return null;
}
return {
width: rect[0].width,
height: rect[0].height,
left: rect[0].x,
top: rect[0].y,
windowSize: {
height: window.innerHeight,
width: window.innerWidth,
},
};
});
const observer = (0, react_1.useMemo)(() => {
if (typeof ResizeObserver === 'undefined') {
return null;
}
return new ResizeObserver((entries) => {
// The contentRect returns the width without any `scale()`'s being applied. The height is wrong
const { contentRect, target } = entries[0];
// The clientRect returns the size with `scale()` being applied.
const newSize = target.getClientRects();
if (!(newSize === null || newSize === void 0 ? void 0 : newSize[0])) {
setSize(null);
return;
}
const probableCssParentScale = contentRect.width === 0 ? 1 : newSize[0].width / contentRect.width;
const width = options.shouldApplyCssTransforms
? newSize[0].width
: newSize[0].width * (1 / probableCssParentScale);
const height = options.shouldApplyCssTransforms
? newSize[0].height
: newSize[0].height * (1 / probableCssParentScale);
setSize((prevState) => {
const isSame = prevState &&
prevState.width === width &&
prevState.height === height &&
prevState.left === newSize[0].x &&
prevState.top === newSize[0].y &&
prevState.windowSize.height === window.innerHeight &&
prevState.windowSize.width === window.innerWidth;
if (isSame) {
return prevState;
}
return {
width,
height,
left: newSize[0].x,
top: newSize[0].y,
windowSize: {
height: window.innerHeight,
width: window.innerWidth,
},
};
});
});
}, [options.shouldApplyCssTransforms]);
const updateSize = (0, react_1.useCallback)(() => {
if (!ref.current) {
return;
}
const rect = ref.current.getClientRects();
if (!rect[0]) {
setSize(null);
return;
}
setSize((prevState) => {
const isSame = prevState &&
prevState.width === rect[0].width &&
prevState.height === rect[0].height &&
prevState.left === rect[0].x &&
prevState.top === rect[0].y &&
prevState.windowSize.height === window.innerHeight &&
prevState.windowSize.width === window.innerWidth;
if (isSame) {
return prevState;
}
return {
width: rect[0].width,
height: rect[0].height,
left: rect[0].x,
top: rect[0].y,
windowSize: {
height: window.innerHeight,
width: window.innerWidth,
},
};
});
}, [ref]);
(0, react_1.useEffect)(() => {
if (!observer) {
return;
}
const { current } = ref;
if (current) {
observer.observe(current);
}
return () => {
if (current) {
observer.unobserve(current);
}
};
}, [observer, ref, updateSize]);
(0, react_1.useEffect)(() => {
if (!options.triggerOnWindowResize) {
return;
}
window.addEventListener('resize', updateSize);
return () => {
window.removeEventListener('resize', updateSize);
};
}, [options.triggerOnWindowResize, updateSize]);
(0, react_1.useEffect)(() => {
elementSizeHooks.push(updateSize);
return () => {
elementSizeHooks = elementSizeHooks.filter((e) => e !== updateSize);
};
}, [updateSize]);
return (0, react_1.useMemo)(() => {
if (!size) {
return null;
}
return { ...size, refresh: updateSize };
}, [size, updateSize]);
};
exports.useElementSize = useElementSize;