diff --git a/media_server/static/css/styles.css b/media_server/static/css/styles.css index b77dff8..ef64f0c 100644 --- a/media_server/static/css/styles.css +++ b/media_server/static/css/styles.css @@ -628,8 +628,8 @@ h1 { } @keyframes vinylSpin { - from { transform: rotate(0deg); } - to { transform: rotate(360deg); } + from { transform: rotate(var(--vinyl-offset, 0deg)); } + to { transform: rotate(calc(var(--vinyl-offset, 0deg) + 360deg)); } } .track-info { diff --git a/media_server/static/js/app.js b/media_server/static/js/app.js index 4b238ce..23ca24e 100644 --- a/media_server/static/js/app.js +++ b/media_server/static/js/app.js @@ -256,6 +256,35 @@ let vinylMode = localStorage.getItem('vinylMode') === 'true'; let currentPlayState = 'idle'; + function getVinylAngle() { + const art = document.getElementById('album-art'); + if (!art) return 0; + const st = getComputedStyle(art); + const tr = st.transform; + if (!tr || tr === 'none') return 0; + const m = tr.match(/matrix\((.+)\)/); + if (!m) return 0; + const vals = m[1].split(',').map(Number); + const angle = Math.round(Math.atan2(vals[1], vals[0]) * (180 / Math.PI)); + return ((angle % 360) + 360) % 360; + } + + function saveVinylAngle() { + if (!vinylMode) return; + localStorage.setItem('vinylAngle', getVinylAngle()); + } + + function restoreVinylAngle() { + const saved = localStorage.getItem('vinylAngle'); + if (saved) { + const art = document.getElementById('album-art'); + if (art) art.style.setProperty('--vinyl-offset', `${saved}deg`); + } + } + + setInterval(saveVinylAngle, 2000); + window.addEventListener('beforeunload', saveVinylAngle); + function toggleVinylMode() { vinylMode = !vinylMode; localStorage.setItem('vinylMode', vinylMode); @@ -269,8 +298,10 @@ if (vinylMode) { container.classList.add('vinyl'); if (btn) btn.classList.add('active'); + restoreVinylAngle(); updateVinylSpin(); } else { + saveVinylAngle(); container.classList.remove('vinyl', 'spinning', 'paused'); if (btn) btn.classList.remove('active'); }