diff --git a/apps/frontend/src/App.css b/apps/frontend/src/App.css index 1e2a0b4..3ccd3b6 100644 --- a/apps/frontend/src/App.css +++ b/apps/frontend/src/App.css @@ -3,6 +3,7 @@ height: 100vh; position: relative; overflow: hidden; + background-color: rgb(163, 139, 102); } .title { diff --git a/apps/frontend/src/App.tsx b/apps/frontend/src/App.tsx index a9142d1..1ed4520 100644 --- a/apps/frontend/src/App.tsx +++ b/apps/frontend/src/App.tsx @@ -1,13 +1,38 @@ import Board from "./features/chess/compomemt/Board"; +import { Canvas } from "@react-three/fiber"; +import { Text3D, Center } from "@react-three/drei"; +import * as THREE from "three"; import "@/App.css"; function App() { return ( <> -
-
Chess
- +
+ + {/* ライトをCanvas直下に配置 */} + + + +
+ + AI Chess + {/* マテリアルを追加 */} + + +
+ + +
); diff --git a/apps/frontend/src/features/chess/compomemt/Board.tsx b/apps/frontend/src/features/chess/compomemt/Board.tsx index 6c7b091..7977430 100644 --- a/apps/frontend/src/features/chess/compomemt/Board.tsx +++ b/apps/frontend/src/features/chess/compomemt/Board.tsx @@ -1,6 +1,5 @@ import { Line, Loader } from "@react-three/drei"; import { OrbitControls } from "@react-three/drei"; -import { Canvas } from "@react-three/fiber"; import ChessPieces from "./ChessPieces"; import { Microphone } from "@/features/microphone"; import { useState } from "react"; @@ -19,7 +18,9 @@ interface BoardProps { function ChessLine() { const squares = []; const squareSize = 0.6; // 1マスのサイズ - const borderColor = new THREE.Color("rgba(228, 221, 209, 1)").convertSRGBToLinear(); + const borderColor = new THREE.Color( + "rgba(228, 221, 209, 1)" + ).convertSRGBToLinear(); for (let row = 0; row < 8; row++) { for (let col = 0; col < 8; col++) { @@ -57,16 +58,16 @@ function ChessLine() { ); } -const Board: React.FC = ({ className }) => { +const Board: React.FC = ({}) => { const [commanddata, setCommanddata] = useState(null); const { turn } = useTurnStore(); return ( - + <> - + {turn == "white" && ( console.log("認識結果:", text)} @@ -76,7 +77,7 @@ const Board: React.FC = ({ className }) => { }} onListeningChange={(listening) => console.log("録音中:", listening)} onError={(err) => console.error(err)} - position={[0, 1.5, 5]} + position={[3, 0.8, 1.8]} /> )} {turn == "black" && ( @@ -88,7 +89,7 @@ const Board: React.FC = ({ className }) => { }} onListeningChange={(listening) => console.log("録音中:", listening)} onError={(err) => console.error(err)} - position={[0, 1.5, 5]} + position={[3, 0.8, 1.8]} /> )} @@ -98,13 +99,13 @@ const Board: React.FC = ({ className }) => { > - - + + - + ); }; diff --git a/apps/frontend/src/features/chess/compomemt/ChooseFromSixPieces.tsx b/apps/frontend/src/features/chess/compomemt/ChooseFromSixPieces.tsx index 2f4aa26..5b2d491 100644 --- a/apps/frontend/src/features/chess/compomemt/ChooseFromSixPieces.tsx +++ b/apps/frontend/src/features/chess/compomemt/ChooseFromSixPieces.tsx @@ -3,24 +3,24 @@ import type { Piece } from "@repo/schema"; import { useAnimationStore, useTurnStore } from "./store"; import { useFrame } from "@react-three/fiber"; import { useRef, useEffect } from "react"; +import * as THREE from "three"; interface ChessPieceProps { piece: Piece; } -// ポーン -function Pawn({ color }: { color: string }) { +function Pawn({ color }: { color: THREE.Color }) { return ( - - + + - - + + - + @@ -29,19 +29,19 @@ function Pawn({ color }: { color: string }) { } // ルーク -function Rook({ color }: { color: string }) { +function Rook({ color }: { color: THREE.Color }) { return ( - - + + - - + + - - + + {[0, 90, 180, 270].map((angle) => ( @@ -49,11 +49,11 @@ function Rook({ color }: { color: string }) { key={angle} position={[ Math.cos((angle * Math.PI) / 180) * 0.12, - 0.65, + 0.845, Math.sin((angle * Math.PI) / 180) * 0.12, ]} > - + ))} @@ -62,27 +62,27 @@ function Rook({ color }: { color: string }) { } // ナイト -function Knight({ color }: { color: string }) { +function Knight({ color }: { color: THREE.Color }) { return ( - - + + - - + + - - + + - - + + - - + + @@ -90,22 +90,22 @@ function Knight({ color }: { color: string }) { } // ビショップ -function Bishop({ color }: { color: string }) { +function Bishop({ color }: { color: THREE.Color }) { return ( - - + + - - + + - - + + - + @@ -114,19 +114,19 @@ function Bishop({ color }: { color: string }) { } // クイーン -function Queen({ color }: { color: string }) { +function Queen({ color }: { color: THREE.Color }) { return ( - - + + - - + + - - + + {[0, 72, 144, 216, 288].map((angle) => ( @@ -134,7 +134,7 @@ function Queen({ color }: { color: string }) { key={angle} position={[ Math.cos((angle * Math.PI) / 180) * 0.1, - 0.75, + 0.975, Math.sin((angle * Math.PI) / 180) * 0.1, ]} > @@ -142,7 +142,7 @@ function Queen({ color }: { color: string }) { ))} - + @@ -151,27 +151,27 @@ function Queen({ color }: { color: string }) { } // キング -function King({ color }: { color: string }) { +function King({ color }: { color: THREE.Color }) { return ( - - + + - - + + - - + + - - + + - - + + @@ -185,7 +185,9 @@ const ChooseFromSixPieces = ({ piece }: ChessPieceProps) => { const { animatingPiece, clearAnimation } = useAnimationStore(); const { change: changeTurn } = useTurnStore(); - const pieceColor = color === "white" ? "#f5f5dc" : "#4a3728"; + const threeColor = new THREE.Color( + color === "white" ? "rgba(205, 188, 139, 1)" : "hsla(37, 68%, 24%, 1.00)" + ); // この駒がアニメーション対象かどうか const isAnimating = animatingPiece?.id === id; @@ -212,7 +214,7 @@ const ChooseFromSixPieces = ({ piece }: ChessPieceProps) => { ); // 滑らかに移動(lerpの係数を調整で速度変更可能) - groupRef.current.position.lerp(target, 0.02); + groupRef.current.position.lerp(target, 0.04); // 目標位置に十分近づいたらアニメーション完了 if (groupRef.current.position.distanceTo(target) < 0.01) { @@ -234,7 +236,7 @@ const ChooseFromSixPieces = ({ piece }: ChessPieceProps) => { return ( - + ); }; diff --git a/apps/frontend/src/features/chess/compomemt/Mark.tsx b/apps/frontend/src/features/chess/compomemt/Mark.tsx index f203e62..efa531d 100644 --- a/apps/frontend/src/features/chess/compomemt/Mark.tsx +++ b/apps/frontend/src/features/chess/compomemt/Mark.tsx @@ -1,153 +1,102 @@ import { Text3D } from "@react-three/drei"; +import * as THREE from "three"; + +const FONT_URL = + "https://threejs.org/examples/fonts/helvetiker_regular.typeface.json"; + +export default function Mark({ color }: { color: string }) { + const threeColor = new THREE.Color( + color === "white" ? "rgba(72, 63, 36, 1)" : "hsla(37, 68%, 24%, 1.00)" + ); + + const isBlack = color === "black"; + // 黒は Z軸で180度回転(文字を正しい向きに) + const rotation: [number, number, number] = isBlack + ? [0, 0, Math.PI] + : [0, 0, 0]; + + // 白側の数字(左側、1が下) + const whiteNumbers = [ + { num: "1", position: [-2.8, -2.25, 0.03] }, + { num: "2", position: [-2.8, -1.65, 0.03] }, + { num: "3", position: [-2.8, -1.05, 0.03] }, + { num: "4", position: [-2.8, -0.45, 0.03] }, + { num: "5", position: [-2.8, 0.15, 0.03] }, + { num: "6", position: [-2.8, 0.73, 0.03] }, + { num: "7", position: [-2.8, 1.3, 0.03] }, + { num: "8", position: [-2.8, 1.97, 0.03] }, + ]; + + // 黒側の数字(右側)- 黒から見て8が下、1が上になるように + const blackNumbers = [ + { num: "8", position: [2.82, -1.93, 0.03] }, + { num: "7", position: [2.82, -1.33, 0.03] }, + { num: "6", position: [2.82, -0.74, 0.03] }, + { num: "5", position: [2.82, -0.1, 0.03] }, + { num: "4", position: [2.82, 0.5, 0.03] }, + { num: "3", position: [2.82, 1.08, 0.03] }, + { num: "2", position: [2.82, 1.72, 0.03] }, + { num: "1", position: [2.82, 2.33, 0.03] }, + ]; + + // 白側のアルファベット(下側、AからH) + const whiteLetters = [ + { letter: "A", position: [-2.25, -2.87, 0.03] }, + { letter: "B", position: [-1.63, -2.87, 0.03] }, + { letter: "C", position: [-1.05, -2.87, 0.03] }, + { letter: "D", position: [-0.43, -2.87, 0.03] }, + { letter: "E", position: [0.17, -2.87, 0.03] }, + { letter: "F", position: [0.78, -2.87, 0.03] }, + { letter: "G", position: [1.32, -2.87, 0.03] }, + { letter: "H", position: [1.93, -2.87, 0.03] }, + ]; + + // 黒側のアルファベット(上側)- 黒から見てAが左、Hが右になるように + const blackLetters = [ + { letter: "H", position: [-1.93, 2.9, 0.03] }, + { letter: "G", position: [-1.3, 2.9, 0.03] }, + { letter: "F", position: [-0.8, 2.9, 0.03] }, + { letter: "E", position: [-0.2, 2.9, 0.03] }, + { letter: "D", position: [0.41, 2.9, 0.03] }, + { letter: "C", position: [1.05, 2.9, 0.03] }, + { letter: "B", position: [1.6, 2.9, 0.03] }, + { letter: "A", position: [2.2, 2.9, 0.03] }, + ]; + + const numbers = isBlack ? blackNumbers : whiteNumbers; + const letters = isBlack ? blackLetters : whiteLetters; -export default function Mark() { return ( - <> - - 1 - - - - 2 - - - - 3 - - - - 4 - - - - 5 - - - - 6 - - - - 7 - - - - 8 - - + + {/* 数字 */} + {numbers.map(({ num, position }) => ( + + {num} + + + ))} - - A - - - - B - - - - C - - - - D - - - - E - - - - F - - - - G - - - - H - - - + {/* アルファベット */} + {letters.map(({ letter, position }) => ( + + {letter} + + + ))} + ); }