Repository navigation
Editor: Keep the canvas height stable while resizing the canvas #81163
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
Changes from 5 commits
4442b75
f4cc690
44fb5e4
9670e97
9d92b0f
e9a4096
42e8847
9e1fafe
55fd27d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,11 @@ import { useEffect, useRef, useMemo, useState } from '@wordpress/element'; | |
| import { useSelect } from '@wordpress/data'; | ||
| import { parse } from '@wordpress/blocks'; | ||
| import { store as coreStore } from '@wordpress/core-data'; | ||
| import { useMergeRefs, useViewportMatch } from '@wordpress/compose'; | ||
| import { | ||
| useMergeRefs, | ||
| useResizeObserver, | ||
| useViewportMatch, | ||
| } from '@wordpress/compose'; | ||
|
|
||
| /** | ||
| * Internal dependencies | ||
|
|
@@ -89,6 +93,41 @@ function checkForPostContentAtRootLevel( blocks ) { | |
| return false; | ||
| } | ||
|
|
||
| const CANVAS_MIN_WIDTH = 300; | ||
| const CANVAS_TARGET_ASPECT_RATIO = 9 / 16; | ||
|
|
||
| /** | ||
| * Returns the canvas height, keeping the aspect ratio of the available space | ||
| * without exceeding it. | ||
| * | ||
| * @param {number} width The canvas width in pixels. | ||
| * @param {Object} containerSize The available space, as `{ width, height }` in pixels. | ||
| * @return {number} The canvas height in pixels. | ||
| */ | ||
| function getCanvasHeight( width, containerSize ) { | ||
| const lerp = ( a, b, amount ) => a + ( b - a ) * amount; | ||
|
|
||
| // The narrower the canvas within the available space, the closer to the | ||
| // target aspect ratio. | ||
| const lerpFactor = | ||
| 1 - | ||
| Math.max( | ||
| 0, | ||
| Math.min( | ||
| 1, | ||
| ( width - CANVAS_MIN_WIDTH ) / | ||
| ( containerSize.width - CANVAS_MIN_WIDTH ) | ||
| ) | ||
| ); | ||
| const aspectRatio = lerp( | ||
| containerSize.width / containerSize.height, | ||
| CANVAS_TARGET_ASPECT_RATIO, | ||
| lerpFactor | ||
| ); | ||
|
|
||
| return Math.min( Math.round( width / aspectRatio ), containerSize.height ); | ||
| } | ||
|
|
||
| function VisualEditor( { | ||
| // Ideally as we unify post and site editors, we won't need these props. | ||
| autoFocus, | ||
|
|
@@ -111,7 +150,6 @@ function VisualEditor( { | |
| styles, | ||
| hasCanvasWidth, | ||
| canvasWidth, | ||
| canvasHeight, | ||
| } = useSelect( ( select ) => { | ||
| const { | ||
| getCurrentPostId, | ||
|
|
@@ -121,7 +159,6 @@ function VisualEditor( { | |
| getRenderingMode, | ||
| getDeviceType, | ||
| getCanvasWidth, | ||
| getCanvasHeight, | ||
| } = unlock( select( editorStore ) ); | ||
| const { getPostType, getEditedEntityRecord } = select( coreStore ); | ||
| const postTypeSlug = getCurrentPostType(); | ||
|
|
@@ -166,7 +203,6 @@ function VisualEditor( { | |
| styles: editorSettings.styles, | ||
| hasCanvasWidth: _canvasWidth !== undefined, | ||
| canvasWidth: _canvasWidth, | ||
| canvasHeight: getCanvasHeight(), | ||
| }; | ||
| }, [] ); | ||
| const { isCleanNewPost } = useSelect( editorStore ); | ||
|
|
@@ -191,9 +227,18 @@ function VisualEditor( { | |
| }, [] ); | ||
|
|
||
| const localRef = useRef(); | ||
| const [ isResizingCanvas, setIsResizingCanvas ] = useState( false ); | ||
| const [ globalLayoutSettings ] = useSettings( 'layout' ); | ||
|
|
||
| const [ containerSize, setContainerSize ] = useState(); | ||
| const containerRef = useResizeObserver( ( entries ) => { | ||
| const { width, height } = entries[ 0 ].contentRect; | ||
| setContainerSize( ( size ) => | ||
| size?.width === width && size?.height === height | ||
| ? size | ||
| : { width, height } | ||
| ); | ||
| } ); | ||
|
|
||
| // fallbackLayout is used if there is no Post Content, | ||
| // and for Post Title. | ||
| const fallbackLayout = useMemo( () => { | ||
|
|
@@ -346,14 +391,18 @@ function VisualEditor( { | |
| ! isPreview && renderingMode === 'post-only' && ! isDesignPostType | ||
| ); | ||
|
|
||
| const shouldConstrainCanvasHeight = | ||
| enableResizing && | ||
| canvasWidth && | ||
| containerSize?.height > 0 && | ||
| containerSize?.width > CANVAS_MIN_WIDTH; | ||
| const canvasHeight = shouldConstrainCanvasHeight | ||
| ? getCanvasHeight( canvasWidth, containerSize ) | ||
| : '100%'; | ||
|
|
||
| const centerContentCSS = `display:flex;align-items:center;justify-content:center;`; | ||
| const shouldExpandIframeBody = | ||
| canvasHeight !== undefined && | ||
| ! isResizablePostType && | ||
| ! isResizingCanvas; | ||
| const iframeBodyMinHeightCSS = shouldExpandIframeBody | ||
| ? 'min-height:100vh;' | ||
| : ''; | ||
| const iframeBodyMinHeightCSS = | ||
| hasCanvasWidth && ! isResizablePostType ? 'min-height:100vh;' : ''; | ||
|
|
||
| const iframeStyles = useMemo( () => { | ||
| return [ | ||
|
|
@@ -411,6 +460,7 @@ function VisualEditor( { | |
|
|
||
| return ( | ||
| <div | ||
| ref={ containerRef } | ||
| className={ clsx( | ||
| 'editor-visual-editor', | ||
| // this class is here for backward compatibility reasons. | ||
|
|
@@ -432,13 +482,7 @@ function VisualEditor( { | |
| width={ | ||
| enableResizing && canvasWidth ? canvasWidth + 'px' : '100%' | ||
| } | ||
| height={ | ||
| enableResizing && canvasHeight && ! isResizingCanvas | ||
| ? canvasHeight + 'px' | ||
| : '100%' | ||
| } | ||
| onResizeStart={ () => setIsResizingCanvas( true ) } | ||
| onResizeStop={ () => setIsResizingCanvas( false ) } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like these two props were introduced recently in #80553; do we need to keep them around now that we're not using them anymore?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice catch, fixed in 9e1fafe. Since |
||
| height={ canvasHeight } | ||
| > | ||
| <BlockCanvas | ||
| shouldIframe | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe worth adding some tests for the new function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 55fd27d