서버에서 가져온 이미지의 단어를 캔버스로 적어서 정답 유무 판별
-정답을 맞췄을 시 다음 레벨로 넘어가기 버튼 추가
page - Game - <Canvas.js>
import React, { useEffect, useRef, useState } from "react";
import axios from "axios";
import "../../css/game.css";
function Canvas({ checkAnswer, newFetch, quiz }) {
const canvasRef = useRef(null);
const [isDrawing, setIsDrawing] = useState(false);
const [checkQuiz, setCheckQuiz] = useState(false);
const [lastX, setLastX] = useState(0);
const [lastY, setLastY] = useState(0);
const [outputImageSrc, setOutputImageSrc] = useState(null);
const [path, setPath] = useState([]);
const [paths, setPaths] = useState([]);
const [imgText, setImgText] = useState("");
useEffect(() => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
const drawing = (e) => {
if (!isDrawing) return;
const rect = canvas.getBoundingClientRect();
const offsetX = e.clientX - rect.left;
const offsetY = e.clientY - rect.top;
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(offsetX, offsetY);
ctx.strokeStyle = "blue";
ctx.lineWidth = 10;
ctx.stroke();
setLastX(offsetX);
setLastY(offsetY);
setPath((prevPath) => [...prevPath, { x: offsetX, y: offsetY }]);
};
canvas.addEventListener("mousemove", drawing);
return () => {
canvas.removeEventListener("mousemove", drawing);
};
}, [isDrawing, lastX, lastY]);
const drawingCanvas = (e) => {
setIsDrawing(true);
const rect = e.target.getBoundingClientRect();
setLastX(e.clientX - rect.left);
setLastY(e.clientY - rect.top);
setPath([{ x: e.clientX - rect.left, y: e.clientY - rect.top }]);
};
const stopDrawing = () => {
if (isDrawing) {
setPaths((prevPaths) => [...prevPaths, path]);
setPath([]);
}
setIsDrawing(false);
};
const canvasOut = () => {
setIsDrawing(false);
};
const outputCanvasImage = async () => {
const canvas = canvasRef.current;
setOutputImageSrc(canvas.toDataURL());
const dataURL = canvas.toDataURL("image/png");
await axios
.post("http://localhost:5000/canvas", { dataURL: dataURL })
.then((res) => {
setImgText(res.data.text); //이미지 데이터 텍스트
checkAnswer(res.data.text); //제출한 답
});
setCheckQuiz(true);
};
const clearCanvas = () => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
setOutputImageSrc(null);
setPaths([]);
setImgText("");
};
const returnCurrentLine = () => {
setPaths((prevPaths) => prevPaths.slice(0, -1));
};
const redrawCanvas = () => {
const canvas = canvasRef.current;
const ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
paths.forEach((p) => {
ctx.beginPath();
ctx.moveTo(p[0].x, p[0].y);
for (let i = 1; i < p.length; i++) {
ctx.lineTo(p[i].x, p[i].y);
}
ctx.stroke();
});
};
useEffect(redrawCanvas, [paths]);
const nextLevel = () => { //다음 레벨 함수
newFetch(); //새 이미지 데이터 불러오기
clearCanvas();
setCheckQuiz(false);
};
return (
<div className="canvas">
<canvas
ref={canvasRef}
width={500}
height={300}
style={{ border: "1px solid black" }}
onMouseDown={drawingCanvas}
onMouseUp={stopDrawing}
onMouseOut={canvasOut}
/>
{outputImageSrc && <img src={outputImageSrc} alt="분석된 이미지" />}
{!checkQuiz && (
<div>
<button onClick={outputCanvasImage}>추출</button>
<button onClick={clearCanvas}>다시 쓰기</button>
<button onClick={returnCurrentLine}>한 획 지우기</button>
</div>
)}
<div>
{checkQuiz && (
<div>
<h1>정답: {quiz}</h1>
<h1>제출한 답: {imgText}</h1>
<button onClick={nextLevel}>다음 레벨</button>
</div>
)}
</div>
</div>
);
}
export default Canvas;
page - Game - <ImageGame.js>
import axios from "axios";
import React, { useCallback, useEffect, useState } from "react";
import "../../css/game.css";
import Canvas from "./Canvas";
function ImageGame() {
const [imageData, setImagaData] = useState([]);
const [quiz, setQuiz] = useState("");
const [count, setCount] = useState(1);
const [gameOver, setGameOver] = useState(false);
const resetButton = () => {
window.location.reload();
};
const checkAnswer = (text) => {
if (text === quiz) {
alert("정답입니다.");
} else {
alert("오답입니다.");
}
};
const newFetch = () => { //새 데이터 불러오기 함수
fetchData();
};
const fetchData = useCallback(() => {
axios.get("http://localhost:5000/image").then((res) => {
if (res.data.game && res.data.game.length > 0) {
setImagaData(res.data.game[0].image);
setQuiz(res.data.game[0].title);
setCount(res.data.count);
if (count >= 5) {
setGameOver(true);
alert(res.data.message);
}
} else {
setGameOver(true);
alert(res.data.message);
}
});
}, [count]);
useEffect(() => {
fetchData();
}, []);
return (
<div className="image">
<div>
{gameOver ? (
<div>
<h1>Game Over</h1>
<button onClick={resetButton}>다시하기</button>
</div>
) : (
<div>
<div>
<img
alt="이미지"
src={`http://localhost:5000/file/${imageData}`}
/>
</div>
<h1>{count}</h1>
</div>
)}
</div>
{!gameOver && (
<div>
<Canvas checkAnswer={checkAnswer} newFetch={newFetch} quiz={quiz} />
</div>
)}
</div>
);
}
export default ImageGame;
'프로젝트 > 한글 게임' 카테고리의 다른 글
14. 재도전 기회 (0) | 2024.04.26 |
---|---|
13. 캔버스/타이핑 변환 (0) | 2024.04.26 |
11. 이미지 중복 방지, 횟수 제한 (0) | 2024.04.20 |
10. 이미지 데이터 가져오기 (0) | 2024.04.18 |
9. 이미지, 낱말 데이터 등록 (0) | 2024.04.17 |