본문 바로가기
프로젝트/한글 게임

2. 선 그리기

by 갱생angel 2024. 4. 11.

<추가사항>

※drawing 함수 추가 - 선 생성

※drawingCanvas 함수 추가 - 선 그리기

※stopDrawing 함수 추가 - 선 그리기 멈추기

※canvasOut 함수 추가 - 캔버스 밖으로 나갔을 시

※css 파일 삭제 - css를 적용하니 마우스 커서 위치 지정에 오류가 생김

 

마우스로 캔버스에 선을 그림

  -getBoundingClientRect() : 캔버스 내의 좌표를 가져오는 매서드

    -e.clientX : 마우스 이벤트가 발생한 X 좌표 위치 (브라우저 창 기준)

    -e.clientY : 마우스 이벤트가 발생한 Y 좌표 위치 (브라우저 창 기준)

    -rect.left : canvas 요소의 왼쪽 경계가 브라우저 창의 왼쪽 경계에서 얼마나 떨어져 있는지 

    -rect.top : canvas 요소의 위쪽 경계가 브라우저 창의 위쪽 경계에서 얼마나 떨어져 있는지 

 

캔버스 함수

  -beginPath() : 새로운 선을 생성

  -moveTo() : 선의 시작점을 설정

  -lineTo() : 선을 그림

  -stroke() : 실제 선을 나타냄

  -strokeStyle : 선의 색상을 지정

  -lineWidth : 선의 굵기를 지정

 

page - <Canvas.js>

 -onMouseDown: 마우스를 클릭했을 시 이벤트

 -onMouseUp: 마우스 클릭을 뗐을 시 이벤트

 -onMouseOut: 마우스 포인터가 요소 밖으로 나갔을 시 이벤트

import React, { useEffect, useRef, useState } from "react";

function Canvas() {
  const canvasRef = useRef(null);

  const [isDrawing, setIsDrawing] = useState(false); //선을 그리고 있는 지 여부를 지정

  const [lastX, setLastX] = useState(0); //선의 마지막 x좌표를 지정
  const [lastY, setLastY] = useState(0); //선의 마지막 y좌표를 지정

  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; //캔버스 내에서 마우스 커서의 x좌표
      const offsetY = e.clientY - rect.top; //캔버스 내에서 마우스 커서의 y좌표
      
      //offsetX는 마우스 이벤트가 발생한 X 좌표(e.clientX)에서
      //canvas 요소의 왼쪽 경계(rect.left)를 뺀 값으로, 캔버스 내에서의 X 좌표를 나타냄.
      //offsetY는 마우스 이벤트가 발생한 Y 좌표(e.clientY)에서 
      //canvas 요소의 위쪽 경계(rect.top)를 뺀 값으로, 캔버스 내에서의 Y 좌표를 나타냄.

      ctx.beginPath(); //새로운 선을 생성
      ctx.moveTo(lastX, lastY); //lastX, lastY를 선의 시작점을 설정
      ctx.lineTo(offsetX, offsetY); //offsetX, offsetY까지 선을 그림
      ctx.strokeStyle = "black"; //선의 색상을 검은색으로 지정
      ctx.lineWidth = 2; //선의 굵기를 2픽셀로 지정
      ctx.stroke(); //실제 선을 그려줌
      
      setLastX(offsetX); //다음 선을 그릴 때 offserX로 시작점을 업데이트
      setLastY(offsetY); //다음 선을 그릴 때 offserY로 시작점을 업데이트

      //moveTo()로 이전 선의 끝점을 설정하고, lineTo()로 새로운 선을 그리고,
      //그리기 옵션(strokeStyle, lineWidth)을 설정한 후 stroke() 메서드로 선을 실제로 그림.
      //그린 선의 끝점을 새로운 시작점으로 설정하여 다음 선을 그릴 때 이어지도록 함.
    };

    canvas.addEventListener("mousemove", drawing); //마우스를 움직일 때 draw 함수 실행
    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);
  };
  //선 그리기를 멈추는 함수
  const stopDrawing = () => {
    setIsDrawing(false);
  };
  //캔버스 밖으로 나갔을 시 선 그리기를 멈추는 함수
  const canvasOut = () => {
    setIsDrawing(false);
  };

  return (
    <div>
      <canvas
        ref={canvasRef}
        width={500}
        height={500}
        style={{ border: "1px solid black" }}
        onMouseDown={drawingCanvas}
        onMouseUp={stopDrawing}
        onMouseOut={canvasOut}
      />
    </div>
  );
}

export default Canvas;

 

'프로젝트 > 한글 게임' 카테고리의 다른 글

6. Google Vision API  (0) 2024.04.14
5. 선 한 획 씩 삭제하기  (0) 2024.04.11
4. Canvas 다시 쓰기  (0) 2024.04.11
3. Canvas 이미지 추출  (0) 2024.04.11
1. Canvas  (0) 2024.04.11