animation vinyle
This commit is contained in:
parent
4eadf7dc7e
commit
0e8efa0902
@ -12,21 +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;
|
|
||||||
let reverseAudioLoaded = false;
|
|
||||||
|
|
||||||
// 3. Variables pour vitesse
|
|
||||||
let lastPosition = null;
|
let lastPosition = null;
|
||||||
let lastTime = null;
|
let lastTime = null;
|
||||||
|
|
||||||
// 4. Connexion socket
|
// 3. Connexion Socket.io
|
||||||
const socket = io();
|
const socket = io();
|
||||||
|
|
||||||
// 5. Sauvegarder les sources
|
|
||||||
const originalSrc = audio.getAttribute('src');
|
|
||||||
const reverseSrc = audio.dataset.reverseSrc || null;
|
|
||||||
|
|
||||||
// 6. SOCKET – gestion de la position envoyée
|
|
||||||
socket.on('position', (position) => {
|
socket.on('position', (position) => {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|
||||||
@ -37,20 +28,15 @@ socket.on('position', (position) => {
|
|||||||
|
|
||||||
clearTimeout(idleTimeout);
|
clearTimeout(idleTimeout);
|
||||||
|
|
||||||
if (Math.abs(speed) < 15) {
|
if (Math.abs(speed) < 10) {
|
||||||
stopPlayback();
|
stopPlayback();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isReverse = speed < 0;
|
if (speed > 0) {
|
||||||
|
controlForwardPlayback(speed);
|
||||||
if (isReverse) {
|
|
||||||
simulateReverse(Math.abs(speed));
|
|
||||||
} else {
|
} else {
|
||||||
stopReverse();
|
controlRewind(Math.abs(speed));
|
||||||
let playbackSpeed = 1 + speed * 0.0003;
|
|
||||||
playbackSpeed = Math.max(0.5, Math.min(1.5, playbackSpeed));
|
|
||||||
controlPlayback(playbackSpeed);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +48,47 @@ socket.on('position', (position) => {
|
|||||||
}, 300);
|
}, 300);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 7. Fonctions
|
// 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 = speed * 0.01;
|
||||||
|
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
|
||||||
|
|
||||||
function togglePlay() {
|
function togglePlay() {
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
@ -94,74 +120,7 @@ function setProgress(e) {
|
|||||||
audio.currentTime = (clickX / width) * duration;
|
audio.currentTime = (clickX / width) * duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
function controlPlayback(speed) {
|
// 6. Événements manuels
|
||||||
stopReverse();
|
|
||||||
if (speed > 0) {
|
|
||||||
if (!isPlaying) {
|
|
||||||
audio.play();
|
|
||||||
vinyl.style.animationPlayState = 'running';
|
|
||||||
isPlaying = true;
|
|
||||||
}
|
|
||||||
audio.playbackRate = speed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function stopPlayback() {
|
|
||||||
audio.pause();
|
|
||||||
vinyl.style.animationPlayState = 'paused';
|
|
||||||
isPlaying = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simule la lecture en reverse via décrémentation du currentTime
|
|
||||||
function simulateReverse(speed) {
|
|
||||||
const reverseSpeed = Math.min(speed * 0.01, 2);
|
|
||||||
|
|
||||||
if (!reverseSrc) return;
|
|
||||||
|
|
||||||
if (!reverseInterval) {
|
|
||||||
reverseInterval = setInterval(() => {
|
|
||||||
if (audio.currentTime > 0.05) {
|
|
||||||
audio.currentTime -= reverseSpeed * 0.1;
|
|
||||||
vinyl.style.animationPlayState = 'running';
|
|
||||||
} else {
|
|
||||||
stopPlayback();
|
|
||||||
}
|
|
||||||
}, 100);
|
|
||||||
|
|
||||||
if (!reverseAudioLoaded) {
|
|
||||||
const currentTime = audio.currentTime;
|
|
||||||
audio.src = reverseSrc;
|
|
||||||
audio.load();
|
|
||||||
audio.addEventListener('loadedmetadata', () => {
|
|
||||||
const newTime = Math.min(currentTime, audio.duration - 0.1);
|
|
||||||
audio.currentTime = newTime;
|
|
||||||
}, { once: true });
|
|
||||||
reverseAudioLoaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
isPlaying = true;
|
|
||||||
audio.pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function stopReverse() {
|
|
||||||
if (reverseInterval) {
|
|
||||||
clearInterval(reverseInterval);
|
|
||||||
reverseInterval = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (reverseAudioLoaded) {
|
|
||||||
const currentTime = audio.currentTime;
|
|
||||||
audio.src = originalSrc;
|
|
||||||
audio.load();
|
|
||||||
audio.addEventListener('loadedmetadata', () => {
|
|
||||||
audio.currentTime = Math.min(currentTime, audio.duration - 0.1);
|
|
||||||
}, { once: true });
|
|
||||||
reverseAudioLoaded = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 8. Événements utilisateur
|
|
||||||
|
|
||||||
vinyl.addEventListener('click', togglePlay);
|
vinyl.addEventListener('click', togglePlay);
|
||||||
audio.addEventListener('timeupdate', updateProgress);
|
audio.addEventListener('timeupdate', updateProgress);
|
||||||
|
|||||||
@ -78,7 +78,8 @@ body {
|
|||||||
height: 600px;
|
height: 600px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: radial-gradient(circle at center, #444 0%, #111 60%, #000 100%);
|
background: radial-gradient(circle at center, #444 0%, #111 60%, #000 100%);
|
||||||
animation: spin 5s linear infinite paused;
|
animation: spin 4s linear infinite;
|
||||||
|
animation-play-state: paused;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -87,6 +88,11 @@ body {
|
|||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.vinyl.reverse {
|
||||||
|
animation: spin-reverse 4s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
.vinyl img {
|
.vinyl img {
|
||||||
width: 40%;
|
width: 40%;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@ -166,12 +172,13 @@ body {
|
|||||||
|
|
||||||
|
|
||||||
@keyframes spin {
|
@keyframes spin {
|
||||||
from {
|
from { transform: rotate(0deg); }
|
||||||
transform: rotate(0deg);
|
to { transform: rotate(360deg); }
|
||||||
}
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes spin-reverse {
|
||||||
|
from { transform: rotate(0deg); }
|
||||||
|
to { transform: rotate(-360deg); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user