diff --git a/src/App.tsx b/src/App.tsx index 8fe7b1b..fa9c287 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -17,7 +17,7 @@ import { templateMatchingForPiece, } from './chessboard/templateMatching'; import { ImageUploader } from './components/ImageUploader'; -import { ChessboardOverlay } from './components/ChessboardOverlay'; +import { BoardResult } from './components/BoardResult'; import { FENDisplay } from './components/FENDisplay'; import { SolutionDisplay } from './components/SolutionDisplay'; import { generateFenFromPieces } from './chessboard/fenGeneration'; @@ -188,7 +188,7 @@ export function App() { setLoading(true); setError(null); try { - const move = await engine.getBestMove(fen, depth); // 传递深度值 + const move = await engine.getBestMove(fen, depth); // 传递度值 setBestMove(move); if (move === 'red_wins' || move === 'black_wins') { setLoading(false); @@ -254,39 +254,44 @@ export function App() {
+ +
+
- -
- - { - if (e.target instanceof HTMLInputElement) { - handleDepthChange(Number(e.target.value)); - } - }} - /> +
+

搜索深度控制

+
+ + { + if (e.target instanceof HTMLInputElement) { + handleDepthChange(Number(e.target.value)); + } + }} + /> +
-
); -} +} \ No newline at end of file diff --git a/src/app.css b/src/app.css index f909a04..23adb82 100644 --- a/src/app.css +++ b/src/app.css @@ -108,27 +108,50 @@ main { .content-wrapper { display: flex; - flex-direction: column; + flex-wrap: wrap; gap: 2rem; width: 100%; - max-width: 850px; - margin: 0 auto 2rem; + max-width: 1200px; + margin: 0 auto; padding: 0 1rem; box-sizing: border-box; } -.left-column { +.left-column, +.right-column { + width: 100%; +} + +.solution-section, +.upload-section, +.board-result-section, +.fen-section, +.depth-control-section { + background-color: #fff; + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + padding: 1.5rem; + margin-bottom: 1rem; +} + +.solution-column, +.image-column { flex: 1; display: flex; flex-direction: column; gap: 1rem; } -.upload-section, .result-section, .fen-section { +.solution-section, +.upload-section, +.board-result-section, +.depth-control-section, +.fen-section { background-color: #fff; border-radius: 8px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); padding: 1.5rem; + margin-bottom: 1rem; } .solution-section { @@ -204,45 +227,69 @@ footer { color: #ecf0f1; } -@media (min-width: 769px) { +@media (max-width: 768px) { .content-wrapper { - flex-direction: row; - align-items: flex-start; + flex-direction: column; + gap: 0; } - .left-column { - width: 50%; - max-width: 600px; + .left-column, + .right-column { + width: 100%; } .solution-section { - width: 50%; - max-width: 600px; + order: 1; + } + + .upload-section { + order: 0; + } + + .board-result-section { + order: 2; + } + + .fen-section { + order: 3; + } + + .depth-control-section { + order: 4; } } -@media (max-width: 768px) { +@media (min-width: 769px) { .content-wrapper { - flex-direction: column; - padding: 0 0.5rem; + flex-direction: row; + align-items: flex-start; + } + + .left-column { + width: calc(50% - 1rem); + position: sticky; + top: 1rem; + align-self: flex-start; + } + + .right-column { + width: calc(50% - 1rem); } - .left-column, .solution-section { - width: 100%; + height: calc(100vh - 2rem); + overflow-y: auto; } - .chessboard { - max-width: 100%; - height: auto; + .solution-column, + .image-column { + width: 50%; + max-width: 600px; + } + .solution-section { + order: -1; } -} -.result-section { - box-sizing: border-box; - max-width: 600px; - margin: 0 auto; - width: 100%; } .chessboard { @@ -281,4 +328,18 @@ footer { background-color: #95a5a6; cursor: not-allowed; opacity: 0.7; +} + +.depth-slider-container { + display: flex; + flex-direction: column; + gap: 0.5rem; +} + +.depth-slider-container label { + font-weight: bold; +} + +#depth-slider { + width: 100%; } \ No newline at end of file diff --git a/src/components/ChessboardOverlay.tsx b/src/components/BoardResult.tsx similarity index 90% rename from src/components/ChessboardOverlay.tsx rename to src/components/BoardResult.tsx index fdaee23..0611f7a 100644 --- a/src/components/ChessboardOverlay.tsx +++ b/src/components/BoardResult.tsx @@ -1,18 +1,18 @@ import './ChessboardOverlay.css'; -interface ChessboardOverlayProps { +interface BoardResultProps { overlayImageSrc: string; chessboardRect?: { x: number; y: number; width: number; height: number }; originalImageSize?: { width: number; height: number }; } -const MAX_WIDTH = 400; // 在 JavaScript 中定义 max-width +const MAX_WIDTH = 360; // 在 JavaScript 中定义 max-width -export function ChessboardOverlay({ +export function BoardResult({ overlayImageSrc, chessboardRect = { x: 0, y: 0, width: 0, height: 0 }, originalImageSize = { width: 0, height: 0 }, -}: ChessboardOverlayProps) { +}: BoardResultProps) { // 添加间隙 const padding = 15; @@ -43,7 +43,7 @@ export function ChessboardOverlay({ const leftOffset = (finalWidth - stretchedWidth) / 2; return ( -
+

分析结果

([]); const canvasRef = useRef(null); + const [scale, setScale] = useState(1); useEffect(() => { const newBoard = parseFEN(fen); @@ -45,6 +46,22 @@ export function ChessboardDisplay({ fen, bestMove }: ChessboardDisplayProps) { } }, [board, bestMove]); + useEffect(() => { + function handleResize() { + if (canvasRef.current) { + const screenWidth = window.innerWidth; + const maxWidth = screenWidth * 0.8; + const originalWidth = 8 * 40 + 40; // 8 cells + 2 margins + const newScale = Math.min(1, maxWidth / originalWidth); + setScale(newScale); + } + } + + handleResize(); + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); + function parseFEN(fen: string): (Piece | null)[][] { const rows = fen.split(' ')[0].split('/'); const board: (Piece | null)[][] = []; @@ -80,8 +97,13 @@ export function ChessboardDisplay({ fen, bestMove }: ChessboardDisplayProps) { const margin = cellSize / 2; const boardWidth = 8 * cellSize + 2 * margin; const boardHeight = 9 * cellSize + 2 * margin; - canvas.width = boardWidth; - canvas.height = boardHeight; + + // Set canvas size based on scale + canvas.width = boardWidth * scale; + canvas.height = boardHeight * scale; + + // Scale the context + ctx.scale(scale, scale); // 绘制棋盘背景 ctx.fillStyle = '#f0d9b5'; @@ -304,5 +326,16 @@ export function ChessboardDisplay({ fen, bestMove }: ChessboardDisplayProps) { ctx.fill(); } - return ; + return ( +
+ +
+ ); } \ No newline at end of file diff --git a/src/components/ChessboardOverlay.css b/src/components/ChessboardOverlay.css index 124ca12..27c9ce0 100644 --- a/src/components/ChessboardOverlay.css +++ b/src/components/ChessboardOverlay.css @@ -1,9 +1,3 @@ -.result-section { - box-sizing: border-box; - margin: 0 auto; - width: 100%; -} - .image-container { position: relative; width: 100%;