feat: add puzzle residence configuration and reflection progress logic
- Introduced `puzzleResidences.ts` to define puzzle residence configurations including properties like display name, position, and puzzle availability. - Added `reflectionProgress.ts` to manage badge unlocking logic based on place completion, including functions to determine unlocked badges and video sources for scenes.
This commit is contained in:
1 parent
e0fa47d21a
commit
f5f36f75b5
153 files changed
+3846
-2352
No files matched your search
@@ -1,9 +1,17 @@
|
||||
import { useCallback, useMemo, useState } from 'react'
|
||||
import { useNavigate, useParams } from 'react-router-dom'
|
||||
import { motion } from 'framer-motion'
|
||||
import { Image, Title, SceneHint, DragFill, ExhibitFlipOverlay } from '@/components'
|
||||
import {
|
||||
Image,
|
||||
Title,
|
||||
SceneHint,
|
||||
DragFill,
|
||||
ExhibitFlipOverlay,
|
||||
FlipActionButton,
|
||||
} from '@/components'
|
||||
import type { DragFillResult } from '@/components'
|
||||
import { cn, getBackgroundImage, getStaticImage } from '@/lib/utils'
|
||||
import { downloadDataUrlImage } from '@/lib/utils/sensitiveWords'
|
||||
import { useZhanglepingStore, saveZhanglepingStore } from '@/store/zhanglepingStore'
|
||||
import { useSceneHintController } from './useSceneHintController'
|
||||
|
||||
@@ -65,8 +73,12 @@ const ZhanglepingReflectionScene5 = () => {
|
||||
const [haloHovered, setHaloHovered] = useState(false)
|
||||
const scene = 'scene5'
|
||||
const total = 1
|
||||
const { markReflectionCursorVisited, getVisitedReflectionCursors, drawArtworkDataUrl } =
|
||||
useZhanglepingStore()
|
||||
const {
|
||||
markReflectionCursorVisited,
|
||||
getVisitedReflectionCursors,
|
||||
drawArtworkDataUrl,
|
||||
hasDrawArtwork,
|
||||
} = useZhanglepingStore()
|
||||
|
||||
// 根据 store 中碎片是否已解锁决定初始子场景
|
||||
const fragmentAlreadyUnlocked = getVisitedReflectionCursors(scene).includes(1)
|
||||
@@ -79,8 +91,9 @@ const ZhanglepingReflectionScene5 = () => {
|
||||
const completed = progressCount >= total
|
||||
const subtitle = completed ? '已完成' : `${Math.min(progressCount, total)}/${total}`
|
||||
const hasSubmittedArtwork =
|
||||
typeof drawArtworkDataUrl === 'string' &&
|
||||
/^data:image\/[a-zA-Z]+;base64,/.test(drawArtworkDataUrl)
|
||||
hasDrawArtwork ||
|
||||
(typeof drawArtworkDataUrl === 'string' &&
|
||||
/^data:image\/[a-zA-Z]+;base64,/.test(drawArtworkDataUrl))
|
||||
|
||||
// 子场景2:拖拽状态
|
||||
const [dragFillValue, setDragFillValue] = useState<DragFillResult[]>([])
|
||||
@@ -155,6 +168,16 @@ const ZhanglepingReflectionScene5 = () => {
|
||||
setTimeout(() => setSubScene(3), 800)
|
||||
}, [])
|
||||
|
||||
const handleDownloadArtwork = useCallback(async () => {
|
||||
if (!hasSubmittedArtwork) return
|
||||
|
||||
try {
|
||||
await downloadDataUrlImage(drawArtworkDataUrl, '三毛新时代图景.png')
|
||||
} catch (error) {
|
||||
console.error('Download artwork failed', error)
|
||||
}
|
||||
}, [drawArtworkDataUrl, hasSubmittedArtwork])
|
||||
|
||||
if (!moduleName) return null
|
||||
|
||||
const subSceneBg = { 1: '场景5', 2: '邮箱', 3: '画板' }[subScene]
|
||||
@@ -372,15 +395,26 @@ const ZhanglepingReflectionScene5 = () => {
|
||||
|
||||
{/* 画板模块提交的画作(无画作时不显示空白画板) */}
|
||||
{hasSubmittedArtwork && (
|
||||
<div
|
||||
className={cn(
|
||||
'absolute left-40 top-178 w-[205px] h-[180px] transform-3d',
|
||||
'bg-white flex justify-center items-center overflow-hidden'
|
||||
)}
|
||||
style={{ transform: 'rotateX(-15deg) rotateY(22deg) rotateZ(3deg)' }}
|
||||
>
|
||||
<Image objectFit="cover" src={drawArtworkDataUrl} />
|
||||
</div>
|
||||
<>
|
||||
<div
|
||||
className={cn(
|
||||
'absolute left-40 top-178 w-[205px] h-[180px] transform-3d',
|
||||
'bg-white flex justify-center items-center overflow-hidden'
|
||||
)}
|
||||
style={{ transform: 'rotateX(-15deg) rotateY(22deg) rotateZ(3deg)' }}
|
||||
>
|
||||
<Image objectFit="cover" src={drawArtworkDataUrl} />
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="absolute left-62 top-[900px] z-20"
|
||||
style={{ transform: 'rotateX(-15deg) rotateY(22deg) rotateZ(3deg)' }}
|
||||
>
|
||||
<FlipActionButton className="text-2xl px-5 py-2" onClick={handleDownloadArtwork}>
|
||||
下载
|
||||
</FlipActionButton>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
Reference in new issue
Block a user