I'm using the following code to be able to use the Panzoom JS lib in a custom block. This is a non-React library for panning and zooming elements using CSS transforms:
edit: (props) => {
const blockProps = useBlockProps();
const ref = useRef();
const {
attributes: { url, id, alt },
setAttributes,
} = props;
const setImage = (media) => {
setAttributes({ url: media.url, id: media.id, alt: media.alt });
};
useEffect( () => {
if ( ref.current ) {
var panzoom = Panzoom(ref.current, {
minScale: 1.1,
maxScale: 5,
startScale: 1.1,
animate: true,
duration: 1000,
origin: '50% 0'
});
}
}, []);
return (
<>
<InspectorControls>
<PanelBody
title={__('Settings', 'my-custom-block')}
>
</PanelBody>
</InspectorControls>
<BlockControls>
<MediaReplaceFlow
mediaId={id}
mediaUrl={url}
allowedTypes={['image']}
accept="image/*"
onSelect={setImage}
name={!url ? __('Add Image', 'my-custom-block') : __('Replace Image', 'my-custom-block')}
/>
</BlockControls>
<div {...blockProps}>
<MediaUploadCheck>
{url &&
<div className="panzoom-parent">
<div className="panzoom-element" ref={ref}>
<img
className={`wp-image-${id}`}
src={url}
alt={alt}
/>
</div>
</div>
}
{!url &&
<MediaPlaceholder
accept="image/*"
allowedTypes={['image']}
onSelect={setImage}
value={id}
multiple={false}
handleUpload={true}
labels={
{ title: __('Panzoom Image', 'my-custom-block') }
}
/>
}
</MediaUploadCheck>
</div>
</>
);
}
Everything is almost working as expected except when a new block is added and there's no image already selected. I select an image from the media library and the panning/zooming doesn't work until I save the page where the block is added and reload it. I imagine that the reason it doesn't work when a new block is added is because the reference returned by the useRef
hook is not present in any DOM node the first time. Is there a way to add this reference automatically when a image selected without having to reload the page?
I hope I explained myself. Any help would be appreciated.
useEffect
and dependencies work, not a WordPress problem, that effect only runs once and never updates again because the dependencies never change, aka[]
will always be[]
url
attribute as a dependency inuseEffect
and now the hook is called every time the image changes.