☔
状态
文章总数
56篇 总字数
7.0万 运营时长
2年7个月分类
标签
AI Arch BF CLI CSS Fuwari Giscus GTK HEO Hyprland JS KDE K签 Linux Lisp LLM Path Pypi Python RSS Vim VTB VUP Whl WP 上海 专业 主题 云朵 享乐 优化 伦理 便利店 俄国 光标 内耗 函数式 分析 创伤 创意 判断 前端 北京 参观 哲学 商业 国庆 壁纸 天津 姐妹 字典 安装 实用 对话 度假 开发环境 开源 归档 微风 心理 意义 技校 抚远 拥抱 推荐 插件 摄影 政策 故障排查 效果 散文 文件 文化 旅游 日本 显卡 样式 模糊 治愈 浏览器 浦东 浦西 热力图 特效 猫猫 玩具 环境 甘城 生态 病毒 直播 社会 社团 视奸 秋游 科幻 移民 窗口 系统 终端 经济 美化 美缝 耳机 脑操 自动驾驶 苏州 茅山 萌系 补档 解释器 设计 评论 话术 谷子 走路 轮子 辍学 迁移 运维 重构 随机 静安 音频 颜文字 颜色 首都 麦金塔 鼠标
790 字
4 分钟
让Fuwari的主题色随时间变化
11月的月度配色,我上线了一个可以让主题色(hue)随着时间而慢慢变化的效果,效果还是可以的。
在Fuwari主题中,hue是取值为0到360的数值,一个数字对应着不同的色相,我的思路是从一个默认色(例如这次的257)开始,每隔一秒就把hue加一,超过360就回到0,以此往复。
接下来我将实现的源码公开(虽然也是用AI写的),省得想要的人扒了,正好还能水一篇文章。
TIP这个设计实际上也不是我独创的,而是很早之前看到的一个Fuwari博客,也只是看到了实装效果,后来这个博客搜索不到了。
修改setting-utils.ts
打开src/utils/setting-utils.ts文件,这里就是控制hue的地方,直接覆盖所有内容:
import type { LIGHT_DARK_MODE } from '@/types/config'
import {
AUTO_MODE,
DARK_MODE,
DEFAULT_THEME,
LIGHT_MODE,
} from '@constants/constants.ts'
// 新增:仅在浏览器环境下删除用户存储的颜色(避免SSR环境报错)
if (typeof window !== 'undefined') {
localStorage.removeItem('hue');
}
export function getDefaultHue(): number {
// 旧代码:原默认颜色 fallback 为 250
// const fallback = '250'
// 新代码:默认颜色改为275,作为循环起始值
const fallback = '275'
const configCarrier = document.getElementById('config-carrier')
return Number.parseInt(configCarrier?.dataset.hue || fallback)
}
export function getHue(): number {
// 新增:检查window环境,避免报错
if (typeof window === 'undefined') {
return getDefaultHue()
}
const stored = localStorage.getItem('hue')
return stored ? Number.parseInt(stored) : getDefaultHue()
}
export function setHue(hue: number): void {
const defaultHue = getDefaultHue()
// 新增:检查window环境,避免报错
if (typeof window !== 'undefined') {
// 只有当要设置的颜色不是默认颜色时,才存入localStorage
// 如果是默认颜色,则移除已存储的值
if (hue === defaultHue) {
localStorage.removeItem('hue')
} else {
localStorage.setItem('hue', String(hue))
}
}
// 无论是否为默认颜色,都更新CSS变量(同样需要检查浏览器环境)
if (typeof window !== 'undefined') {
const root = document.querySelector(':root') as HTMLElement
if (root) {
root.style.setProperty('--hue', String(hue))
}
}
}
export function applyThemeToDocument(theme: LIGHT_DARK_MODE) {
// 检查浏览器环境
if (typeof window === 'undefined') {
return
}
switch (theme) {
case LIGHT_MODE:
document.documentElement.classList.remove('dark')
break
case DARK_MODE:
document.documentElement.classList.add('dark')
break
case AUTO_MODE:
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove('dark')
}
break
}
}
export function setTheme(theme: LIGHT_DARK_MODE): void {
// 检查浏览器环境
if (typeof window !== 'undefined') {
localStorage.setItem('theme', theme)
applyThemeToDocument(theme)
}
}
export function getStoredTheme(): LIGHT_DARK_MODE {
// 检查浏览器环境
if (typeof window === 'undefined') {
return DEFAULT_THEME
}
return (localStorage.getItem('theme') as LIGHT_DARK_MODE) || DEFAULT_THEME
}
// 新增:实现每秒颜色加1,循环往复(0-360)
function startHueCycle() {
// 检查浏览器环境,仅在客户端执行
if (typeof window === 'undefined') {
return
}
// 从默认颜色开始循环(当前默认值为275)
let currentHue = getHue()
setInterval(() => {
currentHue += 1
// 超过360回到0,确保在0-360范围内循环
if (currentHue >= 360) {
currentHue = 0
}
setHue(currentHue)
}, 1000)
}
// 新增:启动颜色循环
startHueCycle()
修改config.ts
打开src/config.ts文件,将themecolor里的fixed项设为true,因为这个效果与主题色选择器不兼容,大概在15行的位置:
// ...
export const siteConfig: SiteConfig = {
title: 'Pinpe的云端',
subtitle: '一个属于自己的云朵',
lang: 'zh_CN',
themeColor: {
hue: 275,
fixed: true, // 将此项设为true
},
banner: {
// ...
如果此时间过长,文中的信息可能会失去时效性,甚至不再准确。

