From b83f895fd13fdfa5bf808e54417de92acdbcd36a Mon Sep 17 00:00:00 2001 From: kicer Date: Tue, 28 Jul 2026 20:14:40 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BE=E7=89=87=E7=BC=A9?= =?UTF-8?q?=E6=94=BE=E6=8B=96=E6=8B=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server/public/js/chat.js | 83 ++++++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 20 deletions(-) diff --git a/server/public/js/chat.js b/server/public/js/chat.js index 5ad4c34..faff508 100644 --- a/server/public/js/chat.js +++ b/server/public/js/chat.js @@ -104,30 +104,19 @@ function onImageClick(e) { e.stopPropagation(); const overlay = document.createElement('div'); overlay.className = 'fullscreen-overlay'; - overlay.innerHTML = ''; - overlay.addEventListener('click', () => overlay.remove()); + overlay.innerHTML = ''; + overlay.addEventListener('click', function(ev) { if (ev.target === overlay) overlay.remove(); }); document.body.appendChild(overlay); + initPinchZoom(overlay.querySelector('img')); } function onImgThumbDblClick(img) { const overlay = document.createElement('div'); overlay.className = 'fullscreen-overlay'; - overlay.innerHTML = ''; - overlay.addEventListener('click', () => overlay.remove()); + overlay.innerHTML = ''; + overlay.addEventListener('click', function(ev) { if (ev.target === overlay) overlay.remove(); }); document.body.appendChild(overlay); - var fsImg = overlay.querySelector('#fs-img'); - var pressTimer; - fsImg.addEventListener('touchstart', function() { - pressTimer = setTimeout(function() { - var a = document.createElement('a'); - a.href = fsImg.src; - a.download = fsImg.src.split('/').pop().split('?')[0] || 'image.jpg'; - a.click(); - clearTimeout(pressTimer); - }, 800); - }); - fsImg.addEventListener('touchend', function() { clearTimeout(pressTimer); }); - fsImg.addEventListener('touchmove', function() { clearTimeout(pressTimer); }); + initPinchZoom(overlay.querySelector('img')); } function onBubbleClick(e) { @@ -176,7 +165,61 @@ function insertTempBubble() { function clearTempBubble() { if (Store.tempBubbleTimer) { clearTimeout(Store.tempBubbleTimer); Store.tempBubbleTimer = null; } if (Store.pollTimer) { clearInterval(Store.pollTimer); Store.pollTimer = null; } - Store.messageCache = Store.messageCache.filter(m => !m.isTemp); - const tempEls = messagesContainer.querySelectorAll('[data-msg-id^="temp_"]'); - tempEls.forEach(el => el.remove()); + Store.messageCache = Store.messageCache.filter(function(m) { return !m.isTemp; }); + var tempEls = messagesContainer.querySelectorAll('[data-msg-id^="temp_"]'); + tempEls.forEach(function(el) { el.remove(); }); +} + +// 双指缩放 + 拖拽 +function initPinchZoom(img) { + var scale = 1, startDist = 0, startScale = 1; + var translateX = 0, translateY = 0; + var startX = 0, startY = 0, startTX = 0, startTY = 0; + var dragging = false; + + function update() { + img.style.transform = 'translate(' + translateX + 'px,' + translateY + 'px) scale(' + scale + ')'; + } + + img.addEventListener('touchstart', function(e) { + if (e.touches.length === 2) { + dragging = false; + startDist = Math.hypot(e.touches[0].clientX - e.touches[1].clientX, e.touches[0].clientY - e.touches[1].clientY); + startScale = scale; + startTX = translateX; + startTY = translateY; + var cx = (e.touches[0].clientX + e.touches[1].clientX) / 2; + var cy = (e.touches[0].clientY + e.touches[1].clientY) / 2; + startX = cx; startY = cy; + } else if (e.touches.length === 1 && scale > 1) { + dragging = true; + startX = e.touches[0].clientX; + startY = e.touches[0].clientY; + startTX = translateX; + startTY = translateY; + } + }); + + img.addEventListener('touchmove', function(e) { + if (e.touches.length === 2) { + e.preventDefault(); + var dist = Math.hypot(e.touches[0].clientX - e.touches[1].clientX, e.touches[0].clientY - e.touches[1].clientY); + scale = Math.max(0.5, Math.min(5, startScale * (dist / startDist))); + var cx = (e.touches[0].clientX + e.touches[1].clientX) / 2; + var cy = (e.touches[0].clientY + e.touches[1].clientY) / 2; + translateX = startTX + (cx - startX); + translateY = startTY + (cy - startY); + update(); + } else if (e.touches.length === 1 && dragging) { + translateX = startTX + (e.touches[0].clientX - startX); + translateY = startTY + (e.touches[0].clientY - startY); + update(); + } + }, { passive: false }); + + img.addEventListener('touchend', function() { + dragging = false; + if (scale < 0.6) { scale = 0.5; translateX = 0; translateY = 0; update(); } + if (scale <= 1) { translateX = 0; translateY = 0; update(); } + }); }