Skip to content

Commit

Permalink
Show nearest zone to mouse by hooking into resizeable box events
Browse files Browse the repository at this point in the history
  • Loading branch information
talldan committed Oct 31, 2022
1 parent 97105cd commit 95c44e0
Show file tree
Hide file tree
Showing 3 changed files with 135 additions and 84 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,7 @@ import { getValidAlignments } from '../../hooks/align';
import { getDistanceToNearestEdge } from '../../utils/math';

const highlightedZoneEdges = [ 'right' ];
function detectNearestZone( mouseMoveEvent, zones ) {
const { clientX, clientY } = mouseMoveEvent;
const point = { x: clientX, y: clientY };

function detectNearestZone( point, zones ) {
let candidateZone;
let candidateDistance;

Expand All @@ -58,6 +55,7 @@ function detectNearestZone( mouseMoveEvent, zones ) {
export default function BlockAlignmentVisualizer( {
allowedAlignments,
clientId,
showNearestAlignmentToCoords,
} ) {
const layout = useLayout();
const { blockName, parentClientId, parentBlockName } = useSelect(
Expand Down Expand Up @@ -86,6 +84,18 @@ export default function BlockAlignmentVisualizer( {
BlockList.__unstableElementContext
);

useEffect( () => {
if ( showNearestAlignmentToCoords ) {
const nearestZone = detectNearestZone(
showNearestAlignmentToCoords,
zones.current
);
if ( nearestZone?.name !== highlightedZone ) {
setHighlightedZone( nearestZone?.name );
}
}
}, [ showNearestAlignmentToCoords ] );

useEffect( () => {
const parentElement = parentBlockElement ?? rootBlockListElement;
if ( ! blockElement || ! parentElement ) {
Expand Down Expand Up @@ -202,12 +212,6 @@ export default function BlockAlignmentVisualizer( {
flip={ false }
resize={ false }
__unstableSlotName=""
onMouseMove={ ( event ) => {
const nearestZone = detectNearestZone( event, zones.current );
if ( nearestZone.name !== highlightedZone ) {
setHighlightedZone( nearestZone.name );
}
} }
>
<Iframe
style={ coverElementStyle }
Expand Down
99 changes: 25 additions & 74 deletions packages/block-library/src/image/image.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { isBlobURL } from '@wordpress/blob';
import {
ExternalLink,
PanelBody,
ResizableBox,
Spinner,
TextareaControl,
TextControl,
Expand All @@ -31,7 +30,6 @@ import {
__experimentalImageEditingProvider as ImageEditingProvider,
__experimentalGetElementClassName,
__experimentalUseBorderProps as useBorderProps,
__experimentalBlockAlignmentVisualizer as BlockAlignmentVisualizer,
} from '@wordpress/block-editor';
import {
useEffect,
Expand All @@ -40,7 +38,7 @@ import {
useRef,
useCallback,
} from '@wordpress/element';
import { __, sprintf, isRTL } from '@wordpress/i18n';
import { __, sprintf } from '@wordpress/i18n';
import { getFilename } from '@wordpress/url';
import {
createBlock,
Expand All @@ -62,6 +60,7 @@ import { store as coreStore } from '@wordpress/core-data';
import { createUpgradedEmbedBlock } from '../embed/util';
import useClientWidth from './use-client-width';
import { isExternalImage } from './edit';
import ResizableImageControls from './resizable-image-controls';

/**
* Module constants
Expand Down Expand Up @@ -163,7 +162,6 @@ export default function Image( {
setLoadedNaturalSize,
] = useState( {} );
const [ isEditingImage, setIsEditingImage ] = useState( false );
const [ isResizingImage, setIsResizingImage ] = useState( false );
const [ externalBlob, setExternalBlob ] = useState();
const clientWidth = useClientWidth( containerRef, [ align ] );
const isResizable =
Expand Down Expand Up @@ -234,12 +232,10 @@ export default function Image( {

function onResizeStart() {
toggleSelection( false );
setIsResizingImage( true );
}

function onResizeStop() {
toggleSelection( true );
setIsResizingImage( false );
}

function onImageError() {
Expand Down Expand Up @@ -556,75 +552,30 @@ export default function Image( {
// becomes available.
const maxWidthBuffer = maxWidth * 2.5;

let showRightHandle = false;
let showLeftHandle = false;

/* eslint-disable no-lonely-if */
// See https://github.com/WordPress/gutenberg/issues/7584.
if ( align === 'center' ) {
// When the image is centered, show both handles.
showRightHandle = true;
showLeftHandle = true;
} else if ( isRTL() ) {
// In RTL mode the image is on the right by default.
// Show the right handle and hide the left handle only when it is
// aligned left. Otherwise always show the left handle.
if ( align === 'left' ) {
showRightHandle = true;
} else {
showLeftHandle = true;
}
} else {
// Show the left handle and hide the right handle only when the
// image is aligned right. Otherwise always show the right handle.
if ( align === 'right' ) {
showLeftHandle = true;
} else {
showRightHandle = true;
}
}
/* eslint-enable no-lonely-if */

img = (
<>
{ isResizingImage && (
<BlockAlignmentVisualizer
clientId={ clientId }
allowedAlignments={ [ 'none', 'wide', 'full' ] }
/>
) }
<ResizableBox
size={ {
width: width ?? 'auto',
height: height && ! hasCustomBorder ? height : 'auto',
} }
showHandle={ isSelected }
minWidth={ minWidth }
maxWidth={ maxWidthBuffer }
minHeight={ minHeight }
maxHeight={ maxWidthBuffer / ratio }
lockAspectRatio
enable={ {
top: false,
right: showRightHandle,
bottom: true,
left: showLeftHandle,
} }
onResizeStart={ onResizeStart }
onResizeStop={ ( event, direction, elt, delta ) => {
onResizeStop();
setAttributes( {
width: parseInt( currentWidth + delta.width, 10 ),
height: parseInt(
currentHeight + delta.height,
10
),
} );
} }
>
{ img }
</ResizableBox>
</>
<ResizableImageControls
align={ align }
clientId={ clientId }
minWidth={ minWidth }
maxWidth={ maxWidthBuffer }
minHeight={ minHeight }
maxHeight={ maxWidthBuffer / ratio }
onResizeStart={ onResizeStart }
onResizeStop={ ( event, direction, elt, delta ) => {
onResizeStop();
setAttributes( {
width: parseInt( currentWidth + delta.width, 10 ),
height: parseInt( currentHeight + delta.height, 10 ),
} );
} }
showHandle={ isSelected }
size={ {
width: width ?? 'auto',
height: height && ! hasCustomBorder ? height : 'auto',
} }
>
{ img }
</ResizableImageControls>
);
}

Expand Down
96 changes: 96 additions & 0 deletions packages/block-library/src/image/resizable-image-controls.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/**
* WordPress dependencies
*/
import { useState } from '@wordpress/element';

/**
* WordPress dependencies
*/
import { __experimentalBlockAlignmentVisualizer as BlockAlignmentVisualizer } from '@wordpress/block-editor';
import { ResizableBox } from '@wordpress/components';
import { isRTL } from '@wordpress/i18n';

export default function ResizableImageControls( {
align,
children,
clientId,
minWidth,
maxWidth,
minHeight,
maxHeight,
showHandle,
onResizeStart,
onResizeStop,
size,
} ) {
let showRightHandle = false;
let showLeftHandle = false;
const [ isResizingImage, setIsResizingImage ] = useState( false );
const [ mousePosition, setMousePosition ] = useState();

/* eslint-disable no-lonely-if */
// See https://github.com/WordPress/gutenberg/issues/7584.
if ( align === 'center' ) {
// When the image is centered, show both handles.
showRightHandle = true;
showLeftHandle = true;
} else if ( isRTL() ) {
// In RTL mode the image is on the right by default.
// Show the right handle and hide the left handle only when it is
// aligned left. Otherwise always show the left handle.
if ( align === 'left' ) {
showRightHandle = true;
} else {
showLeftHandle = true;
}
} else {
// Show the left handle and hide the right handle only when the
// image is aligned right. Otherwise always show the right handle.
if ( align === 'right' ) {
showLeftHandle = true;
} else {
showRightHandle = true;
}
}
/* eslint-enable no-lonely-if */

return (
<>
{ isResizingImage && (
<BlockAlignmentVisualizer
clientId={ clientId }
allowedAlignments={ [ 'none', 'wide', 'full' ] }
showNearestAlignmentToCoords={ mousePosition }
/>
) }
<ResizableBox
size={ size }
showHandle={ showHandle }
minWidth={ minWidth }
maxWidth={ maxWidth }
minHeight={ minHeight }
maxHeight={ maxHeight }
lockAspectRatio
enable={ {
top: false,
right: showRightHandle,
bottom: true,
left: showLeftHandle,
} }
onResizeStart={ ( ...resizeArgs ) => {
onResizeStart( ...resizeArgs );
setIsResizingImage( true );
} }
onResize={ ( event ) => {
setMousePosition( { x: event.clientX, y: event.clientY } );
} }
onResizeStop={ ( ...resizeArgs ) => {
onResizeStop( ...resizeArgs );
setIsResizingImage( false );
} }
>
{ children }
</ResizableBox>
</>
);
}

0 comments on commit 95c44e0

Please sign in to comment.