feat:黄炎培对话对接中
This commit is contained in:
1 parent
3611a0857a
commit
6ab184b328
125 files changed
+6617
-2391
No files matched your search
@@ -1,9 +1,8 @@
|
||||
import { useState, useEffect, useMemo, useCallback } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import { cn, getStaticImage } from "@/lib/utils";
|
||||
import { Image } from "@/components";
|
||||
import { useScale } from "@/contexts/ScaleContext";
|
||||
import { Image, StudyGuideModal } from "@/components";
|
||||
import { SuccessAlert, ErrorAlert } from "@/components/layout";
|
||||
|
||||
export interface ChoiceDialog1Props {
|
||||
/** 是否可见 */
|
||||
@@ -31,14 +30,26 @@ const ChoiceDialog1 = ({
|
||||
const choice2Src = getStaticImage("huangyanpei/reflection/scene2/10_006");
|
||||
const choice3Src = getStaticImage("huangyanpei/reflection/scene2/10_007");
|
||||
|
||||
const { scale, offsetX, offsetY, DESIGN_WIDTH, DESIGN_HEIGHT } = useScale();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [showGuide, setShowGuide] = useState(false);
|
||||
const [showSuccessAlert, setShowSuccessAlert] = useState(false);
|
||||
const [showErrorAlert, setShowErrorAlert] = useState(false);
|
||||
|
||||
// SSR 兼容
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (visible) {
|
||||
setShowGuide(true);
|
||||
setShowSuccessAlert(false);
|
||||
setShowErrorAlert(false);
|
||||
} else {
|
||||
setShowGuide(false);
|
||||
}
|
||||
}, [visible]);
|
||||
|
||||
const handleClose = useCallback(
|
||||
(e: React.MouseEvent<HTMLImageElement>) => {
|
||||
e.stopPropagation();
|
||||
@@ -49,10 +60,15 @@ const ChoiceDialog1 = ({
|
||||
|
||||
const handleChoiceClick = useCallback(
|
||||
(choice: "读书" | "没出息" | "女子不能上学") => {
|
||||
onSelect?.(choice);
|
||||
onClose?.();
|
||||
if (choice === "读书") {
|
||||
setShowGuide(false);
|
||||
setShowSuccessAlert(true);
|
||||
onSelect?.(choice);
|
||||
} else {
|
||||
setShowErrorAlert(true);
|
||||
}
|
||||
},
|
||||
[onSelect, onClose]
|
||||
[onSelect]
|
||||
);
|
||||
|
||||
// 样式
|
||||
@@ -66,20 +82,6 @@ const ChoiceDialog1 = ({
|
||||
[]
|
||||
);
|
||||
|
||||
const scaledContainerStyle = useMemo<React.CSSProperties>(
|
||||
() => ({
|
||||
position: "absolute",
|
||||
width: `${DESIGN_WIDTH}px`,
|
||||
height: `${DESIGN_HEIGHT}px`,
|
||||
left: `${offsetX}px`,
|
||||
top: `${offsetY}px`,
|
||||
transform: `scale(${scale})`,
|
||||
transformOrigin: "top left",
|
||||
overflow: "hidden",
|
||||
}),
|
||||
[scale, offsetX, offsetY, DESIGN_WIDTH, DESIGN_HEIGHT]
|
||||
);
|
||||
|
||||
if (!mounted) return null;
|
||||
|
||||
const content = (
|
||||
@@ -93,109 +95,154 @@ const ChoiceDialog1 = ({
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.3, ease: "easeInOut" }}
|
||||
>
|
||||
<div style={scaledContainerStyle}>
|
||||
<div
|
||||
className={cn(
|
||||
"absolute inset-0 flex flex-col items-center justify-center",
|
||||
"bg-black/70"
|
||||
)}
|
||||
style={{ pointerEvents: "auto" }}
|
||||
<div
|
||||
className={cn(
|
||||
"fixed inset-0 flex flex-col items-center justify-center",
|
||||
"bg-black/70"
|
||||
)}
|
||||
style={{ pointerEvents: "auto" }}
|
||||
>
|
||||
{/* 背景蒙版 */}
|
||||
{maskSrc && (
|
||||
<Image
|
||||
src={maskSrc}
|
||||
className="absolute inset-0 w-full h-full object-cover select-none pointer-events-none"
|
||||
aria-hidden
|
||||
/>
|
||||
)}
|
||||
|
||||
<StudyGuideModal
|
||||
visible={showGuide}
|
||||
onContinue={() => setShowGuide(false)}
|
||||
verticalAlign="center"
|
||||
>
|
||||
{/* 背景蒙版 */}
|
||||
{maskSrc && (
|
||||
<Image
|
||||
src={maskSrc}
|
||||
className="absolute inset-0 w-full h-full object-cover select-none pointer-events-none"
|
||||
aria-hidden
|
||||
/>
|
||||
)}
|
||||
黄校长来考你啦!他设计这所学校,就是为了让学生摆脱旧观念,你知道是哪种吗?
|
||||
</StudyGuideModal>
|
||||
|
||||
{/* 返回按钮 */}
|
||||
{onClose && (
|
||||
<Image
|
||||
src={backSrc}
|
||||
onClick={handleClose}
|
||||
alt="返回"
|
||||
className="absolute top-5 right-5 z-20"
|
||||
button
|
||||
/>
|
||||
)}
|
||||
{/* 返回按钮 */}
|
||||
{onClose && (
|
||||
<Image
|
||||
src={backSrc}
|
||||
onClick={handleClose}
|
||||
alt="返回"
|
||||
className="absolute top-5 right-5 z-20"
|
||||
button
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 内容区域 */}
|
||||
<div className="relative z-10 w-full h-full flex items-center justify-between px-20">
|
||||
{/* 人物 - 左侧 */}
|
||||
<div className="flex-shrink-0">
|
||||
<img src={characterSrc} alt="人物" />
|
||||
{/* 内容区域 */}
|
||||
<div className="relative z-10 w-full h-full flex items-center justify-between px-20">
|
||||
{/* 人物 - 左侧 */}
|
||||
<div className="flex-shrink-0">
|
||||
<img src={characterSrc} alt="人物" />
|
||||
</div>
|
||||
|
||||
{/* 三个选择选项 - 右侧水平排列 */}
|
||||
<div className="flex items-center justify-center gap-16 flex-1">
|
||||
{/* 选择A:读书 */}
|
||||
<div
|
||||
className="flex flex-col items-center cursor-pointer transition-transform duration-200 hover:scale-105 active:scale-95"
|
||||
onClick={() => handleChoiceClick("读书")}
|
||||
>
|
||||
{/* 标签A */}
|
||||
<div className="text-7xl font-bold text-[#ffa500] mb-3 [text-shadow:_3px_3px_0_#fff,_-3px_-3px_0_#fff,_3px_-3px_0_#fff,_-3px_3px_0_#fff]">
|
||||
A
|
||||
</div>
|
||||
{/* 图标 */}
|
||||
<img src={choice1Src} alt="读书" className="mb-3" />
|
||||
{/* 文字说明 */}
|
||||
<div className="text-black text-4xl text-center leading-relaxed font-bold">
|
||||
读书只为
|
||||
<br />
|
||||
升官发财
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 三个选择选项 - 右侧水平排列 */}
|
||||
<div className="flex items-center justify-center gap-16 flex-1">
|
||||
{/* 选择A:读书 */}
|
||||
<div
|
||||
className="flex flex-col items-center cursor-pointer transition-transform duration-200 hover:scale-105 active:scale-95"
|
||||
onClick={() => handleChoiceClick("读书")}
|
||||
>
|
||||
{/* 标签A */}
|
||||
<div className="text-7xl font-bold text-[#ffa500] mb-3 [text-shadow:_3px_3px_0_#fff,_-3px_-3px_0_#fff,_3px_-3px_0_#fff,_-3px_3px_0_#fff]">
|
||||
A
|
||||
</div>
|
||||
{/* 图标 */}
|
||||
<img src={choice1Src} alt="读书" className="mb-3" />
|
||||
{/* 文字说明 */}
|
||||
<div className="text-black text-4xl text-center leading-relaxed font-bold">
|
||||
读书只为
|
||||
<br />
|
||||
升官发财
|
||||
</div>
|
||||
{/* 选择B:没出息 */}
|
||||
<div
|
||||
className="flex flex-col items-center cursor-pointer transition-transform duration-200 hover:scale-105 active:scale-95"
|
||||
onClick={() => handleChoiceClick("没出息")}
|
||||
>
|
||||
{/* 标签B */}
|
||||
<div className="text-7xl font-bold text-[#ffa500] mb-3 [text-shadow:_3px_3px_0_#fff,_-3px_-3px_0_#fff,_3px_-3px_0_#fff,_-3px_3px_0_#fff]">
|
||||
B
|
||||
</div>
|
||||
|
||||
{/* 选择B:没出息 */}
|
||||
<div
|
||||
className="flex flex-col items-center cursor-pointer transition-transform duration-200 hover:scale-105 active:scale-95"
|
||||
onClick={() => handleChoiceClick("没出息")}
|
||||
>
|
||||
{/* 标签B */}
|
||||
<div className="text-7xl font-bold text-[#ffa500] mb-3 [text-shadow:_3px_3px_0_#fff,_-3px_-3px_0_#fff,_3px_-3px_0_#fff,_-3px_3px_0_#fff]">
|
||||
B
|
||||
</div>
|
||||
{/* 图标 */}
|
||||
<img src={choice2Src} alt="没出息" className="mb-3" />
|
||||
{/* 文字说明 */}
|
||||
<div className="text-black text-4xl text-center leading-relaxed font-bold">
|
||||
手工劳作
|
||||
<br />
|
||||
没出息
|
||||
</div>
|
||||
{/* 图标 */}
|
||||
<img src={choice2Src} alt="没出息" className="mb-3" />
|
||||
{/* 文字说明 */}
|
||||
<div className="text-black text-4xl text-center leading-relaxed font-bold">
|
||||
手工劳作
|
||||
<br />
|
||||
没出息
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 选择C:女子不能上学 */}
|
||||
<div
|
||||
className="flex flex-col items-center cursor-pointer transition-transform duration-200 hover:scale-105 active:scale-95"
|
||||
onClick={() => handleChoiceClick("女子不能上学")}
|
||||
>
|
||||
{/* 标签C */}
|
||||
<div className="text-7xl font-bold text-[#ffa500] mb-3 [text-shadow:_3px_3px_0_#fff,_-3px_-3px_0_#fff,_3px_-3px_0_#fff,_-3px_3px_0_#fff]">
|
||||
C
|
||||
</div>
|
||||
{/* 图标 */}
|
||||
<img src={choice3Src} alt="女子不能上学" className="mb-3" />
|
||||
{/* 文字说明 */}
|
||||
<div className="text-black text-4xl text-center leading-relaxed font-bold">
|
||||
女子
|
||||
<br />
|
||||
不能上学
|
||||
</div>
|
||||
{/* 选择C:女子不能上学 */}
|
||||
<div
|
||||
className="flex flex-col items-center cursor-pointer transition-transform duration-200 hover:scale-105 active:scale-95"
|
||||
onClick={() => handleChoiceClick("女子不能上学")}
|
||||
>
|
||||
{/* 标签C */}
|
||||
<div className="text-7xl font-bold text-[#ffa500] mb-3 [text-shadow:_3px_3px_0_#fff,_-3px_-3px_0_#fff,_3px_-3px_0_#fff,_-3px_3px_0_#fff]">
|
||||
C
|
||||
</div>
|
||||
{/* 图标 */}
|
||||
<img src={choice3Src} alt="女子不能上学" className="mb-3" />
|
||||
{/* 文字说明 */}
|
||||
<div className="text-black text-4xl text-center leading-relaxed font-bold">
|
||||
女子
|
||||
<br />
|
||||
不能上学
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SuccessAlert
|
||||
visible={showSuccessAlert}
|
||||
title="任务1 正确反馈"
|
||||
content="答对啦!黄先生说“教育要为国家培养实干人才”,浦东中学就是要教大家学真本事,不是只为当官。"
|
||||
onContinue={() => {
|
||||
setShowSuccessAlert(false);
|
||||
onClose?.();
|
||||
}}
|
||||
onClose={() => {
|
||||
setShowSuccessAlert(false);
|
||||
onClose?.();
|
||||
}}
|
||||
/>
|
||||
|
||||
<ErrorAlert
|
||||
visible={showErrorAlert}
|
||||
text="不对哦~黄先生虽然反对歧视女子、轻视手工,但创办浦东中学的核心是打破“读书只为当官”的旧思想,再选一次吧!"
|
||||
onClose={() => setShowErrorAlert(false)}
|
||||
/>
|
||||
|
||||
<SuccessAlert
|
||||
visible={showSuccessAlert}
|
||||
content="答对啦!黄先生说“教育要为国家培养实干人才”,浦东中学就是要教大家学真本事,不是只为当官。"
|
||||
onContinue={() => {
|
||||
setShowSuccessAlert(false);
|
||||
onClose?.();
|
||||
}}
|
||||
onClose={() => {
|
||||
setShowSuccessAlert(false);
|
||||
onClose?.();
|
||||
}}
|
||||
/>
|
||||
|
||||
<ErrorAlert
|
||||
visible={showErrorAlert}
|
||||
text="不对哦~黄先生虽然反对歧视女子、轻视手工,但创办浦东中学的核心是打破“读书只为当官”的旧思想,再选一次吧!"
|
||||
onClose={() => setShowErrorAlert(false)}
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
|
||||
return createPortal(content, document.body);
|
||||
return content;
|
||||
};
|
||||
|
||||
export default ChoiceDialog1;
|
||||
Reference in new issue
Block a user