UNPKG

@remotion/player

Version:

React component for embedding a Remotion preview into your app

145 lines (144 loc) 5.12 kB
"use strict"; 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;