-
🌐 async-utils.jsWeb, 3.69 kB⬇
-
🌐 auth-storage.jsWeb, 735 B⬇
-
🌐 chat-helpers.jsWeb, 8.85 kB⬇
-
🌐 chat-renderer.jsWeb, 70.00 kB⬇
-
🌐 code-overlay.jsWeb, 21.77 kB⬇
-
🌐 confirm-dialog.jsWeb, 3.17 kB⬇
-
🌐 conversation-format-utils.jsWeb, 21.51 kB⬇
-
🌐 diagram-overlay.jsWeb, 7.93 kB⬇
-
🌐 dialog.jsWeb, 2.50 kB⬇
-
🌐 dom-utils.jsWeb, 8.33 kB⬇
-
🌐 drag-reorder.jsWeb, 4.82 kB⬇
-
🌐 elements.jsWeb, 11.06 kB⬇
-
🌐 export-utils.jsWeb, 1.53 kB⬇
-
🌐 format-utils.jsWeb, 29.60 kB⬇
-
🌐 history-navigation.jsWeb, 1.95 kB⬇
-
🌐 hljs-yaml.jsWeb, 5.07 kB⬇
-
🌐 inline-format.jsWeb, 7.35 kB⬇
-
🌐 instant-answer.jsWeb, 19.82 kB⬇
-
🌐 interactive-tools.jsWeb, 38.77 kB⬇
-
🌐 mermaid-fixes.jsWeb, 4.60 kB⬇
-
🌐 mermaid-render.jsWeb, 5.10 kB⬇
-
🌐 mermaid.jsWeb, 195 B⬇
-
🌐 migrations.jsWeb, 12.11 kB⬇
-
🌐 multi-choice-dialog.jsWeb, 1.33 kB⬇
-
🌐 notification-stack.jsWeb, 2.50 kB⬇
-
🌐 options-manager.jsWeb, 45.56 kB⬇
-
🌐 overlay-utils.jsWeb, 4.14 kB⬇
-
🌐 pdf-export.jsWeb, 23.59 kB⬇
-
🌐 pinch-zoom.jsWeb, 3.21 kB⬇
-
🌐 plugin-dialog.jsWeb, 2.17 kB⬇
-
🌐 read-aloud.jsWeb, 33.84 kB⬇
-
🌐 response-pipeline.jsWeb, 55.19 kB⬇
-
🌐 scratchpad-editor.jsWeb, 8.64 kB⬇
-
🌐 scratchpad-export.jsWeb, 3.56 kB⬇
-
🌐 scrollbars.jsWeb, 3.12 kB⬇
-
🌐 selection-manager.jsWeb, 3.76 kB⬇
-
🌐 settings-utils.jsWeb, 31.08 kB⬇
-
🌐 share.jsWeb, 10.75 kB⬇
-
🌐 side-drawer.jsWeb, 9.37 kB⬇
-
🌐 speech-text.jsWeb, 6.60 kB⬇
-
🌐 swipe-navigation.jsWeb, 6.16 kB⬇
-
🌐 table-overlay.jsWeb, 8.10 kB⬇
-
🌐 theme-utils.jsWeb, 8.34 kB⬇
-
🌐 thinking-panel-base.jsWeb, 14.88 kB⬇
-
🌐 ui-sets.jsWeb, 1.00 kB⬇
-
🌐 version-overlay.jsWeb, 4.63 kB⬇
/**
* Document-level pinch gesture that steps the application UI zoom through
* the configured zoom levels. Gestures starting on form fields, or inside
* overlays that handle their own pinch (diagram overlay), are ignored.
*/
import { is_diagram_overlay_open } from './diagram-overlay.js';
/** Ratio of pinch distance change required to move one zoom level. */
const STEP_RATIO = 1.15;
/** Elements whose pinch gestures are not captured by the app zoom. */
const EXCLUDED_SELECTOR = 'input, textarea, select, [contenteditable]';
let app = null;
let active = false;
let last_step_dist = 0;
/**
* Initializes the document-level pinch-zoom gesture.
* @param {App} app_instance - The main application instance.
*/
export function init_pinch_zoom(app_instance) {
app = app_instance;
document.addEventListener('touchstart', on_touch_start);
document.addEventListener('touchmove', on_touch_move, { passive: false });
document.addEventListener('touchend', on_touch_end);
document.addEventListener('touchcancel', on_touch_end);
}
/**
* Starts tracking a two-finger gesture unless it begins on an excluded element.
* @param {TouchEvent} e - The touch event.
*/
function on_touch_start(e) {
if (e.touches.length !== 2 || is_excluded(e.target)) {
active = false;
return;
}
active = true;
last_step_dist = get_touch_distance(e.touches);
}
/**
* Steps the UI zoom one level in or out each time the pinch distance crosses
* the step ratio, and prevents the browser's native page zoom while active.
* @param {TouchEvent} e - The touch event.
*/
function on_touch_move(e) {
if (!active || e.touches.length !== 2) {
active = false;
return;
}
e.preventDefault();
const dist = get_touch_distance(e.touches);
const zoom = app.options_manager.get_ui_zoom();
if (dist > last_step_dist * STEP_RATIO) {
step_zoom(1, zoom, dist);
} else if (dist < last_step_dist / STEP_RATIO) {
step_zoom(-1, zoom, dist);
}
}
/**
* Ends the gesture when fewer than two touches remain.
* @param {TouchEvent} e - The touch event.
*/
function on_touch_end(e) {
if (e.touches.length < 2) {
active = false;
}
}
/**
* Moves one zoom level in the given direction and re-anchors the step distance.
* @param {number} direction - 1 to zoom in, -1 to zoom out.
* @param {number} zoom - Current zoom percentage.
* @param {number} dist - Current pinch distance in pixels.
*/
function step_zoom(direction, zoom, dist) {
const levels = [70, 90, 100, 110, 125, 150, 175, 200];
const index = levels.indexOf(zoom) + direction;
if (index < 0 || index >= levels.length) return;
app.options_manager.set_ui_zoom(levels[index]);
last_step_dist = dist;
}
/**
* Checks whether the gesture target handles its own pinch behavior.
* @param {EventTarget} target - The event target.
* @returns {boolean} True if the gesture should be ignored.
*/
function is_excluded(target) {
return is_diagram_overlay_open() || !!(target instanceof Element && target.closest(EXCLUDED_SELECTOR));
}
/**
* Computes the distance between the first two touches.
* @param {TouchList} touches - The active touches.
* @returns {number} Distance in pixels.
*/
function get_touch_distance(touches) {
return Math.hypot(touches[0].clientX - touches[1].clientX, touches[0].clientY - touches[1].clientY);
}
pinch-zoom.js
×
Type: Web, text/x-java
3.21 Kilobytes
Last Modified 2026-11-04 09:48:28
⬇ Download File
Type: Web, text/x-java
3.21 Kilobytes
Last Modified 2026-11-04 09:48:28
⬇ Download File