mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-08-04 08:00:12 +00:00
fix(client): block Safari page-level pinch-zoom (#3901)
iOS Safari has ignored the `user-scalable=no` viewport hint since iOS 10, so two-finger pinch still zooms the whole page and can softlock the in-game HUD. Intercept WebKit's non-standard `gesturestart`, `gesturechange` and `gestureend` events at `document` and call `preventDefault()` so the page stays put. The game's own pinch-to-zoom on the map canvas is driven by pointer events (InputHandler) and is unaffected; browsers that do not fire GestureEvent treat the listeners as a no-op. Resolves #2330 If this PR fixes an issue, link it below. If not, delete these two lines. Resolves #(issue number) ## Description: Describe the PR. ## Please complete the following: - [ ] I have added screenshots for all UI updates - [ ] I process any text displayed to the user through translateText() and I've added it to the en.json file - [ ] I have added relevant tests to the test directory - [ ] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced ## Please put your Discord username so you can be contacted if a bug or regression is found: DISCORD_USERNAME
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Blocks the page-level pinch-to-zoom gesture on Safari / WebKit.
|
||||
*
|
||||
* iOS Safari has ignored the `user-scalable=no` viewport hint since iOS 10,
|
||||
* so setting it on the viewport meta tag is not enough to stop two-finger
|
||||
* pinch zoom. The only reliable way to prevent the page from zooming is to
|
||||
* listen for WebKit's non-standard `gesturestart`, `gesturechange` and
|
||||
* `gestureend` events and call `preventDefault()` on them.
|
||||
*
|
||||
* The game's own pinch-to-zoom on the map canvas is driven by pointer
|
||||
* events (see {@link ../InputHandler}), which are unaffected by blocking
|
||||
* these WebKit-only events. Browsers that do not fire `GestureEvent`
|
||||
* (Chrome, Firefox, every Android browser) treat the listeners as a no-op,
|
||||
* so it is safe to install them unconditionally.
|
||||
*
|
||||
* @param target - The EventTarget to attach the listeners to. Defaults to
|
||||
* `document`, which is the scope Safari uses to decide whether to zoom
|
||||
* the page.
|
||||
* @returns A function that removes the installed listeners.
|
||||
*
|
||||
* @see https://github.com/openfrontio/OpenFrontIO/issues/2330
|
||||
*/
|
||||
export function installSafariPinchZoomBlocker(
|
||||
target: EventTarget = document,
|
||||
): () => void {
|
||||
const block = (e: Event) => {
|
||||
e.preventDefault();
|
||||
};
|
||||
|
||||
const events = ["gesturestart", "gesturechange", "gestureend"] as const;
|
||||
for (const type of events) {
|
||||
target.addEventListener(type, block);
|
||||
}
|
||||
|
||||
return () => {
|
||||
for (const type of events) {
|
||||
target.removeEventListener(type, block);
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user