Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Position scaled html within available container space #66034

Merged
merged 11 commits into from
Oct 15, 2024
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;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't appear to have any effect.

}
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
};
Comment on lines +302 to +312
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should be defined inside the useEffect since that's the only place it's used.


// 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',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would maybe rename this to --wp-block-editor-iframe-zoom-out-scale-container-width instead since this is the width of the block-editor-iframe__scale-container.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may not always call it scale container, so I'd be fine leaving this one named as is.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, it may be changed, but for the current reader, the connection between the two would be more clear if the variable was named the same as the container that it's setting the width for.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

--wp-block-editor-iframe-scale-container-width would be acceptable too.

`${ Math.max( initialContainerWidth.current, containerWidth ) }px`
Copy link
Contributor

@ajlende ajlende Oct 16, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would make this a variable since it's used in three places where they are expected to always be the same.

);

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`
// );
Comment on lines +381 to +384
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think these comments were meant to be committed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope!


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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should be able to remove this from the JS too since it's no longer used outside the iframe.

$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);
Comment on lines -15 to -16
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was causing the scrollbar to be hidden off canvas.

$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;
draganescu marked this conversation as resolved.
Show resolved Hide resolved
}
Loading