Skip to content

Commit dc7dac1

Browse files
committed
refactor: improve Now Playing tab background visuals by optimizing blurred image generation, consolidating desktop effects, and refining orb animations.
1 parent 7da27d8 commit dc7dac1

1 file changed

Lines changed: 59 additions & 60 deletions

File tree

client/src/Pages/Music/BottomPlayer/NowPlayingTab.jsx

Lines changed: 59 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,9 @@ const useBlurredBg = (imageSrc) => {
8080
canvas.width = 64
8181
canvas.height = 64
8282
const ctx = canvas.getContext("2d")
83-
ctx.filter = "blur(4px) saturate(1.3) brightness(0.65)"
84-
ctx.drawImage(img, -4, -4, 72, 72)
85-
const dataUrl = canvas.toDataURL("image/jpeg", 0.7)
83+
ctx.filter = "blur(6px) saturate(1.4) brightness(0.6)"
84+
ctx.drawImage(img, -6, -6, 76, 76)
85+
const dataUrl = canvas.toDataURL("image/jpeg", 0.6)
8686
setBgUrls((prev) => ({ current: dataUrl, previous: prev.current, transitioning: true }))
8787
if (timeoutRef.current) clearTimeout(timeoutRef.current)
8888
timeoutRef.current = setTimeout(() => {
@@ -178,7 +178,7 @@ const NowPlayingTab = memo(({ currentSong }) => {
178178
const songImage = useMemo(() => currentSong?.image?.[2]?.link, [currentSong])
179179
const colors = useImageColors(songImage)
180180
const images = useCrossfadeImage(songImage)
181-
const mobileBg = useBlurredBg(songImage)
181+
const blurredBg = useBlurredBg(songImage)
182182
const nextSong = useNextSong(currentSong)
183183
const hasAnimated = useRef(false)
184184
const [showEntrance, setShowEntrance] = useState(false)
@@ -214,67 +214,66 @@ const NowPlayingTab = memo(({ currentSong }) => {
214214
const imgShadowDesktop = `0 30px 80px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.05), 0 0 80px -20px rgba(${c1[0]},${c1[1]},${c1[2]},0.25)`
215215
const imgShadowMobile = `0 24px 60px rgba(0,0,0,0.4), 0 0 0 1px rgba(255,255,255,0.05), 0 0 60px -15px rgba(${c1[0]},${c1[1]},${c1[2]},0.25)`
216216

217-
const orbColor = (c, a) => ({
218-
background: `rgba(${c[0]},${c[1]},${c[2]},${a})`,
219-
transition: "background 2s ease-out",
220-
})
217+
const orbStyle = useMemo(() => ({
218+
o1: { background: `rgba(${c1[0]},${c1[1]},${c1[2]},0.18)`, transition: "background 2s ease-out" },
219+
o2: { background: `rgba(${c2[0]},${c2[1]},${c2[2]},0.14)`, transition: "background 2s ease-out" },
220+
}), [c1, c2])
221+
222+
const overlayStyle = useMemo(() => ({
223+
background: [
224+
"radial-gradient(ellipse 70% 50% at 25% 20%, rgba(255,255,255,0.08) 0%, transparent 50%)",
225+
"radial-gradient(ellipse 50% 35% at 75% 75%, rgba(255,255,255,0.04) 0%, transparent 40%)",
226+
"radial-gradient(ellipse 120% 80% at 50% 40%, rgba(255,255,255,0.03) 0%, transparent 50%)",
227+
"radial-gradient(ellipse at 50% 45%, transparent 30%, rgba(5,5,8,0.3) 60%, rgba(5,5,8,0.85) 100%)",
228+
].join(", "),
229+
}), [])
230+
231+
const mobileVignette = useMemo(() => ({
232+
background: "radial-gradient(ellipse at 50% 45%, transparent 30%, rgba(5,5,8,0.3) 60%, rgba(5,5,8,0.85) 100%)",
233+
}), [])
221234

222235
return (
223236
<div className="w-full h-full relative overflow-hidden bg-[#050508]">
224237

225-
{/* === MOBILE BG: Pre-blurred canvas, no CSS filter === */}
226-
{mobileBg.previous && (
238+
{/* === MOBILE BG: Pre-blurred canvas, zero CSS filter cost === */}
239+
{blurredBg.previous && (
227240
<div
228241
className="lg:hidden absolute inset-0 bg-cover bg-center np-bg-fade-out"
229-
style={{ backgroundImage: `url(${mobileBg.previous})` }}
242+
style={{ backgroundImage: `url(${blurredBg.previous})` }}
230243
/>
231244
)}
232-
{mobileBg.current && (
245+
{blurredBg.current && (
233246
<div
234-
className={`lg:hidden absolute inset-0 bg-cover bg-center ${mobileBg.transitioning ? "np-bg-fade-in" : ""}`}
235-
style={{ backgroundImage: `url(${mobileBg.current})` }}
247+
className={`lg:hidden absolute inset-0 bg-cover bg-center ${blurredBg.transitioning ? "np-bg-fade-in" : ""}`}
248+
style={{ backgroundImage: `url(${blurredBg.current})` }}
236249
/>
237250
)}
238251

239-
{/* === DESKTOP BG: Full liquid glass with CSS blur === */}
252+
{/* === DESKTOP BG: CSS blur for high quality === */}
240253
{images.previous && (
241254
<div
242255
className="hidden lg:block absolute inset-0 bg-cover bg-center np-bg-fade-out"
243-
style={{ backgroundImage: `url(${images.previous})`, filter: "blur(160px) saturate(1.4) brightness(0.65)", transform: "scale(2)" }}
256+
style={{ backgroundImage: `url(${images.previous})`, filter: "blur(160px) saturate(1.4) brightness(0.65)", transform: "scale(2) translateZ(0)", willChange: "transform" }}
244257
/>
245258
)}
246259
<div
247260
className={`hidden lg:block absolute inset-0 bg-cover bg-center ${images.transitioning ? "np-bg-fade-in" : ""}`}
248-
style={{ backgroundImage: `url(${images.current})`, filter: "blur(160px) saturate(1.4) brightness(0.65)", transform: "scale(2)", transition: "background-image 0.6s ease" }}
261+
style={{ backgroundImage: `url(${images.current})`, filter: "blur(160px) saturate(1.4) brightness(0.65)", transform: "scale(2) translateZ(0)", willChange: "transform" }}
249262
/>
250263

251-
{/* Desktop-only: glass noise */}
264+
{/* Desktop: glass effects */}
252265
<div className="hidden lg:block absolute inset-0 np-glass-noise" />
253-
254-
{/* Desktop-only: specular highlights */}
255-
<div className="hidden lg:block absolute inset-0" style={{
256-
background: "radial-gradient(ellipse 70% 50% at 25% 20%, rgba(255,255,255,0.08) 0%, transparent 50%)"
257-
}} />
258-
<div className="hidden lg:block absolute inset-0" style={{
259-
background: "radial-gradient(ellipse 50% 35% at 75% 75%, rgba(255,255,255,0.04) 0%, transparent 40%)"
260-
}} />
261-
262-
{/* Desktop-only: animated liquid shimmer */}
263266
<div className="hidden lg:block absolute inset-0 np-orb-layer">
264-
<div className="np-orb np-o1" style={orbColor(c1, 0.18)} />
265-
<div className="np-orb np-o2" style={orbColor(c2, 0.14)} />
267+
<div className="np-orb np-o1" style={orbStyle.o1} />
268+
<div className="np-orb np-o2" style={orbStyle.o2} />
266269
<div className="np-shimmer" />
267270
</div>
268271

269-
{/* Desktop-only: luminous depth */}
270-
<div className="hidden lg:block absolute inset-0" style={{
271-
background: "radial-gradient(ellipse 120% 80% at 50% 40%, rgba(255,255,255,0.03) 0%, transparent 50%)"
272-
}} />
272+
{/* Desktop: specular + luminous + vignette merged into one div */}
273+
<div className="hidden lg:block absolute inset-0" style={overlayStyle} />
273274

274-
{/* Shared: vignette (single gradient, very light on GPU) */}
275-
<div className="absolute inset-0" style={{
276-
background: "radial-gradient(ellipse at 50% 45%, transparent 30%, rgba(5,5,8,0.3) 60%, rgba(5,5,8,0.85) 100%)"
277-
}} />
275+
{/* Mobile: vignette only */}
276+
<div className="lg:hidden absolute inset-0" style={mobileVignette} />
278277

279278
{/* Desktop layout */}
280279
<div className="hidden lg:flex relative z-10 h-full w-full max-w-[1100px] mx-auto items-center gap-14 xl:gap-20 px-10 xl:px-16">
@@ -393,53 +392,53 @@ const NowPlayingTab = memo(({ currentSong }) => {
393392
mix-blend-mode: overlay;
394393
}
395394
.np-orb-layer {
396-
filter: blur(100px);
397-
transform: scale(1.4);
395+
filter: blur(80px);
396+
transform: scale(1.3);
398397
mix-blend-mode: soft-light;
399-
opacity: 0.7;
398+
opacity: 0.6;
400399
}
401400
.np-orb {
402401
position: absolute;
403402
border-radius: 50%;
404403
}
405404
.np-o1 {
406-
width: 55%;
407-
height: 60%;
408-
top: -10%;
409-
left: -10%;
405+
width: 50%;
406+
height: 55%;
407+
top: -8%;
408+
left: -8%;
410409
animation: npo1 26s ease-in-out infinite;
411410
}
412411
.np-o2 {
413-
width: 50%;
414-
height: 50%;
415-
bottom: -10%;
416-
right: -10%;
412+
width: 45%;
413+
height: 45%;
414+
bottom: -8%;
415+
right: -8%;
417416
animation: npo2 32s ease-in-out infinite;
418417
}
419418
.np-shimmer {
420419
position: absolute;
421-
width: 40%;
422-
height: 30%;
420+
width: 35%;
421+
height: 25%;
423422
top: 15%;
424423
left: 20%;
425424
border-radius: 50%;
426-
background: radial-gradient(ellipse, rgba(255,255,255,0.06) 0%, transparent 70%);
427-
animation: npShimmer 18s ease-in-out infinite;
425+
background: radial-gradient(ellipse, rgba(255,255,255,0.05) 0%, transparent 70%);
426+
animation: npShimmer 20s ease-in-out infinite;
428427
}
429428
@keyframes npo1 {
430429
0%, 100% { transform: translate(0, 0) scale(1); border-radius: 50%; }
431-
33% { transform: translate(10%, 15%) scale(1.05); border-radius: 44% 56% 52% 48%; }
432-
66% { transform: translate(5%, 8%) scale(0.97); border-radius: 48% 52% 46% 54%; }
430+
33% { transform: translate(8%, 12%) scale(1.04); border-radius: 44% 56% 52% 48%; }
431+
66% { transform: translate(4%, 6%) scale(0.97); border-radius: 48% 52% 46% 54%; }
433432
}
434433
@keyframes npo2 {
435434
0%, 100% { transform: translate(0, 0) scale(1); border-radius: 50%; }
436-
33% { transform: translate(-8%, -12%) scale(1.04); border-radius: 54% 46% 48% 52%; }
437-
66% { transform: translate(-14%, -5%) scale(0.96); border-radius: 47% 53% 52% 48%; }
435+
33% { transform: translate(-6%, -10%) scale(1.03); border-radius: 54% 46% 48% 52%; }
436+
66% { transform: translate(-12%, -4%) scale(0.97); border-radius: 47% 53% 52% 48%; }
438437
}
439438
@keyframes npShimmer {
440-
0%, 100% { transform: translate(0, 0); opacity: 0.6; }
441-
33% { transform: translate(30%, 10%); opacity: 1; }
442-
66% { transform: translate(-10%, 20%); opacity: 0.4; }
439+
0%, 100% { transform: translate(0, 0); opacity: 0.5; }
440+
33% { transform: translate(25%, 8%); opacity: 0.8; }
441+
66% { transform: translate(-8%, 15%); opacity: 0.3; }
443442
}
444443
.np-bg-fade-in {
445444
animation: npBgIn 0.8s ease-out both;

0 commit comments

Comments
 (0)