import { useMemo, useState } from 'react'
import { getBackgroundImage, getStaticImage } from '@/lib/utils'
import { usePuzzleStore } from '@/store/puzzleStore'
import { Image } from '@/components'
import { PUZZLE_RESIDENCES } from '@/config/puzzleResidences'
/**
* 六边形进度条组件
* 根据进度值显示不同颜色:100%绿色,50%-99%橙色,0%-49%灰色
*/
interface HexagonProgressBarProps {
progress: number // 0-100
}
const HexagonProgressBar = ({ progress }: HexagonProgressBarProps) => {
const progressPercent = Math.min(100, Math.max(0, progress))
const progressText =
progressPercent.toFixed(2) === '100.00' ? '进度100%' : `进度${Math.round(progressPercent)}%`
// 根据进度值确定填充颜色
const getProgressColor = () => {
if (progressPercent >= 100) {
return '#90B86B' // 浅橄榄绿色(100%完成)
} else if (progressPercent >= 50) {
return '#EEB362' // 橙色(50%-99%)
} else {
return '#E0E0E0' // 浅灰色(0%-49%)
}
}
const fillColor = getProgressColor()
// 六边形路径,细长的水平六边形,左右两端是尖角
// 正确的六边形路径:从左顶点开始,顺时针绘制
// 左顶点(0%, 50%) -> 左上角(3%, 0%) -> 右上角(97%, 0%) -> 右顶点(100%, 50%) -> 右下角(97%, 100%) -> 左下角(3%, 100%)
// 外层路径(包含边框)
const outerHexagonPath = 'polygon(0% 50%, 3% 0%, 97% 0%, 100% 50%, 97% 100%, 3% 100%)'
// 内层路径(边框内部)
const innerHexagonPath = 'polygon(0% 50%, 3% 0%, 97% 0%, 100% 50%, 97% 100%, 3% 100%)'
const borderWidth = 4 // 增加边框宽度从2px到3px
return (
{/* 外层:白色边框(使用 clip-path 裁剪形状) */}
{/* 内容容器(边框内部区域) */}
{/* 背景层:深灰色背景(未填充部分) */}
{/* 填充层(根据进度百分比从左侧填充) */}
{progressPercent > 0 && (
)}
{/* 文字(白色,居中,始终显示在最上层,带阴影效果) */}
{progressText}
)
}
export interface MenuPuzzleCenterProps {
/** 是否可见 */
visible: boolean
/** 关闭回调 */
onClose: () => void
/** 选择某个故居后的回调(进入对应的碎片系统) */
onSelectResidence: (residence: string) => void
/** 是否允许从管理中心进入具体拼图 */
allowPuzzleEntry?: boolean
}
const MenuPuzzleCenter = ({
visible,
onClose,
onSelectResidence,
allowPuzzleEntry = true,
}: MenuPuzzleCenterProps) => {
const { getPuzzleCollectProgress } = usePuzzleStore()
const [activeMapImage, setActiveMapImage] = useState(null)
const residenceProgress = useMemo(
() =>
PUZZLE_RESIDENCES.map((item) => ({
...item,
// 只有已开放拼图的故居才计算收集进度
progress: item.hasPuzzle ? getPuzzleCollectProgress(item.residence) : 0,
})),
[getPuzzleCollectProgress]
)
if (!visible) return null
return (
{
if (e.target === e.currentTarget) {
onClose()
}
}}
>
{/* 箭头指示底图 */}
})
{/* 关闭按钮 */}
{/* 故居列表:按照设计图进行绝对定位 */}
{residenceProgress.map(
({
residence,
displayName,
left,
top,
image,
hasPuzzle,
progress,
hasMap,
mapImage,
}) => (
{/* 故居图片(资源在 puzzle/home 下,可根据实际名称调整) */}
{/* 进度展示,仅对已开放拼图的故居显示 */}
{hasPuzzle && (
)}
{/* 图标 */}
{allowPuzzleEntry && (
{
if (!hasPuzzle) return
e.stopPropagation()
onSelectResidence(residence)
}}
/>
)}
{
e.stopPropagation()
if (!hasMap || !mapImage) return
setActiveMapImage(mapImage)
}}
/>
)
)}
{/* 导图弹窗 */}
{activeMapImage && (
{
if (e.target === e.currentTarget) {
setActiveMapImage(null)
}
}}
>
setActiveMapImage(null)}
/>
)}
)
}
export default MenuPuzzleCenter