mirror of
				https://ghproxy.com/https://github.com/StreakingMan/solvable-sheep-game
				synced 2025-11-04 12:06:08 +08:00 
			
		
		
		
	feat(自定义主题): 背景图片配置
This commit is contained in:
		
							parent
							
								
									0127253fdd
								
							
						
					
					
						commit
						ae7dab752c
					
				
							
								
								
									
										10
									
								
								src/App.scss
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/App.scss
									
									
									
									
									
								
							| 
						 | 
					@ -96,3 +96,13 @@
 | 
				
			||||||
    width: 100%;
 | 
					    width: 100%;
 | 
				
			||||||
    margin-top: 8px;
 | 
					    margin-top: 8px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.background {
 | 
				
			||||||
 | 
					    position: fixed;
 | 
				
			||||||
 | 
					    left: 0;
 | 
				
			||||||
 | 
					    top: 0;
 | 
				
			||||||
 | 
					    width: 100vw;
 | 
				
			||||||
 | 
					    height: 100vh;
 | 
				
			||||||
 | 
					    object-fit: cover;
 | 
				
			||||||
 | 
					    z-index: -1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								src/App.tsx
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								src/App.tsx
									
									
									
									
									
								
							| 
						 | 
					@ -230,7 +230,6 @@ const App: FC = () => {
 | 
				
			||||||
                .then((res) => {
 | 
					                .then((res) => {
 | 
				
			||||||
                    // @ts-ignore
 | 
					                    // @ts-ignore
 | 
				
			||||||
                    const { content } = res;
 | 
					                    const { content } = res;
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    try {
 | 
					                    try {
 | 
				
			||||||
                        const customTheme = JSON.parse(content);
 | 
					                        const customTheme = JSON.parse(content);
 | 
				
			||||||
                        if (!customTheme.pure) {
 | 
					                        if (!customTheme.pure) {
 | 
				
			||||||
| 
						 | 
					@ -483,6 +482,16 @@ const App: FC = () => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <>
 | 
					        <>
 | 
				
			||||||
 | 
					            {curTheme.background && (
 | 
				
			||||||
 | 
					                <img
 | 
				
			||||||
 | 
					                    alt="background"
 | 
				
			||||||
 | 
					                    src={curTheme.background}
 | 
				
			||||||
 | 
					                    className="background"
 | 
				
			||||||
 | 
					                    style={{
 | 
				
			||||||
 | 
					                        filter: curTheme.backgroundBlur ? 'blur(8px)' : 'none',
 | 
				
			||||||
 | 
					                    }}
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					            )}
 | 
				
			||||||
            <h2>
 | 
					            <h2>
 | 
				
			||||||
                {curTheme.title}{' '}
 | 
					                {curTheme.title}{' '}
 | 
				
			||||||
                {curTheme.title === CUSTOM_THEME_FAIL_TIP && (
 | 
					                {curTheme.title === CUSTOM_THEME_FAIL_TIP && (
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +38,9 @@ export const ConfigDialog: FC<{
 | 
				
			||||||
        title: string;
 | 
					        title: string;
 | 
				
			||||||
        desc?: string;
 | 
					        desc?: string;
 | 
				
			||||||
        bgm?: string;
 | 
					        bgm?: string;
 | 
				
			||||||
    }>({ title: '', desc: '', bgm: '' });
 | 
					        background?: string;
 | 
				
			||||||
 | 
					        backgroundBlur?: boolean;
 | 
				
			||||||
 | 
					    }>({ title: '', desc: '', bgm: '', background: '', backgroundBlur: false });
 | 
				
			||||||
    const [addDialog, setAddDialog] = useState<{
 | 
					    const [addDialog, setAddDialog] = useState<{
 | 
				
			||||||
        show: boolean;
 | 
					        show: boolean;
 | 
				
			||||||
        type: 'sound' | 'icon';
 | 
					        type: 'sound' | 'icon';
 | 
				
			||||||
| 
						 | 
					@ -57,7 +59,15 @@ export const ConfigDialog: FC<{
 | 
				
			||||||
    // 初始化
 | 
					    // 初始化
 | 
				
			||||||
    useEffect(() => {
 | 
					    useEffect(() => {
 | 
				
			||||||
        if (storageTheme) {
 | 
					        if (storageTheme) {
 | 
				
			||||||
            const { title, desc, bgm, sounds, icons } = storageTheme;
 | 
					            const {
 | 
				
			||||||
 | 
					                title,
 | 
				
			||||||
 | 
					                desc = '',
 | 
				
			||||||
 | 
					                bgm = '',
 | 
				
			||||||
 | 
					                sounds,
 | 
				
			||||||
 | 
					                icons,
 | 
				
			||||||
 | 
					                background = '',
 | 
				
			||||||
 | 
					                backgroundBlur = false,
 | 
				
			||||||
 | 
					            } = storageTheme;
 | 
				
			||||||
            setSounds(
 | 
					            setSounds(
 | 
				
			||||||
                sounds.filter(
 | 
					                sounds.filter(
 | 
				
			||||||
                    (s) => !['triple', 'button-click'].includes(s.name)
 | 
					                    (s) => !['triple', 'button-click'].includes(s.name)
 | 
				
			||||||
| 
						 | 
					@ -76,6 +86,8 @@ export const ConfigDialog: FC<{
 | 
				
			||||||
                // @ts-ignore
 | 
					                // @ts-ignore
 | 
				
			||||||
                desc,
 | 
					                desc,
 | 
				
			||||||
                bgm,
 | 
					                bgm,
 | 
				
			||||||
 | 
					                background,
 | 
				
			||||||
 | 
					                backgroundBlur,
 | 
				
			||||||
            });
 | 
					            });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }, []);
 | 
					    }, []);
 | 
				
			||||||
| 
						 | 
					@ -205,9 +217,12 @@ export const ConfigDialog: FC<{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // 生成主题
 | 
					    // 生成主题
 | 
				
			||||||
    const generateTheme: () => Promise<Theme<any>> = async () => {
 | 
					    const generateTheme: () => Promise<Theme<any>> = async () => {
 | 
				
			||||||
        const { title, desc, bgm } = customThemeInfo;
 | 
					        const { title, desc, bgm, background, backgroundBlur } =
 | 
				
			||||||
 | 
					            customThemeInfo;
 | 
				
			||||||
        if (bgm && !bgm.startsWith('https'))
 | 
					        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 (!title) return Promise.reject('请填写标题');
 | 
				
			||||||
        if (icons.length !== 10) return Promise.reject('图片素材需要提供10张');
 | 
					        if (icons.length !== 10) return Promise.reject('图片素材需要提供10张');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -235,6 +250,8 @@ export const ConfigDialog: FC<{
 | 
				
			||||||
            title,
 | 
					            title,
 | 
				
			||||||
            desc,
 | 
					            desc,
 | 
				
			||||||
            bgm,
 | 
					            bgm,
 | 
				
			||||||
 | 
					            background,
 | 
				
			||||||
 | 
					            backgroundBlur,
 | 
				
			||||||
            icons: customIcons,
 | 
					            icons: customIcons,
 | 
				
			||||||
            sounds: customSounds,
 | 
					            sounds: customSounds,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
| 
						 | 
					@ -305,6 +322,7 @@ export const ConfigDialog: FC<{
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO HTML有点臭长了,待优化
 | 
				
			||||||
    // @ts-ignore
 | 
					    // @ts-ignore
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <div
 | 
					        <div
 | 
				
			||||||
| 
						 | 
					@ -356,7 +374,7 @@ export const ConfigDialog: FC<{
 | 
				
			||||||
                背景音乐:
 | 
					                背景音乐:
 | 
				
			||||||
                <input
 | 
					                <input
 | 
				
			||||||
                    value={customThemeInfo.bgm}
 | 
					                    value={customThemeInfo.bgm}
 | 
				
			||||||
                    placeholder="可选 https://example.com/src.audioOrImage"
 | 
					                    placeholder="可选 https://example.com/src.audio"
 | 
				
			||||||
                    className="flex-grow"
 | 
					                    className="flex-grow"
 | 
				
			||||||
                    onChange={(e) =>
 | 
					                    onChange={(e) =>
 | 
				
			||||||
                        setCustomThemeInfo({
 | 
					                        setCustomThemeInfo({
 | 
				
			||||||
| 
						 | 
					@ -366,6 +384,35 @@ export const ConfigDialog: FC<{
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                />
 | 
					                />
 | 
				
			||||||
            </h4>
 | 
					            </h4>
 | 
				
			||||||
 | 
					            <h4 className="flex-container flex-center">
 | 
				
			||||||
 | 
					                背景图片:
 | 
				
			||||||
 | 
					                <input
 | 
				
			||||||
 | 
					                    value={customThemeInfo.background}
 | 
				
			||||||
 | 
					                    placeholder="可选 https://example.com/src.image"
 | 
				
			||||||
 | 
					                    className="flex-grow"
 | 
				
			||||||
 | 
					                    onChange={(e) =>
 | 
				
			||||||
 | 
					                        setCustomThemeInfo({
 | 
				
			||||||
 | 
					                            ...customThemeInfo,
 | 
				
			||||||
 | 
					                            background: e.target.value,
 | 
				
			||||||
 | 
					                        })
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                />
 | 
				
			||||||
 | 
					                {customThemeInfo?.background?.startsWith('https') && (
 | 
				
			||||||
 | 
					                    <>
 | 
				
			||||||
 | 
					                        毛玻璃效果:
 | 
				
			||||||
 | 
					                        <input
 | 
				
			||||||
 | 
					                            checked={customThemeInfo.backgroundBlur}
 | 
				
			||||||
 | 
					                            onChange={(e) =>
 | 
				
			||||||
 | 
					                                setCustomThemeInfo({
 | 
				
			||||||
 | 
					                                    ...customThemeInfo,
 | 
				
			||||||
 | 
					                                    backgroundBlur: e.target.checked,
 | 
				
			||||||
 | 
					                                })
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            type="checkbox"
 | 
				
			||||||
 | 
					                        />
 | 
				
			||||||
 | 
					                    </>
 | 
				
			||||||
 | 
					                )}
 | 
				
			||||||
 | 
					            </h4>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <h4>音效素材</h4>
 | 
					            <h4>音效素材</h4>
 | 
				
			||||||
            <div className="flex-container">
 | 
					            <div className="flex-container">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,6 +20,8 @@ export interface Theme<SoundNames> {
 | 
				
			||||||
    desc?: ReactNode;
 | 
					    desc?: ReactNode;
 | 
				
			||||||
    name: string;
 | 
					    name: string;
 | 
				
			||||||
    bgm?: string;
 | 
					    bgm?: string;
 | 
				
			||||||
 | 
					    background?: string;
 | 
				
			||||||
 | 
					    backgroundBlur?: boolean;
 | 
				
			||||||
    pure?: boolean;
 | 
					    pure?: boolean;
 | 
				
			||||||
    icons: Icon<SoundNames>[];
 | 
					    icons: Icon<SoundNames>[];
 | 
				
			||||||
    sounds: Sound<SoundNames>[];
 | 
					    sounds: Sound<SoundNames>[];
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user