diff --git a/src/App.scss b/src/App.scss index caa82e0..20c4a9f 100644 --- a/src/App.scss +++ b/src/App.scss @@ -96,3 +96,13 @@ width: 100%; margin-top: 8px; } + +.background { + position: fixed; + left: 0; + top: 0; + width: 100vw; + height: 100vh; + object-fit: cover; + z-index: -1; +} diff --git a/src/App.tsx b/src/App.tsx index 541e6de..547dd4c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -230,7 +230,6 @@ const App: FC = () => { .then((res) => { // @ts-ignore const { content } = res; - try { const customTheme = JSON.parse(content); if (!customTheme.pure) { @@ -483,6 +482,16 @@ const App: FC = () => { return ( <> + {curTheme.background && ( + background + )}

{curTheme.title}{' '} {curTheme.title === CUSTOM_THEME_FAIL_TIP && ( diff --git a/src/components/ConfigDialog.tsx b/src/components/ConfigDialog.tsx index 137af45..893b40e 100644 --- a/src/components/ConfigDialog.tsx +++ b/src/components/ConfigDialog.tsx @@ -38,7 +38,9 @@ export const ConfigDialog: FC<{ title: string; desc?: string; bgm?: string; - }>({ title: '', desc: '', bgm: '' }); + background?: string; + backgroundBlur?: boolean; + }>({ title: '', desc: '', bgm: '', background: '', backgroundBlur: false }); const [addDialog, setAddDialog] = useState<{ show: boolean; type: 'sound' | 'icon'; @@ -57,7 +59,15 @@ export const ConfigDialog: FC<{ // 初始化 useEffect(() => { if (storageTheme) { - const { title, desc, bgm, sounds, icons } = storageTheme; + const { + title, + desc = '', + bgm = '', + sounds, + icons, + background = '', + backgroundBlur = false, + } = storageTheme; setSounds( sounds.filter( (s) => !['triple', 'button-click'].includes(s.name) @@ -76,6 +86,8 @@ export const ConfigDialog: FC<{ // @ts-ignore desc, bgm, + background, + backgroundBlur, }); } }, []); @@ -205,9 +217,12 @@ export const ConfigDialog: FC<{ // 生成主题 const generateTheme: () => Promise> = async () => { - const { title, desc, bgm } = customThemeInfo; + const { title, desc, bgm, background, backgroundBlur } = + customThemeInfo; if (bgm && !bgm.startsWith('https')) - return Promise.reject('bgm请输入https链接'); + return Promise.reject('背景音乐请输入https链接'); + if (background && !background.startsWith('https')) + return Promise.reject('背景图片请输入https链接'); if (!title) return Promise.reject('请填写标题'); if (icons.length !== 10) return Promise.reject('图片素材需要提供10张'); @@ -235,6 +250,8 @@ export const ConfigDialog: FC<{ title, desc, bgm, + background, + backgroundBlur, icons: customIcons, sounds: customSounds, }; @@ -305,6 +322,7 @@ export const ConfigDialog: FC<{ ); }; + // TODO HTML有点臭长了,待优化 // @ts-ignore return (
setCustomThemeInfo({ @@ -366,6 +384,35 @@ export const ConfigDialog: FC<{ } />

+

+ 背景图片: + + setCustomThemeInfo({ + ...customThemeInfo, + background: e.target.value, + }) + } + /> + {customThemeInfo?.background?.startsWith('https') && ( + <> + 毛玻璃效果: + + setCustomThemeInfo({ + ...customThemeInfo, + backgroundBlur: e.target.checked, + }) + } + type="checkbox" + /> + + )} +

音效素材

diff --git a/src/themes/interface.ts b/src/themes/interface.ts index 8964b51..08b4951 100644 --- a/src/themes/interface.ts +++ b/src/themes/interface.ts @@ -20,6 +20,8 @@ export interface Theme { desc?: ReactNode; name: string; bgm?: string; + background?: string; + backgroundBlur?: boolean; pure?: boolean; icons: Icon[]; sounds: Sound[];