gallery_server_client_s190js/public/js/galleryZoom.js
2026-10-26 11:00:14 +01:00

101 lines
3 KiB
JavaScript

// Zoom indipendente per foto e attività.
(() => {
"use strict";
const STORAGE = {
photos: "galleryZoomPhotos",
activities: "galleryZoomActivities"
};
const MIN_SCALE = 0.65;
const MAX_SCALE = 2.5;
const STEP = 0.1;
function getScale(mode) {
const value = Number(localStorage.getItem(STORAGE[mode]));
return Number.isFinite(value) && value >= MIN_SCALE && value <= MAX_SCALE
? value
: 1;
}
function setScale(mode, value) {
const scale = Math.max(MIN_SCALE, Math.min(MAX_SCALE, value));
localStorage.setItem(STORAGE[mode], String(scale));
window.GalleryRenderer?.refreshLayout?.();
}
function currentMode() {
return window.state?.mode === "activities" ? "activities" : "photos";
}
function getMinTile(activities, base) {
return base * getScale(activities ? "activities" : "photos");
}
// Desktop: Ctrl + rotellina.
window.addEventListener("wheel", (event) => {
if (!event.ctrlKey) return;
const gallery = document.getElementById("gallery");
if (!gallery || !gallery.contains(event.target)) return;
event.preventDefault();
const mode = currentMode();
const direction = event.deltaY < 0 ? 1 : -1;
setScale(mode, getScale(mode) + direction * STEP);
}, { passive: false });
// Smartphone/tablet: pinch a due dita nella galleria.
let pinchStartDistance = 0;
let pinchStartScale = 1;
let pinchMode = "photos";
let pinchActive = false;
function distance(touches) {
const dx = touches[0].clientX - touches[1].clientX;
const dy = touches[0].clientY - touches[1].clientY;
return Math.hypot(dx, dy);
}
function isGalleryTouch(event) {
const gallery = document.getElementById("gallery");
return gallery && gallery.contains(event.target);
}
document.addEventListener("touchstart", (event) => {
if (event.touches.length !== 2 || !isGalleryTouch(event)) return;
pinchActive = true;
pinchMode = currentMode();
pinchStartDistance = distance(event.touches);
pinchStartScale = getScale(pinchMode);
}, { passive: true });
document.addEventListener("touchmove", (event) => {
if (!pinchActive || event.touches.length !== 2 || !isGalleryTouch(event)) return;
event.preventDefault();
const currentDistance = distance(event.touches);
if (pinchStartDistance <= 0) return;
const ratio = currentDistance / pinchStartDistance;
const scale = Math.round((pinchStartScale * ratio) * 100) / 100;
const bounded = Math.max(MIN_SCALE, Math.min(MAX_SCALE, scale));
localStorage.setItem(STORAGE[pinchMode], String(bounded));
window.GalleryRenderer?.refreshLayout?.();
}, { passive: false });
document.addEventListener("touchend", (event) => {
if (event.touches.length < 2) pinchActive = false;
}, { passive: true });
document.addEventListener("touchcancel", () => {
pinchActive = false;
}, { passive: true });
window.GalleryZoom = Object.freeze({
getMinTile,
getScale: (mode) => getScale(mode)
});
})();