Background Cover Scale

This commit is contained in:
2025-09-09 20:09:24 +10:00
parent 9c9b47c930
commit 2ea44bd3cc
2 changed files with 73 additions and 24 deletions
@@ -16,6 +16,7 @@ export const settings = await ReactiveStore.getPluginStorage("RadiantLyrics", {
backgroundBrightness: 40, backgroundBrightness: 40,
spinSpeed: 45, spinSpeed: 45,
settingsAffectNowPlaying: true, settingsAffectNowPlaying: true,
backgroundScale: 15,
}); });
export const Settings = () => { export const Settings = () => {
@@ -53,6 +54,9 @@ export const Settings = () => {
const [trackTitleGlow, setTrackTitleGlow] = React.useState( const [trackTitleGlow, setTrackTitleGlow] = React.useState(
settings.trackTitleGlow, settings.trackTitleGlow,
); );
const [backgroundScale, setBackgroundScale] = React.useState(
settings.backgroundScale,
);
// Derive props and override onChange to accept a broader first param type // Derive props and override onChange to accept a broader first param type
type BaseSwitchProps = React.ComponentProps<typeof LunaSwitchSetting>; type BaseSwitchProps = React.ComponentProps<typeof LunaSwitchSetting>;
@@ -165,6 +169,27 @@ export const Settings = () => {
} }
}} }}
/> />
<LunaNumberSetting
title="Background Cover Scale"
desc="Integer scale 130 (10=100%, 20=200%, 30=300%)"
min={1}
max={30}
value={backgroundScale}
onNumber={(value: number) => {
const next = Math.max(1, Math.min(30, Math.round(value)));
setBackgroundScale((settings.backgroundScale = next));
// Immediate visual update without throttle
if ((window as any).updateRadiantLyricsGlobalBackground) {
(window as any).updateRadiantLyricsGlobalBackground();
}
if (
settings.settingsAffectNowPlaying &&
(window as any).updateRadiantLyricsNowPlayingBackground
) {
(window as any).updateRadiantLyricsNowPlayingBackground();
}
}}
/>
<LunaNumberSetting <LunaNumberSetting
title="Text Glow" title="Text Glow"
desc="Adjust the glow size of lyrics (0-100, default: 20)" desc="Adjust the glow size of lyrics (0-100, default: 20)"
+47 -23
View File
@@ -2,6 +2,11 @@
import { LunaUnload, Tracer, ftch } from "@luna/core"; import { LunaUnload, Tracer, ftch } from "@luna/core";
import { StyleTag, PlayState, observePromise, observe } from "@luna/lib"; import { StyleTag, PlayState, observePromise, observe } from "@luna/lib";
import { settings, Settings } from "./Settings"; import { settings, Settings } from "./Settings";
// Interpret integer backgroundScale (130) strictly as 0.13.0 multiplier
const getScaledMultiplier = (): number => {
const value = Math.round(settings.backgroundScale);
return Math.max(0.1, Math.min(3, value / 10));
};
// Import CSS files directly using Luna's file:// syntax - Took me a while to figure out <3 // Import CSS files directly using Luna's file:// syntax - Took me a while to figure out <3
import baseStyles from "file://styles.css?minify"; import baseStyles from "file://styles.css?minify";
@@ -377,7 +382,9 @@ function updateCoverArtBackground(method: number = 0): void {
.querySelectorAll( .querySelectorAll(
".now-playing-background-image, .now-playing-black-bg, .now-playing-gradient-overlay", ".now-playing-background-image, .now-playing-black-bg, .now-playing-gradient-overlay",
) )
.forEach((el) => el.remove()); .forEach((el) => {
el.remove();
});
// Create container // Create container
nowPlayingBackgroundContainer = document.createElement("div"); nowPlayingBackgroundContainer = document.createElement("div");
@@ -455,10 +462,13 @@ function updateCoverArtBackground(method: number = 0): void {
// Performance mode with spinning enabled // Performance mode with spinning enabled
const blur = Math.min(settings.backgroundBlur, 20); const blur = Math.min(settings.backgroundBlur, 20);
const contrast = Math.min(settings.backgroundContrast, 150); const contrast = Math.min(settings.backgroundContrast, 150);
if (nowPlayingBackgroundImage.style.width !== "70vw") const scalePm = getScaledMultiplier();
nowPlayingBackgroundImage.style.width = "70vw"; const widthPm = `${Math.round(scalePm * 100)}vw`;
if (nowPlayingBackgroundImage.style.height !== "70vh") const heightPm = `${Math.round(scalePm * 100)}vh`;
nowPlayingBackgroundImage.style.height = "70vh"; if (nowPlayingBackgroundImage.style.width !== widthPm)
nowPlayingBackgroundImage.style.width = widthPm;
if (nowPlayingBackgroundImage.style.height !== heightPm)
nowPlayingBackgroundImage.style.height = heightPm;
const filt = `blur(${blur}px) brightness(${settings.backgroundBrightness / 100}) contrast(${contrast}%)`; const filt = `blur(${blur}px) brightness(${settings.backgroundBrightness / 100}) contrast(${contrast}%)`;
if (nowPlayingBackgroundImage.style.filter !== filt) if (nowPlayingBackgroundImage.style.filter !== filt)
nowPlayingBackgroundImage.style.filter = filt; nowPlayingBackgroundImage.style.filter = filt;
@@ -473,10 +483,13 @@ function updateCoverArtBackground(method: number = 0): void {
nowPlayingBackgroundImage.classList.remove("performance-mode-static"); nowPlayingBackgroundImage.classList.remove("performance-mode-static");
} else { } else {
// Normal mode // Normal mode
if (nowPlayingBackgroundImage.style.width !== "90vw") const scaleNm = getScaledMultiplier();
nowPlayingBackgroundImage.style.width = "90vw"; const widthNm = `${Math.round(scaleNm * 100)}vw`;
if (nowPlayingBackgroundImage.style.height !== "90vh") const heightNm = `${Math.round(scaleNm * 100)}vh`;
nowPlayingBackgroundImage.style.height = "90vh"; if (nowPlayingBackgroundImage.style.width !== widthNm)
nowPlayingBackgroundImage.style.width = widthNm;
if (nowPlayingBackgroundImage.style.height !== heightNm)
nowPlayingBackgroundImage.style.height = heightNm;
const filt = `blur(${settings.backgroundBlur}px) brightness(${settings.backgroundBrightness / 100}) contrast(${settings.backgroundContrast}%)`; const filt = `blur(${settings.backgroundBlur}px) brightness(${settings.backgroundBrightness / 100}) contrast(${settings.backgroundContrast}%)`;
if (nowPlayingBackgroundImage.style.filter !== filt) if (nowPlayingBackgroundImage.style.filter !== filt)
nowPlayingBackgroundImage.style.filter = filt; nowPlayingBackgroundImage.style.filter = filt;
@@ -520,16 +533,15 @@ const applyGlobalSpinningBackground = (coverArtImageSrc: string): void => {
return; return;
} }
// Throttle updates to prevent excessive DOM manipulation // Only throttle image src updates; style updates below always run for responsiveness
const now = Date.now(); const now = Date.now();
if ( const shouldUpdateImageSrc =
now - lastUpdateTime < getUpdateThrottle() && now - lastUpdateTime >= getUpdateThrottle() ||
currentGlobalCoverSrc === coverArtImageSrc currentGlobalCoverSrc !== coverArtImageSrc;
) { if (shouldUpdateImageSrc) {
return;
}
lastUpdateTime = now; lastUpdateTime = now;
currentGlobalCoverSrc = coverArtImageSrc; currentGlobalCoverSrc = coverArtImageSrc;
}
// Add StyleTag if not present // Add StyleTag if not present
if (!globalSpinningBgStyleTag) { if (!globalSpinningBgStyleTag) {
@@ -579,18 +591,25 @@ const applyGlobalSpinningBackground = (coverArtImageSrc: string): void => {
globalBackgroundContainer.appendChild(globalBackgroundImage); globalBackgroundContainer.appendChild(globalBackgroundImage);
} }
// Update image source efficiently // Update image source efficiently (throttled)
if (globalBackgroundImage && globalBackgroundImage.src !== coverArtImageSrc) { if (
shouldUpdateImageSrc &&
globalBackgroundImage &&
globalBackgroundImage.src !== coverArtImageSrc
) {
globalBackgroundImage.src = coverArtImageSrc; globalBackgroundImage.src = coverArtImageSrc;
} }
// Apply performance-optimized settings // Apply performance-optimized settings
if (globalBackgroundImage) { if (globalBackgroundImage) {
const scale = getScaledMultiplier();
const scaledWidth = `${Math.round(scale * 100)}vw`;
const scaledHeight = `${Math.round(scale * 100)}vh`;
// Performance mode optimizations // Performance mode optimizations
if (settings.performanceMode) { if (settings.performanceMode) {
// Performance mode with spinning enabled // Performance mode with spinning enabled
globalBackgroundImage.style.width = "100vw"; globalBackgroundImage.style.width = scaledWidth;
globalBackgroundImage.style.height = "100vh"; globalBackgroundImage.style.height = scaledHeight;
globalBackgroundImage.style.filter = `blur(${Math.min(settings.backgroundBlur, 20)}px) brightness(${settings.backgroundBrightness / 100}) contrast(${Math.min(settings.backgroundContrast, 150)}%)`; globalBackgroundImage.style.filter = `blur(${Math.min(settings.backgroundBlur, 20)}px) brightness(${settings.backgroundBrightness / 100}) contrast(${Math.min(settings.backgroundContrast, 150)}%)`;
if (settings.spinningArtEnabled) { if (settings.spinningArtEnabled) {
globalBackgroundImage.style.animation = `spinGlobal ${settings.spinSpeed}s linear infinite`; globalBackgroundImage.style.animation = `spinGlobal ${settings.spinSpeed}s linear infinite`;
@@ -602,8 +621,8 @@ const applyGlobalSpinningBackground = (coverArtImageSrc: string): void => {
globalBackgroundImage.classList.remove("performance-mode-static"); globalBackgroundImage.classList.remove("performance-mode-static");
} else { } else {
// Normal mode // Normal mode
globalBackgroundImage.style.width = "150vw"; globalBackgroundImage.style.width = scaledWidth;
globalBackgroundImage.style.height = "150vh"; globalBackgroundImage.style.height = scaledHeight;
globalBackgroundImage.style.filter = `blur(${settings.backgroundBlur}px) brightness(${settings.backgroundBrightness / 100}) contrast(${settings.backgroundContrast}%)`; globalBackgroundImage.style.filter = `blur(${settings.backgroundBlur}px) brightness(${settings.backgroundBrightness / 100}) contrast(${settings.backgroundContrast}%)`;
if (settings.spinningArtEnabled) { if (settings.spinningArtEnabled) {
globalBackgroundImage.style.animation = `spinGlobal ${settings.spinSpeed}s linear infinite`; globalBackgroundImage.style.animation = `spinGlobal ${settings.spinSpeed}s linear infinite`;
@@ -664,7 +683,7 @@ const updateRadiantLyricsNowPlayingBackground = function (): void {
const defaultContrast = 120; const defaultContrast = 120;
const defaultSpinSpeed = 45; const defaultSpinSpeed = 45;
let blur, brightness, contrast, spinSpeed; let blur: number, brightness: number, contrast: number, spinSpeed: number;
if (settings.settingsAffectNowPlaying) { if (settings.settingsAffectNowPlaying) {
blur = settings.backgroundBlur; blur = settings.backgroundBlur;
@@ -678,6 +697,11 @@ const updateRadiantLyricsNowPlayingBackground = function (): void {
spinSpeed = defaultSpinSpeed; spinSpeed = defaultSpinSpeed;
} }
// Apply size based on backgroundScale
const scale = getScaledMultiplier();
imgElement.style.width = `${Math.round(scale * 100)}vw`;
imgElement.style.height = `${Math.round(scale * 100)}vh`;
// Performance mode optimizations // Performance mode optimizations
if (settings.performanceMode) { if (settings.performanceMode) {
// Reduce blur and effects for better performance, but keep spinning // Reduce blur and effects for better performance, but keep spinning