Files
shanghai-residences/src/pages/chenyun/reflection/mimian/MimianClues.tsx
T

131 lines
4.3 KiB
TypeScript

/**
* 米棉之战线索区域组件
* 包含投机商情报、全国物资分布、对话的展示
*/
import { Image } from "@/components";
import { cn, getStaticImage } from "@/lib/utils";
import { ClueItem } from "../shared/ClueItem";
import type { FileType } from "../shared/types";
import type { ClueData } from "@/components/layout";
import { MIMIAN_CLUE_DATA } from "../constants/mimian";
export interface MimianCluesProps {
/** 当前展开的文件 */
expandedFile: FileType | null;
/** 线索状态 */
clueStates: Record<string, boolean>;
/** 线索点击回调 */
onClueClick: (clue: ClueData, clueKey: string) => void;
}
/**
* 米棉之战线索区域组件
* 显示投机商情报、全国物资分布、对话
*/
export const MimianClues = ({
expandedFile,
clueStates,
onClueClick,
}: MimianCluesProps) => {
const isExpanded = expandedFile === "mimian";
return (
<>
{/* 米棉之战:线索-投机商情报 */}
<div
className={cn([
"absolute left-70 bottom-8 transition-all duration-300 delay-100",
"hover:scale-105 hover:brightness-115",
isExpanded
? "opacity-100 translate-y-0"
: "opacity-0 translate-y-10 pointer-events-none",
])}
>
<ClueItem
clueKey="mimian-intelligence"
imageSrc="chenyun/reflection/投机商情报桌上"
isViewed={clueStates["mimian-intelligence"] || false}
onClick={() => {
const clue = MIMIAN_CLUE_DATA["mimian-intelligence"];
if (clue) {
onClueClick(clue, "mimian-intelligence");
}
}}
viewedMarkOffset={{ left: "4px" }}
/>
</div>
{/* 米棉之战:线索-全国物资分布 */}
<div
className={cn([
"absolute left-135 bottom-8 transition-all duration-300 delay-150",
"hover:scale-105 hover:brightness-115",
isExpanded
? "opacity-100 translate-y-0"
: "opacity-0 translate-y-10 pointer-events-none",
])}
>
<ClueItem
clueKey="mimian-distribution"
imageSrc="chenyun/reflection/全国物资分布桌上"
isViewed={clueStates["mimian-distribution"] || false}
onClick={() => {
const clue = MIMIAN_CLUE_DATA["mimian-distribution"];
if (clue) {
onClueClick(clue, "mimian-distribution");
}
}}
viewedMarkOffset={{ left: "12px" }}
/>
</div>
{/* 米棉之战:消息(对话线索) */}
<div
className={cn([
"absolute left-155 -top-118 transition-all duration-300 delay-200",
"hover:scale-105 hover:brightness-115",
isExpanded
? "opacity-100 translate-y-0"
: "opacity-0 -translate-y-10 pointer-events-none",
])}
>
<div
className="cursor-pointer"
onClick={() => {
const clue = MIMIAN_CLUE_DATA["mimian-dialogue"];
if (clue) {
onClueClick(clue, "mimian-dialogue");
}
}}
>
<Image src={getStaticImage("chenyun/reflection/对话气泡")} button />
{/* 未倾听时显示三个点动画 */}
{!clueStates["mimian-dialogue"] && (
<div className="absolute left-1/2 -translate-x-1/2 top-1/2 -translate-y-1/2 flex items-center justify-center">
<div className="animate-dots flex gap-2">
<span className="w-3 h-3 bg-gray-500 rounded-full inline-block" />
<span className="w-3 h-3 bg-gray-500 rounded-full inline-block" />
<span className="w-3 h-3 bg-gray-500 rounded-full inline-block" />
</div>
</div>
)}
{/* 已倾听标记 */}
{clueStates["mimian-dialogue"] && (
<div className="absolute left-1/2 -translate-x-1/2 bottom-16">
<span
className={cn([
"text-[#ae6400] text-3xl font-bold whitespace-nowrap",
"[text-shadow:_-4px_-4px_0_#ffffff,_4px_-4px_0_#ffffff,_-4px_4px_0_#ffffff,_4px_4px_0_#ffffff,_-5px_0_0_#ffffff,_5px_0_0_#ffffff,_0_-5px_0_#ffffff,_0_5px_0_#ffffff]",
])}
>
已倾听
</span>
</div>
)}
</div>
</div>
</>
);
};