feat(game): 重构游戏组件并新增自动设置模态框
- 将多个组件中的背景图片样式替换为 SmartBackground 组件 - 在 CenterModal 中新增 isShowClose 属性控制关闭按钮显示 - 新增 DesktopAutoSettingModal 组件实现自动设置功能 - 新增 DesktopProceduresModal 和 DesktopWithdrawTopupModal 组件 - 配置 shadcn/ui 并集成 Geist 字体和动画库 - 更新 CSS 样式添加暗色主题变量和输入框样式 - 修复 utils 导入路径错误问题
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { SmartImage } from '@/components/smart-image'
|
||||
import { cn } from '@/lib/untils'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
const animalModules = import.meta.glob('../../../../assets/animal/*.webp', {
|
||||
eager: true,
|
||||
|
||||
@@ -9,9 +9,10 @@ import controlBg from '@/assets/game/control-bg.png'
|
||||
import leftBottomBg from '@/assets/game/left-bg.webp'
|
||||
import reduce from '@/assets/game/reduce.webp'
|
||||
import totalBg from '@/assets/game/total-bg.webp'
|
||||
import { SmartBackground } from '@/components/smart-background.tsx'
|
||||
import { SmartImage } from '@/components/smart-image.tsx'
|
||||
import { ACTION_OPTIONS, CHIP_OPTIONS } from '@/constants'
|
||||
import { cn } from '@/lib/untils.ts'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
export function DesktopControl() {
|
||||
const [chips, setChips] = useState(CHIP_OPTIONS)
|
||||
@@ -66,14 +67,12 @@ export function DesktopControl() {
|
||||
'flex h-design-100 w-full items-center gap-design-12 overflow-hidden'
|
||||
}
|
||||
>
|
||||
<div
|
||||
<SmartBackground
|
||||
src={leftBottomBg}
|
||||
size="100% 100%"
|
||||
className={
|
||||
'flex flex-col items-center gap-1 justify-center h-full w-design-110 shrink-0 bg-center bg-no-repeat'
|
||||
}
|
||||
style={{
|
||||
backgroundImage: `url(${leftBottomBg})`,
|
||||
backgroundSize: '100% 100%',
|
||||
}}
|
||||
>
|
||||
<div className={'flex flex-col items-center justify-center'}>
|
||||
<div>TREBD</div>
|
||||
@@ -84,21 +83,17 @@ export function DesktopControl() {
|
||||
alt={`animal`}
|
||||
className={'w-design-20 h-design-10'}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
</SmartBackground>
|
||||
<SmartBackground
|
||||
src={chipBg}
|
||||
size="100% 100%"
|
||||
className={
|
||||
'desktop-control-chip relative z-10 flex h-full w-design-710 shrink-0 items-center gap-design-10 pl-design-20 pr-design-40 bg-center bg-no-repeat'
|
||||
}
|
||||
style={{
|
||||
backgroundImage: `url(${chipBg})`,
|
||||
backgroundSize: '100% 100%',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
backgroundImage: `url(${chipLineBg})`,
|
||||
backgroundSize: '100% 100%',
|
||||
}}
|
||||
<SmartBackground
|
||||
src={chipLineBg}
|
||||
size="100% 100%"
|
||||
className={
|
||||
'flex min-w-0 flex-1 items-center gap-design-10 overflow-visible'
|
||||
}
|
||||
@@ -215,7 +210,7 @@ export function DesktopControl() {
|
||||
</motion.button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</SmartBackground>
|
||||
|
||||
<div
|
||||
className={
|
||||
@@ -238,27 +233,23 @@ export function DesktopControl() {
|
||||
className={'w-design-40 h-design-40'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
</SmartBackground>
|
||||
<SmartBackground
|
||||
src={totalBg}
|
||||
size="100% 100%"
|
||||
className={
|
||||
'desktop-control-total relative flex flex-col items-center justify-center z-10 h-full w-design-435 shrink-0 bg-center bg-no-repeat'
|
||||
}
|
||||
style={{
|
||||
backgroundImage: `url(${totalBg})`,
|
||||
backgroundSize: '100% 100%',
|
||||
}}
|
||||
>
|
||||
<div>SELECTED:3/5</div>
|
||||
<div>Total Bet:150</div>
|
||||
</div>
|
||||
<div
|
||||
</SmartBackground>
|
||||
<SmartBackground
|
||||
src={controlBg}
|
||||
size="100% 100%"
|
||||
className={cn(
|
||||
'desktop-control-actions relative z-10 flex h-full w-design-385 shrink-0 items-center bg-center bg-no-repeat pl-design-15',
|
||||
)}
|
||||
style={{
|
||||
backgroundImage: `url(${controlBg})`,
|
||||
backgroundSize: '100% 100%',
|
||||
}}
|
||||
>
|
||||
{ACTION_OPTIONS.map(({ id, label, Icon, bg }) => {
|
||||
const isClicked = clickedId === id
|
||||
@@ -278,25 +269,25 @@ export function DesktopControl() {
|
||||
)}
|
||||
>
|
||||
{showBg && (
|
||||
<motion.span
|
||||
<SmartBackground
|
||||
as={motion.span}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={isClicked ? { opacity: 1 } : { opacity: 0 }}
|
||||
transition={{
|
||||
duration: isClicked ? 0.15 : 0.18,
|
||||
ease: 'easeOut',
|
||||
}}
|
||||
src={bg}
|
||||
className={cn(
|
||||
'pointer-events-none absolute bg-center inset-0 bg-no-repeat h-design-100',
|
||||
)}
|
||||
style={{
|
||||
backgroundImage: `url(${bg})`,
|
||||
backgroundSize:
|
||||
id === 'clear'
|
||||
? '110% 90%'
|
||||
: id === 'repeat'
|
||||
? '98% 80%'
|
||||
: '96% 80%',
|
||||
}}
|
||||
size={
|
||||
id === 'clear'
|
||||
? '110% 90%'
|
||||
: id === 'repeat'
|
||||
? '98% 80%'
|
||||
: '96% 80%'
|
||||
}
|
||||
/>
|
||||
)}
|
||||
<motion.div
|
||||
@@ -331,8 +322,11 @@ export function DesktopControl() {
|
||||
</motion.button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
<motion.button
|
||||
</SmartBackground>
|
||||
<SmartBackground
|
||||
as={motion.button}
|
||||
src={confirmBg}
|
||||
size="100% 100%"
|
||||
type="button"
|
||||
onClick={handleConfirmClick}
|
||||
whileHover={{ scale: 1.01 }}
|
||||
@@ -340,22 +334,17 @@ export function DesktopControl() {
|
||||
className={cn(
|
||||
'relative z-10 h-full w-design-260 shrink-0 cursor-pointer bg-center bg-no-repeat flex items-center justify-center text-design-32 font-bold',
|
||||
)}
|
||||
style={{
|
||||
backgroundImage: `url(${confirmBg})`,
|
||||
backgroundSize: '100% 100%',
|
||||
}}
|
||||
>
|
||||
{confirmClicked && (
|
||||
<motion.span
|
||||
<SmartBackground
|
||||
as={motion.span}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.15 }}
|
||||
className="pointer-events-none absolute inset-0 bg-center bg-no-repeat"
|
||||
style={{
|
||||
backgroundImage: `url(${confirmBg})`,
|
||||
backgroundSize: '100% 100%',
|
||||
}}
|
||||
src={confirmBg}
|
||||
size="100% 100%"
|
||||
/>
|
||||
)}
|
||||
<motion.span
|
||||
@@ -365,7 +354,7 @@ export function DesktopControl() {
|
||||
>
|
||||
confirm
|
||||
</motion.span>
|
||||
</motion.button>
|
||||
</SmartBackground>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import dayjs from 'dayjs'
|
||||
import duration from 'dayjs/plugin/duration'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { cn } from '@/lib/untils'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
dayjs.extend(duration)
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import historyBg from '@/assets/system/history-bg.png'
|
||||
import { SmartBackground } from '@/components/smart-background.tsx'
|
||||
|
||||
export function DesktopGameHistory() {
|
||||
const data = [
|
||||
@@ -115,12 +116,10 @@ export function DesktopGameHistory() {
|
||||
]
|
||||
|
||||
return (
|
||||
<div
|
||||
<SmartBackground
|
||||
src={historyBg}
|
||||
size="100% 100%"
|
||||
className="desktop-game-history-glow flex h-full min-h-0 w-full flex-col items-center overflow-hidden bg-center bg-no-repeat py-2"
|
||||
style={{
|
||||
backgroundImage: `url(${historyBg})`,
|
||||
backgroundSize: '100% 100%',
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={
|
||||
@@ -178,6 +177,6 @@ export function DesktopGameHistory() {
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</SmartBackground>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
import statusCenter from '@/assets/system/status-center.webp'
|
||||
import statusLine from '@/assets/system/status-line.webp'
|
||||
import { SmartBackground } from '@/components/smart-background.tsx'
|
||||
import { DesktopCountdown } from '@/features/game/components/desktop/desktop-countdown.tsx'
|
||||
import { DesktopTitle } from '@/features/game/components/desktop/desktop-title.tsx'
|
||||
|
||||
export function DesktopStatusLine() {
|
||||
return (
|
||||
<div className={'relative w-full flex flex-col text-design-22'}>
|
||||
<div
|
||||
<SmartBackground
|
||||
src={statusLine}
|
||||
size="100% 100%"
|
||||
className="w-full h-design-60 bg-no-repeat bg-center flex items-center justify-center"
|
||||
style={{
|
||||
backgroundImage: `url(${statusLine})`,
|
||||
backgroundSize: '100% 100%',
|
||||
}}
|
||||
>
|
||||
<div className={'flex-1 flex items-center justify-center'}>
|
||||
<div>Odds: 1:33</div>
|
||||
<div>Streak: X2</div>
|
||||
<div>Limit: 100</div>
|
||||
</div>
|
||||
<div
|
||||
<SmartBackground
|
||||
src={statusCenter}
|
||||
className="w-design-360 h-[105px] font-countdown bg-no-repeat bg-center bg-contain flex items-center justify-center"
|
||||
style={{ backgroundImage: `url(${statusCenter})` }}
|
||||
size="contain"
|
||||
>
|
||||
<DesktopCountdown
|
||||
initialSeconds={30}
|
||||
@@ -28,7 +28,7 @@ export function DesktopStatusLine() {
|
||||
console.log('countdown finished')
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</SmartBackground>
|
||||
<div className={'flex-1 flex items-center justify-center gap-10'}>
|
||||
<div>Round ID:20241026120</div>
|
||||
<div className={'flex items-center gap-2'}>
|
||||
@@ -41,7 +41,7 @@ export function DesktopStatusLine() {
|
||||
<div>(Menerima Taruhan)</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</SmartBackground>
|
||||
<div
|
||||
className={
|
||||
'absolute top-design-60 left-1/2 -translate-x-1/2 -z-10 w-full px-design-16'
|
||||
|
||||
5
src/features/game/components/desktop/desktop-topup.tsx
Normal file
5
src/features/game/components/desktop/desktop-topup.tsx
Normal file
@@ -0,0 +1,5 @@
|
||||
function DesktopTopup() {
|
||||
return <div>DesktopTopup</div>
|
||||
}
|
||||
|
||||
export default DesktopTopup
|
||||
@@ -0,0 +1,5 @@
|
||||
function DesktopWithdraw() {
|
||||
return <div>DesktopWithdraw</div>
|
||||
}
|
||||
|
||||
export default DesktopWithdraw
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
import { cn } from '@/lib/untils'
|
||||
import { cn } from '@/lib/utils'
|
||||
|
||||
type GameTone = 'neutral' | 'brand' | 'success' | 'warning' | 'danger'
|
||||
|
||||
|
||||
Reference in New Issue
Block a user