feat: 设置标题字体与全局字体同步 #96

This commit is contained in:
LOG1997
2025-12-10 23:38:56 +08:00
parent dcf57459b7
commit ae12335c5d
6 changed files with 101 additions and 24 deletions

View File

@@ -25,6 +25,8 @@ export const useGlobalConfig = defineStore('global', {
patternList: defaultPatternList as number[],
background: {}, // 背景颜色或图片
font: '微软雅黑',
titleFont: '微软雅黑',
titleFontSyncGlobal: true,
},
musicList: defaultMusicList as IMusic[],
imageList: defaultImageList as IImage[],
@@ -111,6 +113,14 @@ export const useGlobalConfig = defineStore('global', {
getFont(state) {
return state.globalConfig.theme.font
},
// 获取标题字体
getTitleFont(state) {
return state.globalConfig.theme.titleFont
},
// 获取标题字体同步全局
getTitleFontSyncGlobal(state) {
return state.globalConfig.theme.titleFontSyncGlobal
},
// 获取是否显示头像
getIsShowAvatar(state) {
return state.globalConfig.isShowAvatar
@@ -241,6 +251,14 @@ export const useGlobalConfig = defineStore('global', {
setFont(font: any) {
this.globalConfig.theme.font = font
},
// 设置标题字体
setTitleFont(titleFont: any) {
this.globalConfig.theme.titleFont = titleFont
},
// 设置同步全局字体
setTitleFontSyncGlobal(titleFontSyncGlobal: boolean) {
this.globalConfig.theme.titleFontSyncGlobal = titleFontSyncGlobal
},
// 设置是否显示头像
setIsShowAvatar(isShowAvatar: boolean) {
this.globalConfig.isShowAvatar = isShowAvatar
@@ -266,6 +284,8 @@ export const useGlobalConfig = defineStore('global', {
patternList: defaultPatternList as number[],
background: {}, // 背景颜色或图片
font: '微软雅黑',
titleFont: '微软雅黑',
titleFontSyncGlobal: true,
},
musicList: defaultMusicList as IMusic[],
imageList: defaultImageList as IImage[],

View File

@@ -2,7 +2,7 @@
import { refDebounced } from '@vueuse/core'
import { ChevronRight, ChevronsUpDownIcon } from 'lucide-vue-next'
import { PopoverArrow } from 'reka-ui'
import { ref } from 'vue'
import { computed, ref } from 'vue'
import { Button } from '@/components/ui/button'
import {
Command,
@@ -20,12 +20,14 @@ import {
import { useLocalFonts } from '@/hooks/useLocalFonts'
import { cn } from '@/lib/utils'
const props = defineProps<{
disabled?: boolean
}>()
const selectedFont = defineModel('selectedFont', {
type: String,
required: true,
})
const { getFonts, disabled, fonts } = useLocalFonts()
const { getFonts, disabled: browserDisabled, fonts } = useLocalFonts()
const open = ref(false)
const activeKey = ref('')
const debouncedActiveKey = refDebounced(activeKey, 20)
@@ -43,12 +45,20 @@ function handelActiveKey(val: string) {
function handleScroll() {
activeKey.value = ''
}
const disabledStyle = computed(() => {
if (props.disabled || browserDisabled) {
return {
cursor: 'not-allowed',
}
}
return {}
})
</script>
<template>
<div class="w-full h-full flex justify-center items-center max-w-xs">
<div class="w-full h-full flex justify-center items-center max-w-xs" :style="disabledStyle">
<Popover v-model:open="open">
<PopoverTrigger as-child :disabled="disabled">
<PopoverTrigger as-child :disabled="browserDisabled || disabled">
<Button
variant="outline"
role="combobox"

View File

@@ -19,7 +19,7 @@ const { t } = useI18n()
const globalConfig = useStore().globalConfig
const personConfig = useStore().personConfig
const prizeConfig = useStore().prizeConfig
const { getTopTitle: topTitle, getTheme: localTheme, getPatterColor: patternColor, getPatternList: patternList, getCardColor: cardColor, getLuckyColor: luckyCardColor, getTextColor: textColor, getCardSize: cardSize, getTextSize: textSize, getRowCount: rowCount, getIsShowPrizeList: isShowPrizeList, getLanguage: userLanguage, getBackground: backgroundImage, getFont: currentFont, getImageList: imageList, getIsShowAvatar: isShowAvatar,
const { getTopTitle: topTitle, getTheme: localTheme, getPatterColor: patternColor, getPatternList: patternList, getCardColor: cardColor, getLuckyColor: luckyCardColor, getTextColor: textColor, getCardSize: cardSize, getTextSize: textSize, getRowCount: rowCount, getIsShowPrizeList: isShowPrizeList, getLanguage: userLanguage, getBackground: backgroundImage, getFont: currentFont, getTitleFont: currentTitleFont, getTitleFontSyncGlobal: titleFontSyncGlobal, getImageList: imageList, getIsShowAvatar: isShowAvatar,
} = storeToRefs(globalConfig)
const { getAlreadyPersonList: alreadyPersonList, getNotPersonList: notPersonList } = storeToRefs(personConfig)
const colorPickerRef = ref()
@@ -43,7 +43,9 @@ const patternColorValue = ref(structuredClone(patternColor.value))
const themeList = ref(daisyuiThemes)
const daisyuiThemeList = ref<ThemeDaType>(daisyuiThemes)
const backgroundImageValue = ref(backgroundImage.value)
const currentFontValue = ref(currentFont.value)
const currentFontValue = ref(structuredClone(currentFont.value))
const currentTitleFontValue = ref(structuredClone(currentTitleFont.value))
const titleFontSyncGlobalValue = ref(structuredClone(titleFontSyncGlobal.value))
const formData = ref({
rowCount: rowCountValue,
})
@@ -155,7 +157,13 @@ watch(backgroundImageValue, (val) => {
watch(currentFontValue, (val) => {
globalConfig.setFont(val)
document.documentElement.style.setProperty('--app-font-family', `"${val}", -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif`)
}, { immediate: true })
})
watch(currentTitleFontValue, (val) => {
globalConfig.setTitleFont(val)
})
watch(titleFontSyncGlobalValue, (val) => {
globalConfig.setTitleFontSyncGlobal(val)
})
watch(languageValue, (val: string) => {
globalConfig.setLanguage(val)
})
@@ -195,9 +203,9 @@ onMounted(() => {
{{ t('button.resetAllData') }}
</button>
</div>
<div class="flex flex-wrap w-full gap-6">
<div class="flex flex-wrap h-auto w-full gap-6">
<!-- 文本设置主标题语言文字大小 -->
<fieldset class="p-4 border text-setting fieldset bg-base-200 border-base-300 rounded-box w-xs">
<fieldset class="p-4 border text-setting fieldset bg-base-200 border-base-300 rounded-box w-xs pb-10">
<legend class="fieldset-legend">
文本设置
</legend>
@@ -216,7 +224,7 @@ onMounted(() => {
<div class="label">
<span class="label-text">{{ t('table.language') }}</span>
</div>
<select v-model="languageValue" data-choose-theme class="w-full max-w-xs border-solid select border-1">
<select v-model="languageValue" data-choose-theme class="w-full max-w-xs border-solid select border">
<option disabled selected>{{ t('table.language') }}</option>
<option v-for="item in languageList" :key="item.key" :value="item.key">{{ item.name }}</option>
</select>
@@ -232,15 +240,29 @@ onMounted(() => {
>
</label>
<label class="w-full max-w-xs form-control">
<label class="w-full max-w-xs form-control mt-3">
<div class="label">
<span class="label-text">字体</span>
<span class="label-text">全局字体</span>
</div>
<SelectFont v-model:selected-font="currentFontValue" />
</label>
<label class="flex flex-row w-full max-w-xs mt-5 gap-10 form-control">
<div class="w-3/4">
<div class="label">
<span class="label-text">标题字体</span>
</div>
<SelectFont v-model:selected-font="currentTitleFontValue" :disabled="titleFontSyncGlobalValue" />
</div>
<div class="flex flex-col gap-4">
<div class="label">
<span class="label-text">同全局</span>
</div>
<input type="checkbox" :checked="titleFontSyncGlobalValue" class="border-solid checkbox checkbox-secondary border" @change="titleFontSyncGlobalValue = !titleFontSyncGlobalValue">
</div>
</label>
</fieldset>
<!-- 布局设置列数卡片宽度卡片高度 -->
<fieldset class="p-4 border text-setting fieldset bg-base-200 border-base-300 rounded-box w-xs">
<fieldset class="p-4 border text-setting fieldset bg-base-200 border-base-300 rounded-box w-xs pb-10">
<legend class="fieldset-legend">
布局设置
</legend>
@@ -291,7 +313,7 @@ onMounted(() => {
</label>
</fieldset>
<!-- 主题设置主题背景图片 -->
<fieldset class="p-4 border text-setting fieldset bg-base-200 border-base-300 rounded-box w-xs">
<fieldset class="p-4 border text-setting fieldset bg-base-200 border-base-300 rounded-box w-xs pb-10">
<legend class="fieldset-legend">
主题设置
</legend>
@@ -363,7 +385,7 @@ onMounted(() => {
</div>
</fieldset>
<!-- 图案设置 -->
<fieldset class="p-4 border text-setting fieldset bg-base-200 border-base-300 rounded-box w-xs">
<fieldset class="p-4 border text-setting fieldset bg-base-200 border-base-300 rounded-box w-xs pb-10">
<legend class="fieldset-legend">
图案设置
</legend>
@@ -392,7 +414,7 @@ onMounted(() => {
</div>
</fieldset>
<!-- 其他设置是否常显奖项列表是否显示头像 -->
<fieldset class="p-4 border text-setting fieldset bg-base-200 border-base-300 rounded-box w-xs">
<fieldset class="p-4 border text-setting fieldset bg-base-200 border-base-300 rounded-box w-xs pb-10">
<legend class="fieldset-legend">
其他设置
</legend>
@@ -402,7 +424,7 @@ onMounted(() => {
<span class="label-text">{{ t('table.alwaysDisplay') }}</span>
</div>
<input
type="checkbox" :checked="isShowPrizeListValue" class="border-solid checkbox checkbox-secondary border-1"
type="checkbox" :checked="isShowPrizeListValue" class="border-solid checkbox checkbox-secondary border"
@change="isShowPrizeListValue = !isShowPrizeListValue"
>
</div>
@@ -411,7 +433,7 @@ onMounted(() => {
<span class="label-text">{{ t('table.avatarDisplay') }}</span>
</div>
<input
type="checkbox" :checked="isShowAvatarValue" class="border-solid checkbox checkbox-secondary border-1"
type="checkbox" :checked="isShowAvatarValue" class="border-solid checkbox checkbox-secondary border"
@change="isShowAvatarValue = !isShowAvatarValue"
>
</div>

View File

@@ -1,5 +1,5 @@
<script setup lang='ts'>
import { toRefs } from 'vue'
import { computed, toRefs } from 'vue'
import { useI18n } from 'vue-i18n'
import { useRouter } from 'vue-router'
@@ -11,11 +11,32 @@ interface Props {
tableData: any[]
setDefaultPersonList: () => void
isInitialDone: boolean
titleFont: string
titleFontSyncGlobal: boolean
}
const props = defineProps<Props>()
const router = useRouter()
const { tableData, textSize, textColor, topTitle, setDefaultPersonList } = toRefs(props)
const { tableData, textSize, textColor, topTitle, setDefaultPersonList, titleFont, titleFontSyncGlobal } = toRefs(props)
const titleStyle = computed(() => {
const baseStyle = {
fontSize: `${textSize.value * 1.5}px`,
color: textColor.value,
}
if (titleFontSyncGlobal.value) {
return {
...baseStyle,
}
}
else {
return {
...baseStyle,
fontFamily: titleFont.value,
}
}
})
const { t } = useI18n()
</script>
@@ -23,7 +44,7 @@ const { t } = useI18n()
<div class="absolute z-10 flex flex-col items-center justify-center -translate-x-1/2 left-1/2">
<h2
class="pt-12 m-0 mb-12 tracking-wide text-center leading-12 header-title"
:style="{ fontSize: `${textSize * 1.5}px`, color: textColor }"
:style="titleStyle"
>
{{ topTitle }}
</h2>

View File

@@ -9,7 +9,7 @@ import { useViewModel } from './useViewModel'
import 'vue-toast-notification/dist/theme-sugar.css'
const viewModel = useViewModel()
const { setDefaultPersonList, tableData, currentStatus, enterLottery, stopLottery, containerRef, startLottery, continueLottery, quitLottery, isInitialDone } = viewModel
const { setDefaultPersonList, tableData, currentStatus, enterLottery, stopLottery, containerRef, startLottery, continueLottery, quitLottery, isInitialDone, titleFont, titleFontSyncGlobal } = viewModel
const globalConfig = useStore().globalConfig
const { getTopTitle: topTitle, getTextColor: textColor, getTextSize: textSize, getBackground: homeBackground } = storeToRefs(globalConfig)
@@ -23,6 +23,8 @@ const { getTopTitle: topTitle, getTextColor: textColor, getTextSize: textSize, g
:top-title="topTitle"
:set-default-person-list="setDefaultPersonList"
:is-initial-done="isInitialDone"
:title-font="titleFont"
:title-font-sync-global="titleFontSyncGlobal"
/>
<div id="container" ref="containerRef" class="3dContainer">
<OptionButton

View File

@@ -26,7 +26,7 @@ export function useViewModel() {
getNotThisPrizePersonList: notThisPrizePersonList,
} = storeToRefs(personConfig)
const { getCurrentPrize: currentPrize } = storeToRefs(prizeConfig)
const { getCardColor: cardColor, getPatterColor: patternColor, getPatternList: patternList, getTextColor: textColor, getLuckyColor: luckyColor, getCardSize: cardSize, getTextSize: textSize, getRowCount: rowCount, getIsShowAvatar: isShowAvatar } = storeToRefs(globalConfig)
const { getCardColor: cardColor, getPatterColor: patternColor, getPatternList: patternList, getTextColor: textColor, getLuckyColor: luckyColor, getCardSize: cardSize, getTextSize: textSize, getRowCount: rowCount, getIsShowAvatar: isShowAvatar, getTitleFont: titleFont, getTitleFontSyncGlobal: titleFontSyncGlobal } = storeToRefs(globalConfig)
// three初始值
const ballRotationY = ref(0)
const containerRef = ref<HTMLElement>()
@@ -636,5 +636,7 @@ export function useViewModel() {
tableData,
currentStatus,
isInitialDone,
titleFont,
titleFontSyncGlobal,
}
}