mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-21 01:53:26 +00:00
Allow to zoom image on mobile if relevant (#3364)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"gitbook": patch
|
||||
---
|
||||
|
||||
Allow to zoom images on mobile if relevant
|
||||
@@ -9,6 +9,8 @@ import { tcls } from '@/lib/tailwind';
|
||||
|
||||
import styles from './ZoomImage.module.css';
|
||||
|
||||
const PADDING = 32; // Padding around the image in the modal, in pixels
|
||||
|
||||
/**
|
||||
* Replacement for an <img> tag that allows zooming.
|
||||
* The implementation uses the experimental View Transition API in Chrome for a smooth transition.
|
||||
@@ -28,14 +30,9 @@ export function ZoomImage(
|
||||
|
||||
// Only allow zooming when image will not actually be larger and on mobile
|
||||
React.useEffect(() => {
|
||||
if (isTouchDevice()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const imageWidth = typeof width === 'number' ? width : 0;
|
||||
let viewWidth = 0;
|
||||
|
||||
const mediaQueryList = window.matchMedia('(min-width: 768px)');
|
||||
const resizeObserver =
|
||||
typeof ResizeObserver !== 'undefined'
|
||||
? new ResizeObserver((entries) => {
|
||||
@@ -52,8 +49,9 @@ export function ZoomImage(
|
||||
: null;
|
||||
|
||||
const onChange = () => {
|
||||
if (!mediaQueryList.matches) {
|
||||
// Don't allow zooming on mobile
|
||||
const viewInModalWidth = window.innerWidth - PADDING * 2;
|
||||
if (viewWidth >= viewInModalWidth) {
|
||||
// If the image will be smaller or same size as it is in the modal, disable zooming
|
||||
setZoomable(false);
|
||||
} else if (resizeObserver && imageWidth && viewWidth && imageWidth <= viewWidth) {
|
||||
// Image can't be zoomed if it's already rendered as it's largest size
|
||||
@@ -63,10 +61,6 @@ export function ZoomImage(
|
||||
}
|
||||
};
|
||||
|
||||
if ('addEventListener' in mediaQueryList) {
|
||||
mediaQueryList.addEventListener('change', onChange);
|
||||
}
|
||||
|
||||
if (imgRef.current) {
|
||||
resizeObserver?.observe(imgRef.current);
|
||||
}
|
||||
@@ -78,9 +72,6 @@ export function ZoomImage(
|
||||
|
||||
return () => {
|
||||
resizeObserver?.disconnect();
|
||||
if ('removeEventListener' in mediaQueryList) {
|
||||
mediaQueryList.removeEventListener('change', onChange);
|
||||
}
|
||||
};
|
||||
}, [imgRef, width]);
|
||||
|
||||
@@ -290,12 +281,3 @@ function startViewTransition(callback: () => void, onEnd?: () => void) {
|
||||
onEnd?.();
|
||||
}
|
||||
}
|
||||
|
||||
function isTouchDevice(): boolean {
|
||||
return (
|
||||
'ontouchstart' in window ||
|
||||
navigator.maxTouchPoints > 0 ||
|
||||
// @ts-ignore
|
||||
navigator.msMaxTouchPoints > 0
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user