feat:修改英文双引号
This commit is contained in:
commit
4a2be3b4d0
1351 files changed
+56547
No files matched your search
@@ -0,0 +1,342 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useNavigate, useParams } from 'react-router-dom'
|
||||
import { Image, StudyGuideModal } from '@/components'
|
||||
import SuccessAlert from '@/components/layout/alert/success-alert'
|
||||
import { getBackgroundImage, getPublicPath, getStaticImage } from '@/lib/utils'
|
||||
import { usePuzzleAnimation } from '@/contexts/PuzzleAnimationContext'
|
||||
import { useLuxunStore, saveLuxunStore } from '@/store/luxunStore'
|
||||
|
||||
const starName = 'luxun'
|
||||
|
||||
// 城市配置 - 根据效果图调整位置
|
||||
// 布局:北京(上) -> 上海(中上) -> 绍兴(中) -> 广州(左下) -> 厦门(右下)
|
||||
const cityConfig = [
|
||||
{
|
||||
id: 1,
|
||||
name: '绍兴',
|
||||
location: '绍兴三味书屋',
|
||||
imagePath: 'luxun/reflection/scene1/绍兴',
|
||||
position: { top: '65%', left: '65%' }, // 中间
|
||||
iconPosition: { top: '0%', left: '0%' },
|
||||
time: '1892年-1898年',
|
||||
description: '少年鲁迅在此求学,为《从百草园到三味书屋》埋下创作种子。',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '北京',
|
||||
location: '北京八道湾胡同',
|
||||
imagePath: 'luxun/reflection/scene1/北京',
|
||||
position: { top: '14%', left: '62%' }, // 顶部
|
||||
iconPosition: { top: '43%', left: '0%' },
|
||||
time: '1919-1923年',
|
||||
description: '鲁迅参与新文化运动的核心时期,《阿Q正传》等经典作品在此酝酿创作。',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '厦门',
|
||||
location: '厦门大学',
|
||||
imagePath: 'luxun/reflection/scene1/厦门',
|
||||
position: { top: '83%', left: '78%' }, // 右下
|
||||
iconPosition: { top: '16%', left: '40%' },
|
||||
time: '1926年9-12月',
|
||||
description: '鲁迅应邀前往厦门大学任教,期间写下多篇批判现实的杂文,关注底层民众命运。',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '广州',
|
||||
location: '广州白云楼',
|
||||
imagePath: 'luxun/reflection/scene1/广州',
|
||||
position: { top: '88%', left: '35%' }, // 左下
|
||||
iconPosition: { top: '16%', left: '30%' },
|
||||
time: '1927年3-9月',
|
||||
description: '先生在此整理旧作,思考民族觉醒之路,《朝花夕拾》部分篇章定稿于此。',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '上海',
|
||||
location: '上海鲁迅故居',
|
||||
imagePath: 'luxun/reflection/scene1/上海',
|
||||
position: { top: '48%', left: '70%' }, // 中上
|
||||
iconPosition: { top: '0%', left: '0%' },
|
||||
time: '1933-1936年',
|
||||
description:
|
||||
'鲁迅晚年定居地,先生在此写下《故事新编》等作品,与进步文人并肩,以文字为刃批判黑暗。',
|
||||
},
|
||||
]
|
||||
|
||||
const LuxunReflectionScene1 = () => {
|
||||
const navigate = useNavigate()
|
||||
const { moduleName } = useParams<{
|
||||
moduleName: string
|
||||
}>()
|
||||
|
||||
//碎片动画触发方法
|
||||
const { triggerPuzzleAnimation } = usePuzzleAnimation()
|
||||
const { setReflectionRoute } = useLuxunStore()
|
||||
|
||||
// 已点击的城市ID集合
|
||||
const [clickedCities, setClickedCities] = useState<Set<number>>(new Set())
|
||||
// 是否显示成功提示(全部完成时)
|
||||
const [showSuccessAlert, setShowSuccessAlert] = useState(false)
|
||||
// 当前显示的城市提示ID(单个地点点击后)
|
||||
const [currentCityAlertId, setCurrentCityAlertId] = useState<number | null>(null)
|
||||
// 是否全部完成
|
||||
const [allCompleted, setAllCompleted] = useState(false)
|
||||
// 学习引导对话是否显示
|
||||
const [showGuideModal, setShowGuideModal] = useState(true)
|
||||
|
||||
const progress = clickedCities.size
|
||||
// 当前应当点亮的城市索引(按照 cityConfig 顺序)
|
||||
const nextCityIndex = progress
|
||||
const nextCityId = cityConfig[nextCityIndex]?.id
|
||||
const totalTasks = cityConfig.length
|
||||
|
||||
// 检查是否全部完成
|
||||
useEffect(() => {
|
||||
if (progress === totalTasks && !allCompleted) {
|
||||
setAllCompleted(true)
|
||||
}
|
||||
}, [progress, totalTasks, allCompleted])
|
||||
|
||||
const handleCityClick = (cityId: number) => {
|
||||
// 仅允许按照 cityConfig 顺序点击
|
||||
if (clickedCities.has(cityId)) return // 已点击过的不再处理
|
||||
if (cityId !== nextCityId) return // 不是当前应点击的城市则不响应
|
||||
|
||||
setClickedCities((prev) => {
|
||||
const next = new Set(prev)
|
||||
next.add(cityId)
|
||||
return next
|
||||
})
|
||||
|
||||
// 显示当前城市的成功提示
|
||||
setCurrentCityAlertId(cityId)
|
||||
}
|
||||
|
||||
const handleSuccessAlertClose = () => {
|
||||
setShowSuccessAlert(false)
|
||||
}
|
||||
|
||||
const handleCityAlertClose = () => {
|
||||
const cityId = currentCityAlertId
|
||||
setCurrentCityAlertId(null)
|
||||
|
||||
// 如果关闭的是最后一个城市(上海鲁迅故居,id=5),则显示全部完成的提示
|
||||
const lastCity = cityConfig[cityConfig.length - 1]
|
||||
if (lastCity && cityId === lastCity.id) {
|
||||
triggerPuzzleAnimation(14)
|
||||
setShowSuccessAlert(true)
|
||||
}
|
||||
}
|
||||
|
||||
// 获取当前显示的城市信息
|
||||
const currentCity = currentCityAlertId
|
||||
? cityConfig.find((city) => city.id === currentCityAlertId)
|
||||
: null
|
||||
|
||||
return (
|
||||
<div
|
||||
className="flex justify-between w-full h-full bg-cover bg-center bg-no-repeat gap-8 relative"
|
||||
style={{
|
||||
backgroundImage: getBackgroundImage(`${starName}/reflection/scene1/底图`),
|
||||
}}
|
||||
>
|
||||
{/* 离开按钮 */}
|
||||
<Image
|
||||
className="absolute right-5 top-5 z-10"
|
||||
src={getStaticImage(`${starName}/reflection/scene1/离开`)}
|
||||
button
|
||||
onClick={() => {
|
||||
if (moduleName && starName) {
|
||||
navigate(`/${moduleName}/${starName}/home`)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 左侧:鲁迅的文学足迹 - 地图区域 */}
|
||||
<div className="w-[45%] relative">
|
||||
{/* 地图容器 */}
|
||||
<div className="relative w-full h-full">
|
||||
{cityConfig.map((city) => {
|
||||
const isClicked = clickedCities.has(city.id)
|
||||
const isNext = city.id === nextCityId
|
||||
return (
|
||||
<div
|
||||
key={city.id}
|
||||
className="absolute flex flex-col items-center cursor-pointer hover:scale-110 transition-all duration-300"
|
||||
style={{
|
||||
top: city.position.top,
|
||||
left: city.position.left,
|
||||
transform: 'translate(-50%, -50%)',
|
||||
}}
|
||||
onClick={() => handleCityClick(city.id)}
|
||||
>
|
||||
{/* 城市图片容器 */}
|
||||
<div className="relative">
|
||||
<img
|
||||
src={getStaticImage(city.imagePath)}
|
||||
alt={city.name}
|
||||
className={`transition-all duration-300 ${
|
||||
isClicked ? 'brightness-100' : 'brightness-50 grayscale'
|
||||
}`}
|
||||
style={{
|
||||
filter: isClicked ? 'none' : 'grayscale(100%) brightness(0.5)',
|
||||
}}
|
||||
/>
|
||||
|
||||
{/* 点击图标和提示 - 覆盖在城市图片上 */}
|
||||
<div
|
||||
className="absolute -translate-x-full -translate-y-full flex flex-col items-center z-10 pointer-events-none"
|
||||
style={{
|
||||
left: city.iconPosition.left,
|
||||
top: city.iconPosition.top,
|
||||
}}
|
||||
>
|
||||
{/* 点一点提示 - 始终显示 */}
|
||||
{/* 仅对当前应点击的城市显示点一点提示 */}
|
||||
{!isClicked && isNext && (
|
||||
<div className="flex items-center">
|
||||
<img
|
||||
src={getStaticImage(`${starName}/reflection/scene1/鲁迅体悟改版点一点`)}
|
||||
alt="点一点"
|
||||
/>
|
||||
<img
|
||||
className="animate-finger-bounce scale-y-[-1]"
|
||||
src={getStaticImage(`${starName}/reflection/scene1/鲁迅体悟点一点图标`)}
|
||||
alt="点一点图标"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 导航栏 */}
|
||||
<div className="absolute top-5 left-[37%] w-80 space-y-4 z-99">
|
||||
{/* 任务1点亮图标 */}
|
||||
<div className="text-4xl font-bold h-16 cursor-pointer"></div>
|
||||
{/* 任务2漫集美学 */}
|
||||
<div
|
||||
className="text-4xl font-bold h-16 cursor-pointer relative"
|
||||
onClick={() => {
|
||||
if (moduleName && allCompleted) {
|
||||
setReflectionRoute('reflection2')
|
||||
saveLuxunStore()
|
||||
navigate(`/${moduleName}/${starName}/reflection2`)
|
||||
}
|
||||
}}
|
||||
>
|
||||
{/* 任务完成后显示点一点图标 */}
|
||||
{allCompleted && (
|
||||
<div className="absolute -right-20 top-1/2 flex items-center gap-2 z-10 pointer-events-none">
|
||||
<img
|
||||
className="animate-finger-bounce scale-x-[-1]"
|
||||
src={getStaticImage(`${starName}/reflection/scene1/鲁迅体悟点一点图标`)}
|
||||
alt="点一点图标"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
{/* 任务3学习精神 */}
|
||||
<div className="text-4xl font-bold h-16 cursor-pointer"></div>
|
||||
</div>
|
||||
|
||||
{/* 右侧区域 */}
|
||||
<div className="flex-1 relative">
|
||||
{/* 任务进度 */}
|
||||
<div className="absolute top-5 left-[24%] w-[445px] h-55 flex justify-center items-center">
|
||||
<span className="text-white text-[54px] font-bold [text-shadow:_0px_0px_4px_#b37921,_6px_6px_4px_#b37921,_6px_6px_4px_#b37921,_6px_6px_4px_#b37921]">
|
||||
{allCompleted ? '任务进度已完成' : `任务进度:(${progress}/${totalTasks})`}
|
||||
</span>
|
||||
</div>
|
||||
{/* 任务展示窗口 */}
|
||||
<div className="absolute bottom-0 right-7 w-[995px] h-[728px] font-bold text-6xl px-10 py-10 ">
|
||||
{allCompleted ? (
|
||||
// 全部完成后显示详细信息
|
||||
<div className="space-y-10 h-full overflow-y-auto custom-scrollbar">
|
||||
{cityConfig.map((city) => (
|
||||
<div key={city.id} className="space-y-2">
|
||||
<div className="text-red-600 text-3xl flex items-end gap-6">
|
||||
<div>{city.location}</div>
|
||||
<div className="text-gray-600 text-2xl font-normal">{city.time}</div>
|
||||
</div>
|
||||
<div className="text-black text-2xl font-normal leading-relaxed">
|
||||
{city.description}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="space-y-16">
|
||||
{
|
||||
// 未完成时显示任务列表
|
||||
cityConfig.map((city, index) => {
|
||||
const isCompleted = clickedCities.has(city.id)
|
||||
return (
|
||||
<div key={city.id} className={isCompleted ? 'text-green-600' : ''}>
|
||||
{index + 1}.{city.location}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 单个地点点击成功提示弹窗 */}
|
||||
{currentCity && (
|
||||
<SuccessAlert
|
||||
visible={true}
|
||||
title=""
|
||||
// title={`你找到了${currentCity.location}!`}
|
||||
content={`${currentCity.time},\n${currentCity.description}`}
|
||||
onClose={handleCityAlertClose}
|
||||
onContinue={handleCityAlertClose}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 全部完成成功提示弹窗 */}
|
||||
<SuccessAlert
|
||||
visible={showSuccessAlert}
|
||||
title="你找到了鲁迅创作的足迹,接下来,填充文字里的故事吧!"
|
||||
onClose={handleSuccessAlertClose}
|
||||
onContinue={handleSuccessAlertClose}
|
||||
/>
|
||||
{/* 学习引导对话 */}
|
||||
{/* <GuideSteps
|
||||
visible={guideVisible}
|
||||
onVisibleChange={setGuideVisible}
|
||||
showMask={false}
|
||||
highlightSelectors={[]}
|
||||
zIndex={10000}
|
||||
>
|
||||
<GuideStepsItem speaker="guide">
|
||||
跟着先生的脚步, 解锁文字里的温度与力量!
|
||||
</GuideStepsItem>
|
||||
<GuideStepsItem speaker="guide">
|
||||
请根据年代由远及近的顺序,依“手指提示”点亮先生的创作足迹,解锁更多的故事背景!
|
||||
</GuideStepsItem>
|
||||
</GuideSteps> */}
|
||||
<StudyGuideModal
|
||||
visible={showGuideModal}
|
||||
onContinue={() => {
|
||||
setShowGuideModal(false)
|
||||
}}
|
||||
audioSrc={getPublicPath('audio/luxun/mp3_luxun_31.mp3')}
|
||||
contentPaddingLeft="2em"
|
||||
// firstLineIndent="2em"
|
||||
>
|
||||
{`同学你好,欢迎来到“跨越时空·体悟”学习模块!
|
||||
请登陆“时空回溯・亲历时代”体验仓,下一站:1892年,绍兴三味书屋。
|
||||
请按照年代由远及近的顺序,依“手指提示”,点亮先生的创作足迹,解锁更多故事背景!时空门已开,请做好准备吧!`}
|
||||
</StudyGuideModal>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default LuxunReflectionScene1
|
||||
Reference in new issue
Block a user