feat: 更新组件和引导对话,增强用户体验

- 在多个组件中添加新的选择和填空功能,提升互动性。
- 更新引导对话文本,确保信息准确性和一致性。
- 引入新的选择组件,优化用户填写体验。
- 清理冗余代码,提升可维护性。
This commit is contained in:
zhongyidian committed 2026-01-16 17:54:51 +08:00
1 parent a8723ab4aa
commit 5bdfdadede
27 files changed
+880 -1252

No files matched your search

+69 -6
View File
@@ -1,5 +1,6 @@
import { forwardRef } from "react";
import { forwardRef, useEffect, useState } from "react";
import { createPortal } from "react-dom";
import { motion } from "framer-motion";
import PuzzlePieceDisplay from "./PuzzlePieceDisplay";
interface PuzzlePiecePortalProps {
@@ -12,21 +13,82 @@ interface PuzzlePiecePortalProps {
/**
* 碎片 Portal 组件
* 将碎片渲染到 document.body,确保在最上层显示
* 支持旋转+放大的初始出现动画
*/
const PuzzlePiecePortal = forwardRef<HTMLDivElement, PuzzlePiecePortalProps>(
({ residence, pieceId, hidden = false }, ref) => {
const [isAnimating, setIsAnimating] = useState(true);
// 当组件首次渲染时,标记动画开始
useEffect(() => {
setIsAnimating(true);
// 动画完成后,重置状态以便下次出现时重新播放
const timer = setTimeout(() => {
setIsAnimating(false);
}, 800); // 与动画时长一致
return () => clearTimeout(timer);
}, [pieceId]); // 当 pieceId 变化时重新播放动画
return createPortal(
<div
ref={ref}
className="fixed z-[99999] pointer-events-none"
style={{
position: "fixed",
left: "50%",
top: "50%",
transform: "translate(-50%, -50%)",
width: "120px",
height: "120px",
opacity: hidden ? 0 : 1,
visibility: hidden ? "hidden" : "visible",
transform: "translate(-50%, -50%)",
perspective: "1000px", // 添加透视,让3D效果更明显
zIndex: 99999,
pointerEvents: "none",
}}
>
<motion.div
ref={ref}
style={{
width: "100%",
height: "100%",
transformStyle: "preserve-3d", // 保持3D变换
}}
initial={
isAnimating
? {
scale: 0,
rotateY: -180,
opacity: 0,
}
: false
}
animate={
hidden
? { opacity: 0, visibility: "hidden" as const }
: isAnimating
? {
scale: 1,
rotateY: 0,
opacity: 1,
visibility: "visible" as const,
}
: {
opacity: 1,
visibility: "visible" as const,
}
}
transition={{
duration: 0.8, // 稍微延长动画时间,让效果更舒缓
ease: [0.25, 0.46, 0.45, 0.94], // 平滑的缓动函数,缓缓出现
scale: {
duration: 0.8,
ease: [0.25, 0.46, 0.45, 0.94],
},
rotateY: {
duration: 0.8,
ease: [0.25, 0.46, 0.45, 0.94],
},
opacity: {
duration: 0.6,
ease: "easeOut",
},
}}
>
<PuzzlePieceDisplay
@@ -35,6 +97,7 @@ const PuzzlePiecePortal = forwardRef<HTMLDivElement, PuzzlePiecePortalProps>(
showGlow={true}
className="w-full h-full"
/>
</motion.div>
</div>,
document.body
);