feat(显示设置): 实现彩虹模式动画效果

添加CSS动画实现彩虹模式效果,使用CSS变量控制动画速度
移除旧的JavaScript实现的彩虹模式逻辑,改为纯CSS方案
This commit is contained in:
二叉树树
2026-01-03 20:30:18 +08:00
parent 65fdf10e34
commit 05510702f4
2 changed files with 87 additions and 69 deletions

View File

@@ -30,80 +30,69 @@ let rainbowSpeed = getRainbowSpeed();
let bgBlur = getBgBlur();
let hideBg = getHideBg();
let isDevMode = getDevMode();
let devServer = getDevServer();
let animationId: number;
let lastUpdate = 0;
let rainbowHue = 0; // Independent hue for background rotation
let devServer = getDevServer();
let animationId: number;
const defaultHue = getDefaultHue();
const defaultHue = getDefaultHue();
function resetHue() {
hue = getDefaultHue();
}
$: if ((hue || hue === 0) && !isRainbowMode) {
setHue(hue);
}
$: {
setBgBlur(bgBlur);
}
function switchTheme(newTheme: string) {
theme = newTheme;
setTheme(newTheme);
}
function updateRainbow() {
if (!isRainbowMode) return;
hue = (hue + rainbowSpeed * 0.05) % 360;
setHue(hue, false);
animationId = requestAnimationFrame(updateRainbow);
}
function toggleRainbow() {
isRainbowMode = !isRainbowMode;
setRainbowMode(isRainbowMode);
if (isRainbowMode) {
lastUpdate = performance.now();
rainbowHue = 0; // Reset rotation start
animationId = requestAnimationFrame(updateRainbow);
} else {
cancelAnimationFrame(animationId);
// Reset background rotation to 0 when stopped
setBgHueRotate(0);
function resetHue() {
hue = getDefaultHue();
}
}
function toggleHideBg() {
hideBg = !hideBg;
setHideBg(hideBg);
}
function toggleDevMode() {
isDevMode = !isDevMode;
setDevMode(isDevMode);
}
function onDevServerChange() {
setDevServer(devServer);
}
function onSpeedChange() {
setRainbowSpeed(rainbowSpeed);
}
onMount(() => {
if (isRainbowMode) {
updateRainbow();
$: if ((hue || hue === 0) && !isRainbowMode) {
setHue(hue);
}
return () => {
if (animationId) cancelAnimationFrame(animationId);
};
});
$: {
setBgBlur(bgBlur);
}
function switchTheme(newTheme: string) {
theme = newTheme;
setTheme(newTheme);
}
function toggleRainbow() {
isRainbowMode = !isRainbowMode;
setRainbowMode(isRainbowMode);
if (isRainbowMode) {
document.documentElement.classList.add("is-rainbow-mode");
document.documentElement.style.setProperty("--rainbow-duration", `${120 / rainbowSpeed}s`);
} else {
document.documentElement.classList.remove("is-rainbow-mode");
document.documentElement.style.removeProperty("--rainbow-duration");
setHue(hue); // Restore the static hue
}
}
function toggleHideBg() {
hideBg = !hideBg;
setHideBg(hideBg);
}
function toggleDevMode() {
isDevMode = !isDevMode;
setDevMode(isDevMode);
}
function onDevServerChange() {
setDevServer(devServer);
}
function onSpeedChange() {
setRainbowSpeed(rainbowSpeed);
if (isRainbowMode) {
document.documentElement.style.setProperty("--rainbow-duration", `${120 / rainbowSpeed}s`);
}
}
onMount(() => {
if (isRainbowMode) {
document.documentElement.classList.add("is-rainbow-mode");
document.documentElement.style.setProperty("--rainbow-duration", `${120 / rainbowSpeed}s`);
}
});
</script>
<div id="display-setting" class="float-panel float-panel-closed absolute transition-all w-80 right-4 px-4 py-4">

View File

@@ -1,6 +1,35 @@
@tailwind components;
@layer components {
/* Rainbow Mode Animation */
@keyframes rainbow-backdrop {
0% { backdrop-filter: hue-rotate(0deg); }
100% { backdrop-filter: hue-rotate(360deg); }
}
html.is-rainbow-mode .card-base {
position: relative;
}
html.is-rainbow-mode .card-base::after {
content: "";
position: absolute;
inset: 0;
z-index: 1;
pointer-events: none;
border-radius: inherit;
animation: rainbow-backdrop linear infinite;
animation-duration: var(--rainbow-duration, 5s);
}
/* Protect images and other sensitive media from color rotation */
html.is-rainbow-mode .card-base img,
html.is-rainbow-mode .card-base video,
html.is-rainbow-mode .card-base iframe {
position: relative;
z-index: 2;
}
.card-base {
@apply rounded-[var(--radius-large)] overflow-hidden bg-[var(--card-bg)] transition;
@apply border border-black/5 dark:border-white/10;