bisbis
This commit is contained in:
parent
825acfe48b
commit
9cf7c74f9c
@ -1,4 +1,4 @@
|
|||||||
// 1. Sélection des éléments du DOM
|
// 1. Sélection des éléments DOM
|
||||||
const vinyl = document.getElementById('vinyl');
|
const vinyl = document.getElementById('vinyl');
|
||||||
const audio = document.getElementById('audio');
|
const audio = document.getElementById('audio');
|
||||||
const progress = document.getElementById('progress');
|
const progress = document.getElementById('progress');
|
||||||
@ -12,13 +12,12 @@ const loopBtn = document.getElementById('loop');
|
|||||||
let isPlaying = false;
|
let isPlaying = false;
|
||||||
let isLooping = false;
|
let isLooping = false;
|
||||||
let idleTimeout = null;
|
let idleTimeout = null;
|
||||||
let reverseInterval = null;
|
|
||||||
|
|
||||||
// 3. Variables pour calcul de vitesse
|
|
||||||
let lastPosition = null;
|
let lastPosition = null;
|
||||||
let lastTime = null;
|
let lastTime = null;
|
||||||
|
|
||||||
// 4. Connexion Socket.io
|
const rotationsPerTrack = 3; // Nombre de tours complets du vinyle sur toute la durée
|
||||||
|
|
||||||
|
// 3. Connexion Socket.io
|
||||||
const socket = io();
|
const socket = io();
|
||||||
|
|
||||||
socket.on('position', (position) => {
|
socket.on('position', (position) => {
|
||||||
@ -28,35 +27,46 @@ socket.on('position', (position) => {
|
|||||||
const deltaPos = position - lastPosition;
|
const deltaPos = position - lastPosition;
|
||||||
const deltaTime = (now - lastTime) / 1000;
|
const deltaTime = (now - lastTime) / 1000;
|
||||||
|
|
||||||
const speed = deltaPos / deltaTime;
|
const speed = deltaPos / deltaTime; // vitesse de rotation
|
||||||
console.log('instant speed:', speed);
|
|
||||||
|
|
||||||
clearTimeout(idleTimeout);
|
clearTimeout(idleTimeout);
|
||||||
|
|
||||||
|
// Si la vitesse est très faible, on considère que l'encodeur est à l'arrêt
|
||||||
if (Math.abs(speed) < 5) {
|
if (Math.abs(speed) < 5) {
|
||||||
stopPlayback();
|
stopPlayback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isReverse = speed < 0;
|
if (speed < 0) {
|
||||||
|
// Rotation inverse : on recule la timeline
|
||||||
if (isReverse) {
|
audio.pause();
|
||||||
simulateReverse(Math.abs(speed));
|
isPlaying = false;
|
||||||
|
// On recule la timeline proportionnellement à la vitesse inversée, avec un facteur de sensibilité
|
||||||
|
audio.currentTime = Math.max(0, audio.currentTime + speed * 0.03); // speed<0 donc avance négative ici
|
||||||
} else {
|
} else {
|
||||||
stopReverse();
|
// Rotation avant : on joue la piste et ajuste la vitesse
|
||||||
controlPlayback(speed);
|
if (!isPlaying) {
|
||||||
|
audio.play();
|
||||||
|
isPlaying = true;
|
||||||
|
}
|
||||||
|
// Accélération adoucie : vitesse lente plus étendue, max 1.5x
|
||||||
|
let playbackSpeed = 0.5 + speed / 400;
|
||||||
|
playbackSpeed = Math.min(Math.max(playbackSpeed, 0.5), 1.5);
|
||||||
|
audio.playbackRate = playbackSpeed;
|
||||||
|
// On fait avancer le son naturellement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastPosition = position;
|
lastPosition = position;
|
||||||
lastTime = now;
|
lastTime = now;
|
||||||
|
|
||||||
|
// Détecter l'inactivité (pas de mouvement > 300ms) : stoppe la lecture
|
||||||
idleTimeout = setTimeout(() => {
|
idleTimeout = setTimeout(() => {
|
||||||
stopPlayback();
|
stopPlayback();
|
||||||
}, 300);
|
}, 300);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 5. Fonctions
|
// 4. Fonctions
|
||||||
|
|
||||||
function togglePlay() {
|
function togglePlay() {
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
@ -70,9 +80,15 @@ function togglePlay() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateProgress() {
|
function updateProgress() {
|
||||||
const progressPercent = (audio.currentTime / audio.duration) * 100;
|
if (!isNaN(audio.duration)) {
|
||||||
progress.value = progressPercent;
|
const progressPercent = (audio.currentTime / audio.duration) * 100;
|
||||||
currentTimeEl.textContent = formatTime(audio.currentTime);
|
progress.value = progressPercent;
|
||||||
|
currentTimeEl.textContent = formatTime(audio.currentTime);
|
||||||
|
durationEl.textContent = formatTime(audio.duration);
|
||||||
|
|
||||||
|
// Mise à jour rotation vinyle synchronisée au temps courant
|
||||||
|
updateVinylRotation();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatTime(time) {
|
function formatTime(time) {
|
||||||
@ -88,67 +104,25 @@ function setProgress(e) {
|
|||||||
audio.currentTime = (clickX / width) * duration;
|
audio.currentTime = (clickX / width) * duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lecture en avant selon la vitesse
|
// Fonction pour stopper la lecture
|
||||||
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 / 400, 1);
|
|
||||||
const minRate = 0.3;
|
|
||||||
const maxRate = 1.5;
|
|
||||||
const playbackSpeed = minRate + (maxRate - minRate) * Math.pow(normalized, 1.2);
|
|
||||||
|
|
||||||
audio.playbackRate = playbackSpeed;
|
|
||||||
vinyl.style.animationDuration = `${1 / playbackSpeed * 2}s`;
|
|
||||||
vinyl.style.animationDirection = 'normal';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function stopPlayback() {
|
function stopPlayback() {
|
||||||
audio.pause();
|
audio.pause();
|
||||||
vinyl.style.animationPlayState = 'paused';
|
vinyl.style.animationPlayState = 'paused';
|
||||||
isPlaying = false;
|
isPlaying = false;
|
||||||
stopReverse();
|
audio.playbackRate = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
function simulateReverse(speed) {
|
// Fonction qui fait tourner le vinyle selon la timeline audio
|
||||||
const reverseSpeed = Math.min(speed * 0.03, 2); // secondes à reculer par tick
|
function updateVinylRotation() {
|
||||||
|
if (audio.duration && audio.currentTime >= 0) {
|
||||||
if (!reverseInterval) {
|
// Calcul de l'angle en degrés
|
||||||
reverseInterval = setInterval(() => {
|
// rotation proportionnelle au temps courant * nombre de rotations sur la piste
|
||||||
if (audio.currentTime > 0.05) {
|
const rotationDegrees = (audio.currentTime / audio.duration) * 360 * rotationsPerTrack;
|
||||||
audio.currentTime -= reverseSpeed * 0.1;
|
vinyl.style.transform = `rotate(${rotationDegrees}deg)`;
|
||||||
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
|
// 5. Événements
|
||||||
|
|
||||||
vinyl.addEventListener('click', togglePlay);
|
vinyl.addEventListener('click', togglePlay);
|
||||||
audio.addEventListener('timeupdate', updateProgress);
|
audio.addEventListener('timeupdate', updateProgress);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user