Skip to content

Commit

Permalink
Scale the zoom out mode to fit available space (#59342)
Browse files Browse the repository at this point in the history
* Scale zoom out mode frame based on available content width

When there's a small area available to scale the editor, we want to have the editor larger. This implements a smooth sloped clamped scale to scale the zoomed out editor to better fit its available space.

We moved the scale calculation inside of the iframe components so when this is used within the edit post and other packages, they won't need to implement their own scaling.

* update variable name

* Add an explanatory comment

* Add shouldZoom prop to only use zooming if desired

---------

Co-authored-by: scruffian <[email protected]>
Co-authored-by: jeryj <[email protected]>
Co-authored-by: scruffian <[email protected]>
  • Loading branch information
4 people authored Feb 25, 2024
1 parent fa902df commit 944ff08
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 20 deletions.
50 changes: 38 additions & 12 deletions packages/block-editor/src/components/iframe/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { useBlockSelectionClearer } from '../block-selection-clearer';
import { useWritingFlow } from '../writing-flow';
import { getCompatibilityStyles } from './get-compatibility-styles';
import { store as blockEditorStore } from '../../store';

import calculateScale from '../../utils/calculate-scale';
function bubbleEvent( event, Constructor, frame ) {
const init = {};

Expand Down Expand Up @@ -104,26 +104,52 @@ function Iframe( {
contentRef,
children,
tabIndex = 0,
scale = 1,
frameSize = 0,
shouldZoom = false,
readonly,
forwardedRef: ref,
...props
} ) {
const { resolvedAssets, isPreviewMode } = useSelect( ( select ) => {
const settings = select( blockEditorStore ).getSettings();
return {
resolvedAssets: settings.__unstableResolvedAssets,
isPreviewMode: settings.__unstableIsPreviewMode,
};
}, [] );
const { resolvedAssets, isPreviewMode, isZoomOutMode } = useSelect(
( select ) => {
const { getSettings, __unstableGetEditorMode } =
select( blockEditorStore );
const settings = getSettings();
return {
resolvedAssets: settings.__unstableResolvedAssets,
isPreviewMode: settings.__unstableIsPreviewMode,
isZoomOutMode: __unstableGetEditorMode() === 'zoom-out',
};
},
[]
);
const { styles = '', scripts = '' } = resolvedAssets;
const [ iframeDocument, setIframeDocument ] = useState();
const [ bodyClasses, setBodyClasses ] = useState( [] );
const clearerRef = useBlockSelectionClearer();
const [ before, writingFlowRef, after ] = useWritingFlow();
const [ contentResizeListener, { height: contentHeight } ] =
useResizeObserver();
const [
contentResizeListener,
{ height: contentHeight, width: contentWidth },
] = useResizeObserver();

// When zoom-out mode is enabled, the iframe is scaled down to fit the
// content within the viewport.
// At 1000px wide, the iframe is scaled to 45%.
// At 400px wide, the iframe is scaled to 90%.
const scale =
isZoomOutMode && shouldZoom
? calculateScale(
{
maxWidth: 1000,
minWidth: 400,
maxScale: 0.45,
minScale: 0.9,
},
contentWidth
)
: 1;
const frameSize = isZoomOutMode ? 100 : 0;

const setRef = useRefEffect( ( node ) => {
node._load = () => {
setIframeDocument( node.contentDocument );
Expand Down
20 changes: 20 additions & 0 deletions packages/block-editor/src/utils/calculate-scale.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const clamp = ( lowerlimit, width, upperlimit ) => {
if ( width < lowerlimit ) return lowerlimit;
if ( width > upperlimit ) return upperlimit;
return width;
};

export default function calculateScale( scaleConfig, width ) {
const scaleSlope =
( scaleConfig.maxScale - scaleConfig.minScale ) /
( scaleConfig.maxWidth - scaleConfig.minWidth );

const scaleIntercept =
scaleConfig.minScale - scaleSlope * scaleConfig.minWidth;

return clamp(
scaleConfig.maxScale,
scaleSlope * width + scaleIntercept,
scaleConfig.minScale
);
}
15 changes: 7 additions & 8 deletions packages/edit-site/src/components/block-editor/editor-canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,9 @@ import {
const { EditorCanvas: EditorCanvasRoot } = unlock( editorPrivateApis );

function EditorCanvas( { enableResizing, settings, children, ...props } ) {
const { hasBlocks, isFocusMode, templateType, canvasMode, isZoomOutMode } =
useSelect( ( select ) => {
const { getBlockCount, __unstableGetEditorMode } =
select( blockEditorStore );
const { hasBlocks, isFocusMode, templateType, canvasMode } = useSelect(
( select ) => {
const { getBlockCount } = select( blockEditorStore );
const { getEditedPostType, getCanvasMode } = unlock(
select( editSiteStore )
);
Expand All @@ -38,11 +37,12 @@ function EditorCanvas( { enableResizing, settings, children, ...props } ) {
return {
templateType: _templateType,
isFocusMode: FOCUSABLE_ENTITIES.includes( _templateType ),
isZoomOutMode: __unstableGetEditorMode() === 'zoom-out',
canvasMode: getCanvasMode(),
hasBlocks: !! getBlockCount(),
};
}, [] );
},
[]
);
const { setCanvasMode } = unlock( useDispatch( editSiteStore ) );
const [ isFocused, setIsFocused ] = useState( false );

Expand Down Expand Up @@ -107,8 +107,7 @@ function EditorCanvas( { enableResizing, settings, children, ...props } ) {
renderAppender={ showBlockAppender }
styles={ styles }
iframeProps={ {
scale: isZoomOutMode ? 0.45 : undefined,
frameSize: isZoomOutMode ? 100 : undefined,
shouldZoom: true,
className: classnames(
'edit-site-visual-editor__editor-canvas',
{
Expand Down

0 comments on commit 944ff08

Please sign in to comment.