From 914bd7cd6aa14e839332a98d91c30b19865b0cf2 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sun, 17 May 2026 15:25:52 +0300 Subject: Restructure repo: move Go server into player-server/ --- web/js/imageViewer.js | 193 -------------------------------------------------- 1 file changed, 193 deletions(-) delete mode 100644 web/js/imageViewer.js (limited to 'web/js/imageViewer.js') diff --git a/web/js/imageViewer.js b/web/js/imageViewer.js deleted file mode 100644 index 09e1563..0000000 --- a/web/js/imageViewer.js +++ /dev/null @@ -1,193 +0,0 @@ -let els = () => ({}); -let isImageMode = () => false; -let playNext = () => {}; - -let zoomScale = 1; -let panX = 0; -let panY = 0; -let isPanning = false; -let panStart = { x: 0, y: 0 }; -let slideshowTimer = null; -let slideshowPausedUntil = 0; -let cropMode = false; -let cropPositionX = 50; -let cropPositionY = 50; -const CROP_PRESETS = [ - { x: 50, y: 50, label: 'C' }, - { x: 50, y: 0, label: 'T' }, - { x: 50, y: 100, label: 'B' }, - { x: 0, y: 50, label: 'L' }, - { x: 100, y: 50, label: 'R' }, -]; -let cropPresetIndex = 0; - -export function initImageViewer(options = {}) { - els = typeof options.els === 'function' ? options.els : els; - isImageMode = typeof options.isImageMode === 'function' ? options.isImageMode : isImageMode; - playNext = typeof options.playNext === 'function' ? options.playNext : playNext; - - const e = els(); - e.btnZoomIn?.addEventListener('click', () => { zoomIn(); pauseSlideshow(); }); - e.btnZoomOut?.addEventListener('click', () => { zoomOut(); pauseSlideshow(); }); - e.btnSlideshow?.addEventListener('click', toggleSlideshow); - - e.image?.addEventListener('mousedown', (ev) => { - if (zoomScale > 1) { - isPanning = true; - panStart = { x: ev.clientX - panX, y: ev.clientY - panY }; - e.image.style.cursor = 'grabbing'; - ev.preventDefault(); - } - }); - e.image?.addEventListener('wheel', (ev) => { - ev.preventDefault(); - if (ev.deltaY < 0) zoomIn(); - else zoomOut(); - }, { passive: false }); - window.addEventListener('mousemove', (ev) => { - if (!isPanning) return; - panX = ev.clientX - panStart.x; - panY = ev.clientY - panStart.y; - applyImageTransform(); - }); - window.addEventListener('mouseup', () => { - if (isPanning) { - isPanning = false; - const image = els().image; - if (image) image.style.cursor = zoomScale > 1 ? 'grab' : 'zoom-in'; - } - }); -} - -function setImageZoom(s) { - zoomScale = Math.max(0.5, Math.min(s, 5)); - applyImageTransform(); -} - -function applyImageTransform() { - const e = els(); - if (!e.image) return; - e.image.style.transform = `translate(${panX}px, ${panY}px) scale(${zoomScale})`; - e.image.style.cursor = zoomScale > 1 ? 'grab' : 'zoom-in'; -} - -export function resetImageZoom() { - zoomScale = 1; - panX = 0; - panY = 0; - applyImageTransform(); -} - -export function zoomIn() { - setImageZoom(zoomScale * 1.25); -} - -export function zoomOut() { - setImageZoom(zoomScale / 1.25); -} - -export function resetZoom() { - resetImageZoom(); -} - -export function toggleSlideshow() { - if (slideshowTimer) stopSlideshow(); - else startSlideshow(); -} - -export function isSlideshowActive() { - return !!slideshowTimer; -} - -function startSlideshow() { - if (slideshowTimer) clearInterval(slideshowTimer); - slideshowTimer = setInterval(() => { - if (Date.now() < slideshowPausedUntil) return; - if (!isImageMode()) { stopSlideshow(); return; } - playNext(); - }, 5000); - const btn = els().btnSlideshow; - if (btn) btn.textContent = '⏸'; -} - -export function stopSlideshow() { - clearInterval(slideshowTimer); - slideshowTimer = null; - const btn = els().btnSlideshow; - if (btn) btn.textContent = '⏵'; -} - -export function pauseSlideshow() { - slideshowPausedUntil = Date.now() + 10000; -} - -export function toggleCrop() { - const e = els(); - if (!e.player) return; - if (!document.fullscreenElement) return; - cropMode = !cropMode; - e.player.classList.toggle('crop-mode', cropMode); - if (!cropMode) { - resetCropPosition(); - } else { - applyCropPosition(); - } -} - -function applyCropPosition() { - const e = els(); - if (!e.player) return; - e.player.style.setProperty('--crop-x', cropPositionX + '%'); - e.player.style.setProperty('--crop-y', cropPositionY + '%'); - updateCropIndicator(); -} - -function updateCropIndicator() { - const e = els(); - if (!e.cropIndicator) return; - if (!cropMode) { - e.cropIndicator.classList.add('hidden'); - return; - } - const snap = 5; - let label = ''; - if (Math.abs(cropPositionX - 50) <= snap && Math.abs(cropPositionY - 50) <= snap) label = 'C'; - else if (Math.abs(cropPositionX - 50) <= snap && cropPositionY <= snap) label = 'T'; - else if (Math.abs(cropPositionX - 50) <= snap && cropPositionY >= 95) label = 'B'; - else if (cropPositionX <= snap && Math.abs(cropPositionY - 50) <= snap) label = 'L'; - else if (cropPositionX >= 95 && Math.abs(cropPositionY - 50) <= snap) label = 'R'; - else label = Math.round(cropPositionX) + ',' + Math.round(cropPositionY); - e.cropIndicator.textContent = label; - e.cropIndicator.classList.remove('hidden'); -} - -export function resetCropPosition() { - cropPositionX = 50; - cropPositionY = 50; - cropPresetIndex = 0; - applyCropPosition(); -} - -export function clearCropMode() { - cropMode = false; - const e = els(); - e.player?.classList.remove('crop-mode'); - resetCropPosition(); -} - -export function shiftCropPosition(dx, dy) { - if (!cropMode) return false; - cropPositionX = Math.max(0, Math.min(100, cropPositionX + dx)); - cropPositionY = Math.max(0, Math.min(100, cropPositionY + dy)); - applyCropPosition(); - return true; -} - -export function cycleCropPosition() { - if (!cropMode) return; - cropPresetIndex = (cropPresetIndex + 1) % CROP_PRESETS.length; - const preset = CROP_PRESETS[cropPresetIndex]; - cropPositionX = preset.x; - cropPositionY = preset.y; - applyCropPosition(); -} -- cgit v1.2.3