From 532a887119bedf15f53c6a7ec6d577b7b046e383 Mon Sep 17 00:00:00 2001 From: Tobias Leuschner Date: Sun, 22 Feb 2026 11:05:23 +0100 Subject: [PATCH] =?UTF-8?q?F=C3=BCge=20Unterst=C3=BCtzung=20f=C3=BCr=20Aus?= =?UTF-8?q?wahlepochen=20hinzu,=20um=20die=20Auswahl=20bei=20=C3=84nderung?= =?UTF-8?q?en=20zu=20verwalten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/app.js | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/js/app.js b/js/app.js index a449152..2520017 100644 --- a/js/app.js +++ b/js/app.js @@ -4,6 +4,7 @@ document.addEventListener('DOMContentLoaded', function(){ let selecting = false; let selectionDone = false; let selectionTimer = null; + let selectionEpoch = 0; function createFinger(t){ const id = (t.identifier !== undefined && t.identifier !== null) ? String(t.identifier) : ('m'+Date.now()); @@ -57,15 +58,16 @@ document.addEventListener('DOMContentLoaded', function(){ function startSelectionIfNeeded(){ if(selecting || selectionDone) return; - if(touches.size < 1) return; // require at least 1 finger + if(touches.size < 1) return; selecting = true; + const epoch = selectionEpoch; const {items} = computeOrderedItems(); const els = items.map(i=>i.el); const n = els.length; - // If only one finger, immediately mark it as winner (short visual) if(n === 1){ + if(epoch !== selectionEpoch) return; const el = els[0]; el.classList.add('winner','pulse'); selecting = false; @@ -73,7 +75,7 @@ document.addEventListener('DOMContentLoaded', function(){ return; } - const rotations = Math.floor(Math.random()*3)+3; // 3-5 rotations + const rotations = Math.floor(Math.random()*3)+3; const winnerIndex = Math.floor(Math.random()*n); const totalSteps = rotations * n + winnerIndex; @@ -81,10 +83,11 @@ document.addEventListener('DOMContentLoaded', function(){ let current = 0; for(let step=0; step<=totalSteps; step++){ const t = step/totalSteps; - const delay = 40 + Math.pow(t,2)*520; // ease-out timing + const delay = 40 + Math.pow(t,2)*520; cumulative += delay; const idx = current % n; setTimeout(()=>{ + if(epoch !== selectionEpoch) return; els.forEach((el,i)=>{ if(i===idx) el.classList.add('highlight'); else el.classList.remove('highlight'); }); @@ -93,6 +96,7 @@ document.addEventListener('DOMContentLoaded', function(){ } setTimeout(()=>{ + if(epoch !== selectionEpoch) return; els.forEach((el,i)=>{ if(i===winnerIndex){ el.classList.remove('highlight'); el.classList.add('winner','pulse'); } else { el.classList.remove('highlight'); el.classList.add('lost'); } @@ -103,6 +107,7 @@ document.addEventListener('DOMContentLoaded', function(){ } function cancelSelection(){ + selectionEpoch++; clearTimeout(selectionTimer); selectionTimer = null; selecting = false; @@ -113,6 +118,7 @@ document.addEventListener('DOMContentLoaded', function(){ function resetWhenAllUp(){ if(touches.size===0){ setTimeout(()=>{ + if(touches.size > 0) return; selecting=false; selectionDone=false; const nodes = Array.from(stage.querySelectorAll('.finger')); nodes.forEach(node=>node.remove()); @@ -126,10 +132,8 @@ document.addEventListener('DOMContentLoaded', function(){ e.preventDefault(); const changed = Array.from(e.changedTouches || []); changed.forEach(t=>createFinger(t)); - if(!selectionDone){ - clearTimeout(selectionTimer); - selectionTimer = setTimeout(startSelectionIfNeeded, 700); - } + cancelSelection(); + selectionTimer = setTimeout(startSelectionIfNeeded, 700); }, {passive:false}); stage.addEventListener('touchmove', function(e){ e.preventDefault(); @@ -147,8 +151,13 @@ document.addEventListener('DOMContentLoaded', function(){ e.preventDefault(); const changed = Array.from(e.changedTouches || []); changed.forEach(t=>removeFingerById(t.identifier)); - if(!selectionDone) cancelSelection(); - if(touches.size===0) resetWhenAllUp(); + cancelSelection(); + if(touches.size > 0){ + selectionTimer = setTimeout(startSelectionIfNeeded, 700); + } + // touches.size===0: cancelSelection hat State bereits bereinigt, + // DOM-Elemente durch removeFingerById entfernt. + // iOS feuert neue touchstart-Events für noch liegende Finger selbst. }, {passive:false}); // Support mouse for desktop testing