Make GIFs zoomable too

This commit is contained in:
Lim Chee Aun 2023-03-28 23:24:43 +08:00
parent 5de45fe885
commit bf76728528

View file

@ -40,21 +40,39 @@ function Media({ media, showOriginal, autoAnimate, onClick = () => {} }) {
focalBackgroundPosition = `${x.toFixed(0)}% ${y.toFixed(0)}%`; focalBackgroundPosition = `${x.toFixed(0)}% ${y.toFixed(0)}%`;
} }
const imgRef = useRef(); const mediaRef = useRef();
const onUpdate = useCallback(({ x, y, scale }) => { const onUpdate = useCallback(({ x, y, scale }) => {
const { current: img } = imgRef; const { current: media } = mediaRef;
if (img) { if (media) {
const value = make3dTransformValue({ x, y, scale }); const value = make3dTransformValue({ x, y, scale });
img.style.setProperty('transform', value); media.style.setProperty('transform', value);
img.closest('.media-zoom').style.touchAction = scale <= 1 ? 'pan-x' : ''; media.closest('.media-zoom').style.touchAction =
scale <= 1 ? 'pan-x' : '';
} }
}, []); }, []);
const quickPinchZoomProps = {
draggableUnZoomed: false,
inertiaFriction: 0.9,
containerProps: {
className: 'media-zoom',
style: {
width: 'inherit',
height: 'inherit',
justifyContent: 'inherit',
alignItems: 'inherit',
// display: 'inherit',
},
},
onUpdate,
};
if (type === 'image' || (type === 'unknown' && previewUrl && url)) { if (type === 'image' || (type === 'unknown' && previewUrl && url)) {
// Note: type: unknown might not have width/height // Note: type: unknown might not have width/height
quickPinchZoomProps.containerProps.style.display = 'inherit';
return ( return (
<div <div
class={`media media-image`} class={`media media-image`}
@ -66,23 +84,9 @@ function Media({ media, showOriginal, autoAnimate, onClick = () => {} }) {
} }
> >
{showOriginal ? ( {showOriginal ? (
<QuickPinchZoom <QuickPinchZoom {...quickPinchZoomProps}>
draggableUnZoomed={false}
inertiaFriction={0.9}
containerProps={{
className: 'media-zoom',
style: {
width: 'inherit',
height: 'inherit',
justifyContent: 'inherit',
alignItems: 'inherit',
display: 'inherit',
},
}}
onUpdate={onUpdate}
>
<img <img
ref={imgRef} ref={mediaRef}
src={mediaURL} src={mediaURL}
alt={description} alt={description}
width={width} width={width}
@ -122,6 +126,23 @@ function Media({ media, showOriginal, autoAnimate, onClick = () => {} }) {
const formattedDuration = formatDuration(original.duration); const formattedDuration = formatDuration(original.duration);
const hoverAnimate = !showOriginal && !autoAnimate && isGIF; const hoverAnimate = !showOriginal && !autoAnimate && isGIF;
const autoGIFAnimate = !showOriginal && autoAnimate && isGIF; const autoGIFAnimate = !showOriginal && autoAnimate && isGIF;
const videoHTML = `
<video
src="${url}"
poster="${previewUrl}"
width="${width}"
height="${height}"
preload="auto"
autoplay
muted="${isGIF}"
${isGIF ? '' : 'controls'}
playsinline
loop="${loopable}"
${isGIF ? 'ondblclick="this.paused ? this.play() : this.pause()"' : ''}
></video>
`;
return ( return (
<div <div
class={`media media-${isGIF ? 'gif' : 'video'} ${ class={`media media-${isGIF ? 'gif' : 'video'} ${
@ -157,29 +178,22 @@ function Media({ media, showOriginal, autoAnimate, onClick = () => {} }) {
}} }}
> >
{showOriginal || autoGIFAnimate ? ( {showOriginal || autoGIFAnimate ? (
<div isGIF ? (
dangerouslySetInnerHTML={{ <QuickPinchZoom {...quickPinchZoomProps}>
__html: ` <div
<video ref={mediaRef}
src="${url}" dangerouslySetInnerHTML={{
poster="${previewUrl}" __html: videoHTML,
width="${width}" }}
height="${height}" />
preload="auto" </QuickPinchZoom>
autoplay ) : (
muted="${isGIF}" <div
${isGIF ? '' : 'controls'} dangerouslySetInnerHTML={{
playsinline __html: videoHTML,
loop="${loopable}" }}
${ />
isGIF )
? 'ondblclick="this.paused ? this.play() : this.pause()"'
: ''
}
></video>
`,
}}
/>
) : isGIF ? ( ) : isGIF ? (
<video <video
ref={videoRef} ref={videoRef}