Performance fix
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
import { onMount } from 'svelte';
|
||||
import { env } from '$env/dynamic/public';
|
||||
|
||||
// Svelte 5 Runes for Reactivity
|
||||
// Svelte 5 Runes for Core Reactivity
|
||||
let photos = $state([]);
|
||||
let nextToken = $state(null);
|
||||
let loading = $state(false);
|
||||
@@ -10,18 +10,20 @@
|
||||
let activePhoto = $state(null);
|
||||
let observerTarget;
|
||||
|
||||
// Lightbox Pan & Zoom Matrix State
|
||||
// Lightbox Control Flags
|
||||
let isZoomed = $state(false);
|
||||
let lightboxContainer = $state(null);
|
||||
let isDragging = $state(false);
|
||||
let imageMatrixWrapper = $state(null); // Explicit ref to bypass reactive state lag
|
||||
let isDragging = false; // Internal mutable flag (not a reactive rune)
|
||||
|
||||
// Coordinate state vectors for custom 2D transform panning
|
||||
let panX = $state(0);
|
||||
let panY = $state(0);
|
||||
// Coordinate Vector Matrix (using raw numbers to bypass Svelte state loops on fast cycles)
|
||||
let currentX = 0;
|
||||
let currentY = 0;
|
||||
let startX = 0;
|
||||
let startY = 0;
|
||||
let ticking = false;
|
||||
|
||||
// Touch tracking coordinates for mobile swipes
|
||||
// Touch tracking coordinates for layout pagination swipes
|
||||
let touchStartX = 0;
|
||||
let touchEndX = 0;
|
||||
|
||||
@@ -75,8 +77,11 @@
|
||||
function resetZoom() {
|
||||
isZoomed = false;
|
||||
isDragging = false;
|
||||
panX = 0;
|
||||
panY = 0;
|
||||
currentX = 0;
|
||||
currentY = 0;
|
||||
if (imageMatrixWrapper) {
|
||||
imageMatrixWrapper.style.transform = `translate3d(0px, 0px, 0px)`;
|
||||
}
|
||||
}
|
||||
|
||||
function nextPhoto() {
|
||||
@@ -100,11 +105,11 @@
|
||||
activePhoto = null;
|
||||
}
|
||||
if (e.key === 'ArrowRight' && !isZoomed) {
|
||||
e.preventDefault(); // 👈 Stops the underlying grid buttons from changing focus
|
||||
e.preventDefault();
|
||||
nextPhoto();
|
||||
}
|
||||
if (e.key === 'ArrowLeft' && !isZoomed) {
|
||||
e.preventDefault(); // 👈 Stops the underlying grid buttons from changing focus
|
||||
e.preventDefault();
|
||||
prevPhoto();
|
||||
}
|
||||
}
|
||||
@@ -118,34 +123,46 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Dynamic Pointer Interface Input Routing (Desktop Mouse & Mobile Touch Dragging)
|
||||
// HIGH PERFORMANCE NATIVE INTERFACE PIPELINE (60FPS Engine)
|
||||
function pointerDown(clientX, clientY, target) {
|
||||
if (!isZoomed) return;
|
||||
if (target.tagName === 'BUTTON' || target.closest('button')) return;
|
||||
|
||||
isDragging = true;
|
||||
startX = clientX - panX;
|
||||
startY = clientY - panY;
|
||||
startX = clientX - currentX;
|
||||
startY = clientY - currentY;
|
||||
}
|
||||
|
||||
function pointerMove(clientX, clientY, preventDefaultFunc) {
|
||||
function pointerMove(clientX, clientY) {
|
||||
if (!isDragging) return;
|
||||
if (typeof preventDefaultFunc === 'function') preventDefaultFunc();
|
||||
|
||||
panX = clientX - startX;
|
||||
panY = clientY - startY;
|
||||
currentX = clientX - startX;
|
||||
currentY = clientY - startY;
|
||||
|
||||
// requestAnimationFrame schedules updates with the browser screen refresh cycle
|
||||
if (!ticking) {
|
||||
window.requestAnimationFrame(() => {
|
||||
if (imageMatrixWrapper) {
|
||||
imageMatrixWrapper.style.transform = `translate3d(${currentX}px, ${currentY}px, 0px)`;
|
||||
}
|
||||
ticking = false;
|
||||
});
|
||||
ticking = true;
|
||||
}
|
||||
}
|
||||
|
||||
function pointerUp() {
|
||||
isDragging = false;
|
||||
}
|
||||
|
||||
// Desktop Mouse Adapters
|
||||
// Desktop Mouse Interface Subscriptions
|
||||
function handleMouseDown(e) { pointerDown(e.clientX, e.clientY, e.target); }
|
||||
function handleMouseMove(e) { pointerMove(e.clientX, e.clientY, () => e.preventDefault()); }
|
||||
function handleMouseMove(e) {
|
||||
if(isDragging) e.preventDefault();
|
||||
pointerMove(e.clientX, e.clientY);
|
||||
}
|
||||
|
||||
// Mobile Touch Panning Adapters
|
||||
// Mobile Touch Panning Adapters
|
||||
// Mobile Touch Interface Subscriptions
|
||||
function handleTouchStart(e) {
|
||||
if (isZoomed) {
|
||||
const touch = e.touches[0];
|
||||
@@ -156,9 +173,10 @@
|
||||
}
|
||||
|
||||
function handleTouchMove(e) {
|
||||
if (isZoomed && e.touches.length === 1) { // 👈 Ensures single finger panning behaves correctly
|
||||
if (isZoomed && e.touches.length === 1) {
|
||||
e.preventDefault(); // Kill native momentum bouncing
|
||||
const touch = e.touches[0];
|
||||
pointerMove(touch.clientX, touch.clientY, () => e.preventDefault());
|
||||
pointerMove(touch.clientX, touch.clientY);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +236,7 @@
|
||||
onclick={(e) => { if (e.target === e.currentTarget) activePhoto = null; }}
|
||||
onkeydown={handleKeyDown}
|
||||
ontouchstart={handleTouchStart}
|
||||
ontouchmove={handleTouchMove}
|
||||
ontouchmove={handleTouchMove}
|
||||
ontouchend={handleTouchEnd}
|
||||
>
|
||||
<div class="w-full flex justify-between items-center z-50 p-2 pointer-events-none">
|
||||
@@ -315,16 +333,17 @@
|
||||
{/if}
|
||||
|
||||
<div
|
||||
class="max-w-full max-h-full flex items-center justify-center p-2 transition-transform duration-300 ease-out"
|
||||
style="transform: translate3d({panX}px, {panY}px, 0px);"
|
||||
bind:this={imageMatrixWrapper}
|
||||
class="max-w-full max-h-full flex items-center justify-center p-2 ease-out will-change-transform"
|
||||
>
|
||||
<img
|
||||
src={activePhoto.fullUrl}
|
||||
alt="Gallery Content Visual"
|
||||
draggable="false"
|
||||
class="max-h-[70vh] max-w-full rounded shadow-2xl select-none pointer-events-none transition-transform duration-300 will-change-transform"
|
||||
style="transform: scale({isZoomed ? 3.8 : 1});"
|
||||
/> </div>
|
||||
class="max-h-[70vh] max-w-full rounded shadow-2xl select-none pointer-events-none transition-transform duration-200 ease-out will-change-transform"
|
||||
style="transform: scale({isZoomed ? 3.8 : 1});"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="w-full max-w-4xl mx-auto z-40 bg-zinc-950/90 border border-zinc-900 px-4 py-3 rounded-xl backdrop-blur-md pointer-events-auto">
|
||||
|
||||
Reference in New Issue
Block a user