From fc093da36b2bf3a0f33567ae44777ef0c84158f8 Mon Sep 17 00:00:00 2001 From: bernd Date: Tue, 29 Sep 2026 09:41:45 +0200 Subject: [PATCH] =?UTF-8?q?touch=20bedienung=20hinzugef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- editor.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/editor.py b/editor.py index d7dd325..3751f89 100644 --- a/editor.py +++ b/editor.py @@ -466,6 +466,55 @@ wave.addEventListener('wheel', e => { const factor = e.deltaY < 0 ? ZOOM_FACTOR : 1/ZOOM_FACTOR; setZoom(zoom*factor, e.clientX); }, {passive:false}); + +// Touchscreen: two-finger pinch zoom. The midpoint between the fingers +// is used as the zoom focus, just like the mouse position for the wheel. +const touchPointers = new Map(); +let pinchDistance = null; +let pinchZoom = null; + +function touchDistance(a, b) { + return Math.hypot(a.clientX-b.clientX, a.clientY-b.clientY); +} +function touchMidpoint(a, b) { + return (a.clientX+b.clientX)/2; +} +function startPinch() { + const points = [...touchPointers.values()]; + if (points.length !== 2) return; + pinchDistance = touchDistance(points[0], points[1]); + pinchZoom = zoom; +} +wave.addEventListener('pointerdown', e => { + if (e.pointerType !== 'touch') return; + touchPointers.set(e.pointerId, e); + if (touchPointers.size === 2) { + pinchZoom = zoom; + startPinch(); + } +}, {passive:false}); +wave.addEventListener('pointermove', e => { + if (e.pointerType !== 'touch' || !touchPointers.has(e.pointerId)) return; + touchPointers.set(e.pointerId, e); + if (touchPointers.size !== 2 || !pinchDistance || pinchZoom === null) return; + const points = [...touchPointers.values()]; + const distance = touchDistance(points[0], points[1]); + if (distance <= 0) return; + const midpointX = touchMidpoint(points[0], points[1]); + setZoom(pinchZoom * (distance/pinchDistance), midpointX); + e.preventDefault(); +}, {passive:false}); +function endTouchPointer(e) { + if (e.pointerType !== 'touch') return; + touchPointers.delete(e.pointerId); + if (touchPointers.size < 2) { + pinchDistance = null; + pinchZoom = null; + } +} +wave.addEventListener('pointerup', endTouchPointer); +wave.addEventListener('pointercancel', endTouchPointer); + function beginDrag(which, e) { e.preventDefault(); dragging = which; @@ -483,6 +532,7 @@ document.addEventListener('pointermove', e => { document.addEventListener('pointerup', () => { dragging=null; document.body.style.cursor=''; }); wave.addEventListener('pointerdown', e => { if (e.target === startHandle || e.target === endHandle) return; + if (e.pointerType === 'touch' && touchPointers.size >= 2) return; const t=xToTime(e.clientX); audio.currentTime = Math.max(0, Math.min(duration,t)); });