diff --git a/public/wxQrcode1.jpg b/public/wxQrcode1.jpg new file mode 100644 index 0000000..fc37010 Binary files /dev/null and b/public/wxQrcode1.jpg differ diff --git a/public/wxQrcode5.jpg b/public/wxQrcode5.jpg new file mode 100644 index 0000000..eac6395 Binary files /dev/null and b/public/wxQrcode5.jpg differ diff --git a/public/wxQrcode8.jpg b/public/wxQrcode8.jpg new file mode 100644 index 0000000..585c06d Binary files /dev/null and b/public/wxQrcode8.jpg differ diff --git a/public/wxqrcode.png b/public/wxqrcode.png deleted file mode 100644 index c696f9a..0000000 Binary files a/public/wxqrcode.png and /dev/null differ diff --git a/src/App.tsx b/src/App.tsx index 0e3ce6d..54fb4a9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -15,6 +15,7 @@ import { PersonalInfo } from './components/PersonalInfo'; import { Info } from './components/Info'; const ThemeChanger = React.lazy(() => import('./components/ThemeChanger')); const ConfigDialog = React.lazy(() => import('./components/ConfigDialog')); +const WxQrCode = React.lazy(() => import('./components/WxQrCode')); // 读取缓存关卡得分 const initLevel = Number(localStorage.getItem(LAST_LEVEL_STORAGE_KEY) || '1'); @@ -74,7 +75,10 @@ const App: FC<{ theme: Theme }> = ({ theme: initTheme }) => { initTime={initTime} /> -
+
+ Loading}> + {!__DIY__ && } + {!__DIY__ && (

= ({ fill }) => { + return ( + + + + ); +}; diff --git a/src/components/FixedAnimateScalePanel.tsx b/src/components/FixedAnimateScalePanel.tsx index 71c1d13..c0d7e44 100644 --- a/src/components/FixedAnimateScalePanel.tsx +++ b/src/components/FixedAnimateScalePanel.tsx @@ -1,6 +1,7 @@ import React, { FC, ReactNode, useState } from 'react'; import style from './FixedAnimateScalePanel.module.scss'; import classNames from 'classnames'; +import { CloseIcon } from './CloseIcon'; export const FixedAnimateScalePanel: FC<{ children: ReactNode; @@ -28,20 +29,7 @@ export const FixedAnimateScalePanel: FC<{ > {children}

setOpen(false)}> - - - +
); diff --git a/src/components/Game.scss b/src/components/Game.scss index 7b253a5..0a72322 100644 --- a/src/components/Game.scss +++ b/src/components/Game.scss @@ -107,7 +107,8 @@ .level { font-size: 1.5em; font-weight: 900; - line-height: 2; + line-height: 1.4; + padding: 12px 0; text-shadow: 4px 6px 2px rgb(0 0 0 / 20%); font-family: Menlo, Monaco, 'Courier New', monospace, serif; } diff --git a/src/components/ThemeChanger.module.scss b/src/components/ThemeChanger.module.scss index 0961501..651ff06 100644 --- a/src/components/ThemeChanger.module.scss +++ b/src/components/ThemeChanger.module.scss @@ -45,16 +45,16 @@ } } - .diy{ + .diy { width: 52px; font-weight: 900; font-size: 18px; background-image: linear-gradient( - 45deg, - #ee7752, - #e73c7e, - #23a6d5, - #23d5ab + 45deg, + #ee7752, + #e73c7e, + #23a6d5, + #23d5ab ); background-size: 400% 400%; background-position: 0 0; @@ -68,3 +68,26 @@ } } } + +.adv { + position: fixed; + right: 8px; + bottom: 8px; + transition: 0.5s; + height: 250px; + backdrop-filter: blur(10px); + border-radius: 8px; + background-color: rgb(0 0 0 / 30%); + transform-origin: right bottom; + display: flex; + align-items: center; + box-sizing: border-box; + padding: 8px; + + @media screen and (max-width: 500px) { + width: calc(100vw - 16px); + } + @media screen and (min-width: 501px) { + width: 500px; + } +} diff --git a/src/components/ThemeChanger.tsx b/src/components/ThemeChanger.tsx index d4856fb..42abf80 100644 --- a/src/components/ThemeChanger.tsx +++ b/src/components/ThemeChanger.tsx @@ -7,6 +7,7 @@ import { ikunTheme } from '../themes/ikun'; import { pddTheme } from '../themes/pdd'; import { getDefaultTheme } from '../themes/default'; import { Theme } from '../themes/interface'; +import WxQrCode from './WxQrCode'; const BuiltinThemes = [ getDefaultTheme(), @@ -22,57 +23,71 @@ const ThemeChanger: FC<{ }> = ({ changeTheme, onDiyClick }) => { const [open, setOpen] = useState(false); return ( -
- {BuiltinThemes.map((theme, idx) => ( + <> +
+ {BuiltinThemes.map((theme, idx) => ( +
{ + setOpen(false); + changeTheme(theme); + }} + > + {typeof theme.icons[0].content === 'string' ? ( + theme.icons[0].content.startsWith('http') ? ( + /*图片外链*/ + + ) : ( + /*字符表情*/ + {theme.icons[0].content} + ) + ) : ( + /*ReactNode*/ + theme.icons[0].content + )} +
+ ))}
{ setOpen(false); - changeTheme(theme); + onDiyClick(); + }} + style={{ + transform: open + ? `translateY(-${110 * 6}%)` + : 'translateX(-110%)', }} > - {typeof theme.icons[0].content === 'string' ? ( - theme.icons[0].content.startsWith('http') ? ( - /*图片外链*/ - - ) : ( - /*字符表情*/ - {theme.icons[0].content} - ) - ) : ( - /*ReactNode*/ - theme.icons[0].content - )} + {open ? '点我整活' : 'DIY!'}
- ))} + +
setOpen(!open)} + className={classNames(style.square)} + > + {open ? '收起' : '更多'} +
+
{ - setOpen(false); - onDiyClick(); - }} + className={style.adv} style={{ + opacity: open ? 1 : 0.3, transform: open - ? `translateY(-${110 * 6}%)` - : 'translateX(-110%)', + ? `translateY(-400px) scale(1)` + : 'translateY(0) scale(0)', }} > - {open ? '点我整活' : 'DIY!'} +
-
setOpen(!open)} - className={classNames(style.square)} - > - {open ? '收起' : '更多'} -
-
+ ); }; diff --git a/src/components/WxQrCode.module.scss b/src/components/WxQrCode.module.scss new file mode 100644 index 0000000..9e5c7c9 --- /dev/null +++ b/src/components/WxQrCode.module.scss @@ -0,0 +1,63 @@ +.wxQrCode { + &Container { + display: flex; + gap: 16px; + flex-wrap: wrap; + padding: 12px; + border-radius: 12px; + border: 1px solid currentcolor; + } + + &Title { + opacity: 0.8; + width: 100%; + } + + &Item { + display: flex; + flex: 1 1 0; + gap: 12px; + flex-direction: column; + align-items: center; + transition: 0.3s; + + &Title { + font-weight: 600; + font-size: 16px; + } + + &Image { + width: 100%; + transition: 0.3s; + cursor: pointer; + z-index: 1; + transform-origin: bottom; + + &:hover { + z-index: 10; + transform: scale(1.1); + box-shadow: 0 19px 38px rgb(0 0 0 / 30%), + 0 15px 12px rgb(0 0 0 / 22%); + } + } + + &.fullScreen .wxQrCodeItemImage { + z-index: 10; + transform: scale(3); + box-shadow: 0 19px 38px rgb(0 0 0 / 30%), + 0 15px 12px rgb(0 0 0 / 22%); + } + + &:nth-child(2).fullScreen .wxQrCodeItemImage { + transform-origin: left bottom; + } + + &:nth-child(3).fullScreen .wxQrCodeItemImage { + transform-origin: center bottom; + } + + &:nth-child(4).fullScreen .wxQrCodeItemImage { + transform-origin: right bottom; + } + } +} diff --git a/src/components/WxQrCode.tsx b/src/components/WxQrCode.tsx new file mode 100644 index 0000000..6100e59 --- /dev/null +++ b/src/components/WxQrCode.tsx @@ -0,0 +1,54 @@ +import React, { FC, useState } from 'react'; +import style from './WxQrCode.module.scss'; +import classNames from 'classnames'; +const WxQrCode: FC<{ title?: string }> = ({ + title = '【广告位招租中】同时如果您喜欢这个项目的话,可以点击扫描下方收款码分摊后台相关费用,感谢~😘', +}) => { + const [fullScreen, setFullScreen] = useState>({ + 0: false, + 1: false, + 2: false, + }); + const onImageClick = (idx: number) => { + setFullScreen({ + 0: false, + 1: false, + 2: false, + [idx]: !fullScreen[idx], + }); + const clickListener: EventListener = (e) => { + // @ts-ignore + if (e.target?.className !== style.wxQrCodeItemImage) { + setFullScreen({ 0: false, 1: false, 2: false }); + } + window.removeEventListener('click', clickListener); + }; + setTimeout(() => { + window.addEventListener('click', clickListener); + }); + }; + return ( +
+
{title}
+ {[1, 5, 8].map((num, idx) => ( +
+ ¥ {num} + {''} onImageClick(idx)} + /> +
+ ))} +
+ ); +}; + +export default WxQrCode; diff --git a/src/utils.ts b/src/utils.ts index a167f38..0f5e1ab 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -5,6 +5,7 @@ export const LAST_LEVEL_STORAGE_KEY = 'lastLevel'; export const LAST_SCORE_STORAGE_KEY = 'lastScore'; export const LAST_TIME_STORAGE_KEY = 'lastTime'; export const LAST_UPLOAD_TIME_STORAGE_KEY = 'lastUploadTime'; +export const CUSTOM_THEME_STORAGE_KEY = 'customTheme'; export const DEFAULT_BGM_STORAGE_KEY = 'defaultBgm'; export const DEFAULT_TRIPLE_SOUND_STORAGE_KEY = 'defaultTripleSound'; export const DEFAULT_CLICK_SOUND_STORAGE_KEY = 'defaultClickSound';