UNPKG

@wordpress/block-editor

Version:
293 lines (291 loc) 10.5 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // packages/block-editor/src/components/iframe/use-scale-canvas.js var use_scale_canvas_exports = {}; __export(use_scale_canvas_exports, { useScaleCanvas: () => useScaleCanvas }); module.exports = __toCommonJS(use_scale_canvas_exports); var import_element = require("@wordpress/element"); var import_compose = require("@wordpress/compose"); function calculateScale({ frameSize, containerWidth, maxContainerWidth, scaleContainerWidth }) { return (Math.min(containerWidth, maxContainerWidth) - frameSize * 2) / scaleContainerWidth; } function computeScrollHeightNext(transitionFrom, transitionTo) { const { scaleValue: prevScale, scrollHeight: prevScrollHeight } = transitionFrom; const { frameSize, scaleValue } = transitionTo; return prevScrollHeight * (scaleValue / prevScale) + frameSize * 2; } function computeScrollTopNext(transitionFrom, transitionTo) { const { containerHeight: prevContainerHeight, frameSize: prevFrameSize, scaleValue: prevScale, scrollTop: prevScrollTop } = transitionFrom; const { containerHeight, frameSize, scaleValue, scrollHeight } = transitionTo; let scrollTopNext = prevScrollTop; scrollTopNext = (scrollTopNext + prevContainerHeight / 2 - prevFrameSize) / prevScale - prevContainerHeight / 2; scrollTopNext = (scrollTopNext + containerHeight / 2) * scaleValue + frameSize - containerHeight / 2; scrollTopNext = prevScrollTop <= prevFrameSize ? 0 : scrollTopNext; const maxScrollTop = scrollHeight - containerHeight; return Math.round( Math.min(Math.max(0, scrollTopNext), Math.max(0, maxScrollTop)) ); } function getAnimationKeyframes(transitionFrom, transitionTo) { const { scaleValue: prevScale, frameSize: prevFrameSize, scrollTop } = transitionFrom; const { scaleValue, frameSize, scrollTop: scrollTopNext } = transitionTo; return [ { translate: `0 0`, scale: prevScale, paddingTop: `${prevFrameSize / prevScale}px`, paddingBottom: `${prevFrameSize / prevScale}px` }, { translate: `0 ${scrollTop - scrollTopNext}px`, scale: scaleValue, paddingTop: `${frameSize / scaleValue}px`, paddingBottom: `${frameSize / scaleValue}px` } ]; } function useScaleCanvas({ frameSize, iframeDocument, maxContainerWidth = 750, scale }) { const [contentResizeListener, { height: contentHeight }] = (0, import_compose.useResizeObserver)(); const [ containerResizeListener, { width: containerWidth, height: containerHeight } ] = (0, import_compose.useResizeObserver)(); const initialContainerWidthRef = (0, import_element.useRef)(0); const isZoomedOut = scale !== 1; const prefersReducedMotion = (0, import_compose.useReducedMotion)(); const isAutoScaled = scale === "auto-scaled"; const startAnimationRef = (0, import_element.useRef)(false); const animationRef = (0, import_element.useRef)(null); (0, import_element.useEffect)(() => { if (!isZoomedOut) { initialContainerWidthRef.current = containerWidth; } }, [containerWidth, isZoomedOut]); const scaleContainerWidth = Math.max( initialContainerWidthRef.current, containerWidth ); const scaleValue = isAutoScaled ? calculateScale({ frameSize, containerWidth, maxContainerWidth, scaleContainerWidth }) : scale; const transitionFromRef = (0, import_element.useRef)({ scaleValue, frameSize, containerHeight: 0, scrollTop: 0, scrollHeight: 0 }); const transitionToRef = (0, import_element.useRef)({ scaleValue, frameSize, containerHeight: 0, scrollTop: 0, scrollHeight: 0 }); const startZoomOutAnimation = (0, import_element.useCallback)(() => { const { scrollTop } = transitionFromRef.current; const { scrollTop: scrollTopNext } = transitionToRef.current; iframeDocument.documentElement.style.setProperty( "--wp-block-editor-iframe-zoom-out-scroll-top", `${scrollTop}px` ); iframeDocument.documentElement.style.setProperty( "--wp-block-editor-iframe-zoom-out-scroll-top-next", `${scrollTopNext}px` ); iframeDocument.documentElement.style.setProperty( "--wp-block-editor-iframe-zoom-out-overflow-behavior", transitionFromRef.current.scrollHeight === transitionFromRef.current.containerHeight ? "auto" : "scroll" ); iframeDocument.documentElement.classList.add("zoom-out-animation"); return iframeDocument.documentElement.animate( getAnimationKeyframes( transitionFromRef.current, transitionToRef.current ), { easing: "cubic-bezier(0.46, 0.03, 0.52, 0.96)", duration: 400 } ); }, [iframeDocument]); const finishZoomOutAnimation = (0, import_element.useCallback)(() => { startAnimationRef.current = false; animationRef.current = null; iframeDocument.documentElement.style.setProperty( "--wp-block-editor-iframe-zoom-out-scale", transitionToRef.current.scaleValue ); iframeDocument.documentElement.style.setProperty( "--wp-block-editor-iframe-zoom-out-frame-size", `${transitionToRef.current.frameSize}px` ); iframeDocument.documentElement.classList.remove("zoom-out-animation"); iframeDocument.documentElement.scrollTop = transitionToRef.current.scrollTop; iframeDocument.documentElement.style.removeProperty( "--wp-block-editor-iframe-zoom-out-scroll-top" ); iframeDocument.documentElement.style.removeProperty( "--wp-block-editor-iframe-zoom-out-scroll-top-next" ); iframeDocument.documentElement.style.removeProperty( "--wp-block-editor-iframe-zoom-out-overflow-behavior" ); transitionFromRef.current = transitionToRef.current; }, [iframeDocument]); const previousIsZoomedOut = (0, import_element.useRef)(false); (0, import_element.useEffect)(() => { const trigger = iframeDocument && previousIsZoomedOut.current !== isZoomedOut; previousIsZoomedOut.current = isZoomedOut; if (!trigger) { return; } startAnimationRef.current = true; if (!isZoomedOut) { return; } iframeDocument.documentElement.classList.add("is-zoomed-out"); return () => { iframeDocument.documentElement.classList.remove("is-zoomed-out"); }; }, [iframeDocument, isZoomedOut]); (0, import_element.useEffect)(() => { if (!iframeDocument) { return; } if (isAutoScaled && transitionFromRef.current.scaleValue !== 1) { transitionFromRef.current.scaleValue = calculateScale({ frameSize: transitionFromRef.current.frameSize, containerWidth, maxContainerWidth, scaleContainerWidth: containerWidth }); } if (scaleValue < 1) { if (!startAnimationRef.current) { iframeDocument.documentElement.style.setProperty( "--wp-block-editor-iframe-zoom-out-scale", scaleValue ); iframeDocument.documentElement.style.setProperty( "--wp-block-editor-iframe-zoom-out-frame-size", `${frameSize}px` ); } iframeDocument.documentElement.style.setProperty( "--wp-block-editor-iframe-zoom-out-content-height", `${contentHeight}px` ); iframeDocument.documentElement.style.setProperty( "--wp-block-editor-iframe-zoom-out-inner-height", `${containerHeight}px` ); iframeDocument.documentElement.style.setProperty( "--wp-block-editor-iframe-zoom-out-container-width", `${containerWidth}px` ); iframeDocument.documentElement.style.setProperty( "--wp-block-editor-iframe-zoom-out-scale-container-width", `${scaleContainerWidth}px` ); } if (startAnimationRef.current) { startAnimationRef.current = false; if (animationRef.current) { animationRef.current.reverse(); const tempTransitionFrom = transitionFromRef.current; const tempTransitionTo = transitionToRef.current; transitionFromRef.current = tempTransitionTo; transitionToRef.current = tempTransitionFrom; } else { transitionFromRef.current.scrollTop = iframeDocument.documentElement.scrollTop; transitionFromRef.current.scrollHeight = iframeDocument.documentElement.scrollHeight; transitionFromRef.current.containerHeight = containerHeight; transitionToRef.current = { scaleValue, frameSize, containerHeight: iframeDocument.documentElement.clientHeight // use clientHeight to get the actual height of the new container after zoom state changes have rendered, as it will be the most up-to-date. }; transitionToRef.current.scrollHeight = computeScrollHeightNext( transitionFromRef.current, transitionToRef.current ); transitionToRef.current.scrollTop = computeScrollTopNext( transitionFromRef.current, transitionToRef.current ); animationRef.current = startZoomOutAnimation(); if (prefersReducedMotion) { finishZoomOutAnimation(); } else { animationRef.current.onfinish = finishZoomOutAnimation; } } } }, [ startZoomOutAnimation, finishZoomOutAnimation, prefersReducedMotion, isAutoScaled, scaleValue, frameSize, iframeDocument, contentHeight, containerWidth, containerHeight, maxContainerWidth, scaleContainerWidth ]); return { isZoomedOut, scaleContainerWidth, contentResizeListener, containerResizeListener }; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { useScaleCanvas }); //# sourceMappingURL=use-scale-canvas.js.map