仰望星辰工作室

starmusic-pc

starmusic-pc/ frontend/src/composables/useTheme.js 1.9 KB · 57 行 原始文件
1/**
2 * 外观状态(主题色 + 自定义背景图)
3 *
4 * 把 common/theme.js 与 common/background.js 的同步计算结果收敛成一个响应式对象,
5 * 挂在 .app-root 的内联样式上——切主题只需一次赋值,全站 CSS 变量即时生效。
6 */
7import { reactive, computed } from 'vue'
8import { THEMES, getTheme, setTheme, getThemeId, buildThemeStyle } from '../common/theme.js'
9import { buildBgStyle, buildBgVars, isBgImageOn } from '../common/background.js'
10import event from '../common/event.js'
11
12export { THEMES }
13
14export const appearance = reactive({
15 /** 当前主题 id */
16 themeId: getThemeId(),
17 /** 注入 .app-root 的 CSS 变量 + 内容层透明变量 */
18 style: {},
19 /** 背景图层内联样式(未启用时为 null) */
20 bgStyle: null,
21 /** 背景图是否启用 */
22 bgOn: false,
23})
24
25/** 当前主题对象(含 name / color 等,供色板与文案使用) */
26export const currentTheme = computed(() => THEMES.find((t) => t.id === appearance.themeId) || THEMES[0])
27
28/** 当前主题主色(canvas 等无法用 CSS 变量的场景) */
29export const themeColor = computed(() => currentTheme.value.color)
30
31/** 重新计算结果(主题或背景图变化时调用) */
32export const refreshAppearance = () => {
33 appearance.themeId = getThemeId()
34 appearance.style = { ...buildThemeStyle(), ...buildBgVars() }
35 appearance.bgStyle = buildBgStyle()
36 appearance.bgOn = isBgImageOn()
37}
38
39/** 切换主题 */
40export const applyTheme = (id) => {
41 const theme = setTheme(id)
42 refreshAppearance()
43 return theme
44}
45
46/** 初始化(幂等),并在设置变化时自动刷新 */
47let initialized = false
48export const initAppearance = () => {
49 if (initialized) return
50 initialized = true
51 refreshAppearance()
52 event.on('settingUpdated', (keys) => {
53 if (!keys || keys.some((k) => k.indexOf('common.theme') === 0 || k.indexOf('common.bgImage') === 0)) {
54 refreshAppearance()
55 }
56 })
57}