Skip to content

Commit

Permalink
Position scaled html within available container space (#66034)
Browse files Browse the repository at this point in the history
* Positions the iframed HTML canvas via translateX rather than margin-left on the iframe in order to have the scrollbar for the iframe available instead of hidden off canvas. This also fixes issues with the vertical toolbar and inserters not rerendering to their new positions.

* Renames prevContainerWidthRef to initialContainerWidth so it's clearer that this is the point when zoom out was initialized, then renames the CSS vars prev-container-width to outer-container-width, using the larger value of containerWidth or initialContainerWidth so it can be more consistently named.

* Force largest available window size to scale from
If you started with a sidebar open, then entered zoom out, then closed the sidebar, your scaled canvas would be too large. It should match the same size as if you start with no sidebars open, then enter zoom out. This also fixes an issue where scaling could be larger than 1.

* Only animate scaling on entry and exit of zoom out mode to improve animations when opening and closing sidebars.

* Known divergence: When starting from a smaller canvas (sidebars open), entering zoom out, then closing sidebars, there will be reflow on the canvas.

---------

Co-authored-by: jeryj <jeryj@git.wordpress.org>
Co-authored-by: ajlende <ajlende@git.wordpress.org>
Co-authored-by: stokesman <presstoke@git.wordpress.org>
Co-authored-by: ciampo <mciampini@git.wordpress.org>
Co-authored-by: MaggieCabrera <onemaggie@git.wordpress.org>
Co-authored-by: draganescu <andraganescu@git.wordpress.org>
Co-authored-by: getdave <get_dave@git.wordpress.org>
Co-authored-by: dhruvang21 <dhruvang21@git.wordpress.org>
Co-authored-by: AhmarZaidi <ahmarzaidi@git.wordpress.org>
Co-authored-by: kevin940726 <kevin940726@git.wordpress.org>
  • Loading branch information
11 people authored and ajlende committed Oct 16, 2024
1 parent a9ab8b8 commit 98d8034
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 28 deletions.
5 changes: 0 additions & 5 deletions packages/base-styles/_animations.scss
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,6 @@
@include reduce-motion("animation");
}

@mixin editor-canvas-resize-animation() {
transition: all 0.4s cubic-bezier(0.46, 0.03, 0.52, 0.96);
@include reduce-motion("transition");
}

// Deprecated
@mixin edit-post__fade-in-animation($speed: 0.08s, $delay: 0s) {
@warn "The `edit-post__fade-in-animation` mixin is deprecated. Use `animation__fade-in` instead.";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ iframe[name="editor-canvas"] {
height: 100%;
display: block;
background-color: transparent;
@include editor-canvas-resize-animation;
}
25 changes: 20 additions & 5 deletions packages/block-editor/src/components/iframe/content.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,33 @@

.block-editor-iframe__html {
transform-origin: top center;
@include editor-canvas-resize-animation;
// 400ms should match the animation speed used in iframe/index.js
$zoomOutAnimation: all 400ms cubic-bezier(0.46, 0.03, 0.52, 0.96);

// We don't want to animate the transform of the translateX because it is used
// to "center" the canvas. Leaving it on causes the canvas to slide around in
// odd ways.
transition: $zoomOutAnimation, transform 0s scale 0s;
@include reduce-motion("transition");

&.zoom-out-animation {
// we only want to animate the scaling when entering zoom out. When sidebars
// are toggled, the resizing of the iframe handles scaling the canvas as well,
// and the doubled animations cause very odd animations.
transition: $zoomOutAnimation, transform 0s;
}
}

.block-editor-iframe__html.is-zoomed-out {
$scale: var(--wp-block-editor-iframe-zoom-out-scale);
$frame-size: var(--wp-block-editor-iframe-zoom-out-frame-size);
$inner-height: var(--wp-block-editor-iframe-zoom-out-inner-height);
$content-height: var(--wp-block-editor-iframe-zoom-out-content-height);
$prev-container-width: var(--wp-block-editor-iframe-zoom-out-prev-container-width);

transform: scale(#{$scale});

$outer-container-width: var(--wp-block-editor-iframe-zoom-out-outer-container-width);
$container-width: var(--wp-block-editor-iframe-zoom-out-container-width, 100vw);
// Apply an X translation to center the scaled content within the available space.
transform: translateX(calc(( #{$outer-container-width} - #{ $container-width }) / 2 / #{$scale}));
scale: #{$scale};
background-color: $gray-300;

// Chrome seems to respect that transform scale shouldn't affect the layout size of the element,
Expand Down
67 changes: 55 additions & 12 deletions packages/block-editor/src/components/iframe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ function Iframe( {
}, [] );
const { styles = '', scripts = '' } = resolvedAssets;
const [ iframeDocument, setIframeDocument ] = useState();
const prevContainerWidthRef = useRef();
const initialContainerWidth = useRef();
const [ bodyClasses, setBodyClasses ] = useState( [] );
const clearerRef = useBlockSelectionClearer();
const [ before, writingFlowRef, after ] = useWritingFlow();
Expand Down Expand Up @@ -243,7 +243,7 @@ function Iframe( {

useEffect( () => {
if ( ! isZoomedOut ) {
prevContainerWidthRef.current = containerWidth;
initialContainerWidth.current = containerWidth;
}
}, [ containerWidth, isZoomedOut ] );

Expand Down Expand Up @@ -298,14 +298,49 @@ function Iframe( {

useEffect( () => cleanup, [ cleanup ] );

const zoomOutAnimationClassnameRef = useRef( null );
const handleZoomOutAnimationClassname = () => {
clearTimeout( zoomOutAnimationClassnameRef.current );

iframeDocument.documentElement.classList.add( 'zoom-out-animation' );

zoomOutAnimationClassnameRef.current = setTimeout( () => {
iframeDocument.documentElement.classList.remove(
'zoom-out-animation'
);
}, 400 ); // 400ms should match the animation speed used in components/iframe/content.scss
};

// Toggle zoom out CSS Classes only when zoom out mode changes. We could add these into the useEffect
// that controls settings the CSS variables, but then we would need to do more work to ensure we're
// only toggling these when the zoom out mode changes, as that useEffect is also triggered by a large
// number of dependencies.
useEffect( () => {
if ( ! iframeDocument || ! isZoomedOut ) {
return;
}

handleZoomOutAnimationClassname();
iframeDocument.documentElement.classList.add( 'is-zoomed-out' );

return () => {
handleZoomOutAnimationClassname();
iframeDocument.documentElement.classList.remove( 'is-zoomed-out' );
};
}, [ iframeDocument, isZoomedOut ] );

// Calculate the scaling and CSS variables for the zoom out canvas
useEffect( () => {
if ( ! iframeDocument || ! isZoomedOut ) {
return;
}

const maxWidth = 750;
// Note: When we initialize the zoom out when the canvas is smaller (sidebars open),
// initialContainerWidth will be smaller than the full page, and reflow will happen
// when the canvas area becomes larger due to sidebars closing. This is a known but
// minor divergence for now.

// This scaling calculation has to happen within the JS because CSS calc() can
// only divide and multiply by a unitless value. I.e. calc( 100px / 2 ) is valid
// but calc( 100px / 2px ) is not.
Expand All @@ -314,7 +349,10 @@ function Iframe( {
scale === 'default'
? ( Math.min( containerWidth, maxWidth ) -
parseInt( frameSize ) * 2 ) /
prevContainerWidthRef.current
Math.max(
initialContainerWidth.current,
containerWidth
)
: scale
);

Expand All @@ -336,13 +374,16 @@ function Iframe( {
`${ containerWidth }px`
);
iframeDocument.documentElement.style.setProperty(
'--wp-block-editor-iframe-zoom-out-prev-container-width',
`${ prevContainerWidthRef.current }px`
'--wp-block-editor-iframe-zoom-out-outer-container-width',
`${ Math.max( initialContainerWidth.current, containerWidth ) }px`
);

return () => {
iframeDocument.documentElement.classList.remove( 'is-zoomed-out' );
// iframeDocument.documentElement.style.setProperty(
// '--wp-block-editor-iframe-zoom-out-outer-container-width',
// `${ Math.max( initialContainerWidth.current, containerWidth ) }px`
// );

return () => {
iframeDocument.documentElement.style.removeProperty(
'--wp-block-editor-iframe-zoom-out-scale'
);
Expand All @@ -359,7 +400,7 @@ function Iframe( {
'--wp-block-editor-iframe-zoom-out-container-width'
);
iframeDocument.documentElement.style.removeProperty(
'--wp-block-editor-iframe-zoom-out-prev-container-width'
'--wp-block-editor-iframe-zoom-out-outer-container-width'
);
};
}, [
Expand Down Expand Up @@ -460,10 +501,12 @@ function Iframe( {
isZoomedOut && 'is-zoomed-out'
) }
style={ {
'--wp-block-editor-iframe-zoom-out-container-width':
isZoomedOut && `${ containerWidth }px`,
'--wp-block-editor-iframe-zoom-out-prev-container-width':
isZoomedOut && `${ prevContainerWidthRef.current }px`,
'--wp-block-editor-iframe-zoom-out-outer-container-width':
isZoomedOut &&
`${ Math.max(
initialContainerWidth.current,
containerWidth
) }px`,
} }
>
{ iframe }
Expand Down
11 changes: 6 additions & 5 deletions packages/block-editor/src/components/iframe/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
}

.block-editor-iframe__scale-container.is-zoomed-out {
$container-width: var(--wp-block-editor-iframe-zoom-out-container-width, 100vw);
$prev-container-width: var(--wp-block-editor-iframe-zoom-out-prev-container-width, 100vw);
width: $prev-container-width;
// This is to offset the movement of the iframe when we open sidebars
margin-left: calc(-1 * (#{$prev-container-width} - #{$container-width}) / 2);
$outer-container-width: var(--wp-block-editor-iframe-zoom-out-outer-container-width, 100vw);
width: $outer-container-width;
// Position the iframe so that it is always aligned with the right side so that
// the scrollbar is always visible on the right side
position: absolute;
right: 0;
}

0 comments on commit 98d8034

Please sign in to comment.