diff --git a/node-server/assets/script.js b/node-server/assets/script.js index 071dd8c..8238a91 100644 --- a/node-server/assets/script.js +++ b/node-server/assets/script.js @@ -12,10 +12,13 @@ const loopBtn = document.getElementById('loop'); let isPlaying = false; let isLooping = false; let idleTimeout = null; +let reverseInterval = null; + +// 3. Variables pour calcul de vitesse let lastPosition = null; let lastTime = null; -// 3. Connexion Socket.io +// 4. Connexion Socket.io const socket = io(); socket.on('position', (position) => { @@ -24,19 +27,24 @@ socket.on('position', (position) => { if (lastPosition !== null && lastTime !== null) { const deltaPos = position - lastPosition; const deltaTime = (now - lastTime) / 1000; + const speed = deltaPos / deltaTime; + console.log('instant speed:', speed); clearTimeout(idleTimeout); - if (Math.abs(speed) < 10) { + if (Math.abs(speed) < 5) { stopPlayback(); return; } - if (speed > 0) { - controlForwardPlayback(speed); + const isReverse = speed < 0; + + if (isReverse) { + simulateReverse(Math.abs(speed)); } else { - controlRewind(Math.abs(speed)); + stopReverse(); + controlPlayback(speed); } } @@ -48,47 +56,7 @@ socket.on('position', (position) => { }, 300); }); -// 4. Fonctions principales - -function controlForwardPlayback(speed) { - const rate = 1 + speed * 0.0003; - const playbackSpeed = Math.min(2, Math.max(0.5, rate)); - - vinyl.classList.remove('reverse'); - vinyl.style.animationPlayState = 'running'; - - if (!isPlaying) { - audio.play(); - isPlaying = true; - } - - audio.playbackRate = playbackSpeed; -} - -function controlRewind(speed) { - if (isPlaying) { - audio.pause(); - isPlaying = false; - } - - const rewindAmount = Math.min(speed * 0.01, 1); - audio.currentTime = Math.max(0, audio.currentTime - rewindAmount); - - vinyl.classList.add('reverse'); - vinyl.style.animationPlayState = 'running'; -} - -function stopPlayback() { - if (isPlaying) { - audio.pause(); - isPlaying = false; - } - - vinyl.classList.remove('reverse'); - vinyl.style.animationPlayState = 'paused'; -} - -// 5. Fonctions interface +// 5. Fonctions function togglePlay() { if (isPlaying) { @@ -120,7 +88,67 @@ function setProgress(e) { audio.currentTime = (clickX / width) * duration; } -// 6. Événements manuels +// Lecture en avant selon la vitesse +function controlPlayback(speed) { + stopReverse(); + + if (speed > 0) { + if (!isPlaying) { + audio.play(); + vinyl.style.animationPlayState = 'running'; + isPlaying = true; + } + + // Vitesse normalisée + const normalized = Math.min(speed / 100, 1); + const minRate = 0.3; + const maxRate = 1.5; + const playbackSpeed = minRate + (maxRate - minRate) * normalized; + + audio.playbackRate = playbackSpeed; + vinyl.style.animationDuration = `${1 / playbackSpeed * 2}s`; + vinyl.style.animationDirection = 'normal'; + } +} + +function stopPlayback() { + audio.pause(); + vinyl.style.animationPlayState = 'paused'; + isPlaying = false; + stopReverse(); +} + +function simulateReverse(speed) { + const reverseSpeed = Math.min(speed * 0.01, 2); // secondes à reculer par tick + + if (!reverseInterval) { + reverseInterval = setInterval(() => { + if (audio.currentTime > 0.05) { + audio.currentTime -= reverseSpeed * 0.1; + vinyl.style.animationPlayState = 'running'; + vinyl.style.animationDirection = 'reverse'; + } else { + stopPlayback(); + } + }, 100); + + if (!isPlaying) { + isPlaying = true; + } + } + + audio.pause(); // son désactivé pour reverse simulé +} + +function stopReverse() { + if (reverseInterval) { + clearInterval(reverseInterval); + reverseInterval = null; + vinyl.style.animationDirection = 'normal'; + } +} + +// 6. Événements vinyl.addEventListener('click', togglePlay); audio.addEventListener('timeupdate', updateProgress);