101 lines
3 KiB
JavaScript
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)
|
|
});
|
|
})();
|