feat: allow mobile user zooming in image preview (#3880)

* Set viewport scalable in image preview dialog for mobile zooming and reset it on destroy

* Format with prettier

* move setViewportScalable() into useEffect

* use const instead of function
pull/3966/head
auphone 5 months ago committed by GitHub
parent ea881338a9
commit 0711ac4ecb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,5 +1,5 @@
import { XIcon } from "lucide-react"; import { XIcon } from "lucide-react";
import React, { useState } from "react"; import React, { useEffect, useState } from "react";
import { generateDialog } from "./Dialog"; import { generateDialog } from "./Dialog";
import "@/less/preview-image-dialog.less"; import "@/less/preview-image-dialog.less";
@ -31,7 +31,7 @@ const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }:
let endX = -1; let endX = -1;
const handleCloseBtnClick = () => { const handleCloseBtnClick = () => {
destroy(); destroyAndResetViewport();
}; };
const handleTouchStart = (event: React.TouchEvent) => { const handleTouchStart = (event: React.TouchEvent) => {
@ -73,7 +73,7 @@ const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }:
setState(defaultState); setState(defaultState);
setCurrentIndex(currentIndex - 1); setCurrentIndex(currentIndex - 1);
} else { } else {
destroy(); destroyAndResetViewport();
} }
}; };
@ -82,7 +82,7 @@ const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }:
setState(defaultState); setState(defaultState);
setCurrentIndex(currentIndex + 1); setCurrentIndex(currentIndex + 1);
} else { } else {
destroy(); destroyAndResetViewport();
} }
}; };
@ -107,11 +107,36 @@ const PreviewImageDialog: React.FC<Props> = ({ destroy, imgUrls, initialIndex }:
}); });
}; };
const setViewportScalable = () => {
const viewport = document.querySelector("meta[name=viewport]");
if (viewport) {
const contentAttrs = viewport.getAttribute("content");
if (contentAttrs) {
viewport.setAttribute("content", contentAttrs.replace("user-scalable=no", "user-scalable=yes"));
}
}
};
const destroyAndResetViewport = () => {
const viewport = document.querySelector("meta[name=viewport]");
if (viewport) {
const contentAttrs = viewport.getAttribute("content");
if (contentAttrs) {
viewport.setAttribute("content", contentAttrs.replace("user-scalable=yes", "user-scalable=no"));
}
}
destroy();
};
const imageComputedStyle = { const imageComputedStyle = {
transform: `scale(${state.scale})`, transform: `scale(${state.scale})`,
transformOrigin: `${state.originX === -1 ? "center" : `${state.originX}px`} ${state.originY === -1 ? "center" : `${state.originY}px`}`, transformOrigin: `${state.originX === -1 ? "center" : `${state.originX}px`} ${state.originY === -1 ? "center" : `${state.originY}px`}`,
}; };
useEffect(() => {
setViewportScalable();
}, []);
return ( return (
<> <>
<div className="btns-container"> <div className="btns-container">

Loading…
Cancel
Save