import { forwardRef, useEffect, useState } from 'react' import { createPortal } from 'react-dom' import { motion } from 'framer-motion' import PuzzlePieceDisplay from './PuzzlePieceDisplay' interface PuzzlePiecePortalProps { residence: string pieceId: number /** 是否隐藏(飞行时隐藏原始碎片) */ hidden?: boolean } /** * 碎片 Portal 组件 * 将碎片渲染到 document.body,确保在最上层显示 * 支持旋转+放大的初始出现动画 */ const PuzzlePiecePortal = forwardRef( ({ 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(
, document.body ) } ) PuzzlePiecePortal.displayName = 'PuzzlePiecePortal' export default PuzzlePiecePortal