치지직 채널 ID로 입장하게 변경 및 일부 판 커스텀 설정 추가.

This commit is contained in:
kimyu
2026-09-16 05:29:50 +09:00
parent 7c402dfd8f
commit 6f72824598
5 changed files with 170 additions and 31 deletions

View File

@@ -10,8 +10,10 @@ import { getAssets } from './asset-storage';
import {
buildPlaneCells,
cellColorFor,
DEFAULT_PLANE_SIZE,
diceAreaSpan,
getOrCreateBoardConfig,
perimeterLength,
} from './board-config';
const STEP_MS = 280;
@@ -34,15 +36,13 @@ export default function DicePlane({
chatFeed?: ChatFeedItem[];
showChatFeed?: boolean;
}) {
const initial = getOrCreateBoardConfig();
const [planeSize, setPlaneSize] = useState({
width: initial.width,
height: initial.height,
const [boardReady, setBoardReady] = useState(false);
const [planeSize, setPlaneSize] = useState<{ width: number; height: number }>({
width: DEFAULT_PLANE_SIZE.width,
height: DEFAULT_PLANE_SIZE.height,
});
const [dicePlaneArray, setDicePlaneArray] = useState<PlaneCell[]>(() =>
buildPlaneCells(initial),
);
const chessmanRef = useRef(new Chessman(initial.cells.length));
const [dicePlaneArray, setDicePlaneArray] = useState<PlaneCell[]>([]);
const chessmanRef = useRef(new Chessman(perimeterLength(DEFAULT_PLANE_SIZE.width, DEFAULT_PLANE_SIZE.height)));
const boardRef = useRef(dicePlaneArray);
const [chessmanIndex, setChessmanIndex] = useState(0);
const [chessmanSrc, setChessmanSrc] = useState('/chessman/default.png');
@@ -59,6 +59,7 @@ export default function DicePlane({
const [islandTurnsLeft, setIslandTurnsLeft] = useState(0);
const moveTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
// SSR/초기 렌더에서 랜덤 판을 쓰지 않고, 브라우저에 저장된 설정을 로드
useEffect(() => {
const board = getOrCreateBoardConfig();
const cells = buildPlaneCells(board);
@@ -72,6 +73,7 @@ export default function DicePlane({
setStatusText('시계방향');
setIslandTurnsLeft(0);
setDicePlaneArray(cells);
setBoardReady(true);
}, []);
useEffect(() => {
@@ -175,6 +177,25 @@ export default function DicePlane({
const chessmanCell = dicePlaneArray[chessmanIndex] ?? dicePlaneArray[0];
const diceSpan = diceAreaSpan(planeSize.width, planeSize.height);
if (!boardReady || dicePlaneArray.length === 0) {
return (
<div
style={{
position: 'relative',
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: 'rgba(255,255,255,0.7)',
fontSize: 14,
}}
>
판 불러오는 중…
</div>
);
}
return (
<div style={{ position: 'relative', width: '100%', height: '100%' }}>
<div
@@ -192,6 +213,7 @@ export default function DicePlane({
{dicePlaneArray.map((plane, index) => {
const isStart = index === 0;
const isLanded = !moving && index === chessmanIndex && landedLabel != null;
const showContent = plane.contentVisible !== false;
return (
<div
key={plane.id}
@@ -201,8 +223,11 @@ export default function DicePlane({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: cellColorFor(plane.eventId, index),
backgroundImage: plane.imageSrc ? `url(${plane.imageSrc})` : undefined,
backgroundColor: cellColorFor(plane.eventId, index, {
contentVisible: showContent,
}),
backgroundImage:
showContent && plane.imageSrc ? `url(${plane.imageSrc})` : undefined,
backgroundSize: 'cover',
backgroundPosition: 'center',
color: 'white',
@@ -219,10 +244,13 @@ export default function DicePlane({
transform: isLanded ? 'scale(1.04)' : undefined,
transition: 'box-shadow 180ms ease, transform 180ms ease',
zIndex: isLanded ? 4 : undefined,
textShadow: plane.imageSrc ? '0 1px 3px rgba(0,0,0,0.85)' : undefined,
textShadow:
showContent && plane.imageSrc
? '0 1px 3px rgba(0,0,0,0.85)'
: undefined,
}}
>
{isStart ? '시작' : plane.type}
{showContent ? (isStart ? '시작' : plane.type) : null}
</div>
);
})}