fix: crossfade now-playing background instead of hard flash
Two-layer opacity crossfade replaces the broken background-image transition. New image loads on the hidden layer, then both opacity values swap smoothly. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
e75d90e165
commit
97a4cc756d
3 files changed
+17
-5
No files matched your search
+2
-1
@@ -613,7 +613,8 @@
|
|||||||
|
|
||||||
<!-- NOW PLAYING OVERLAY -->
|
<!-- NOW PLAYING OVERLAY -->
|
||||||
<div class="np-overlay" id="np-overlay">
|
<div class="np-overlay" id="np-overlay">
|
||||||
<div class="np-bg" id="np-bg"></div>
|
<div class="np-bg" id="np-bg-a"></div>
|
||||||
|
<div class="np-bg" id="np-bg-b" style="opacity:0"></div>
|
||||||
<div class="np-inner">
|
<div class="np-inner">
|
||||||
<div class="np-topbar">
|
<div class="np-topbar">
|
||||||
<button class="np-close" onclick="closeNowPlaying()" title="Schließen">
|
<button class="np-close" onclick="closeNowPlaying()" title="Schließen">
|
||||||
|
|||||||
+13
-2
@@ -57,17 +57,28 @@ export function updatePlayerUI(s) {
|
|||||||
_syncNpDirect(s);
|
_syncNpDirect(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let _npBgCurr = 'a';
|
||||||
|
function _crossfadeNpBg(cv) {
|
||||||
|
const currEl = document.getElementById(`np-bg-${_npBgCurr}`);
|
||||||
|
const nextId = _npBgCurr === 'a' ? 'b' : 'a';
|
||||||
|
const nextEl = document.getElementById(`np-bg-${nextId}`);
|
||||||
|
if (!currEl || !nextEl) return;
|
||||||
|
nextEl.style.backgroundImage = cv ? `url('${cv}')` : 'none';
|
||||||
|
nextEl.style.opacity = '1';
|
||||||
|
currEl.style.opacity = '0';
|
||||||
|
_npBgCurr = nextId;
|
||||||
|
}
|
||||||
|
|
||||||
export function _syncNpDirect(s) {
|
export function _syncNpDirect(s) {
|
||||||
if(!S.npOpen || !s) return;
|
if(!S.npOpen || !s) return;
|
||||||
const cv = coverUrl(s.coverArt, 400);
|
const cv = coverUrl(s.coverArt, 400);
|
||||||
const cover = document.getElementById('np-cover');
|
const cover = document.getElementById('np-cover');
|
||||||
const bg = document.getElementById('np-bg');
|
|
||||||
if (cover) {
|
if (cover) {
|
||||||
const existingImg = cover.querySelector('img');
|
const existingImg = cover.querySelector('img');
|
||||||
if (cv && existingImg) existingImg.src = cv;
|
if (cv && existingImg) existingImg.src = cv;
|
||||||
else if (cover) cover.innerHTML = cv ? `<img src="${cv}" style="width:100%;height:100%;object-fit:cover">` : '<div class="no-art">♪</div>';
|
else if (cover) cover.innerHTML = cv ? `<img src="${cv}" style="width:100%;height:100%;object-fit:cover">` : '<div class="no-art">♪</div>';
|
||||||
}
|
}
|
||||||
if(bg) bg.style.backgroundImage = cv ? `url('${cv}')` : 'none';
|
_crossfadeNpBg(cv);
|
||||||
const t = document.getElementById('np-title'); if(t) t.textContent = s.title || '—';
|
const t = document.getElementById('np-title'); if(t) t.textContent = s.title || '—';
|
||||||
const an = document.getElementById('np-artist-name');
|
const an = document.getElementById('np-artist-name');
|
||||||
if(an) {
|
if(an) {
|
||||||
|
|||||||
+2
-2
@@ -508,13 +508,13 @@ nav{flex:1;overflow-y:auto;padding:4px 10px}
|
|||||||
}
|
}
|
||||||
.np-overlay.open{transform:translateY(0)}
|
.np-overlay.open{transform:translateY(0)}
|
||||||
|
|
||||||
/* Blurred album art as background */
|
/* Blurred album art as background — two layers for crossfade */
|
||||||
.np-bg{
|
.np-bg{
|
||||||
position:absolute;inset:-40px;
|
position:absolute;inset:-40px;
|
||||||
background-size:cover;background-position:center;
|
background-size:cover;background-position:center;
|
||||||
filter:blur(60px) brightness(.35) saturate(1.4);
|
filter:blur(60px) brightness(.35) saturate(1.4);
|
||||||
transform:scale(1.1);
|
transform:scale(1.1);
|
||||||
transition:background-image .6s ease;
|
transition:opacity .55s ease;
|
||||||
z-index:0;
|
z-index:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user