Overnap

마우스 이벤트리스너 및 그림 그리기 기능 추가

1 import React, { useCallback, useEffect, useRef, useState } from 'react'; 1 import React, { useCallback, useEffect, useRef, useState } from 'react';
2 import { Vector } from './types'; 2 import { Vector } from './types';
3 3
4 +// 참고 : https://basketdeveloper.tistory.com/79
5 +
4 export const Canvas: React.FC = () => { 6 export const Canvas: React.FC = () => {
5 const canvasRef = useRef<HTMLCanvasElement>(null); 7 const canvasRef = useRef<HTMLCanvasElement>(null);
6 8
9 + const [mousePosition, setMousePosition] = useState<Vector>({ x:0, y:0 });
10 + const [isPainting, setIsPainting] = useState(false);
11 +
7 const getCoordinates = useCallback((event: MouseEvent): Vector | undefined => { 12 const getCoordinates = useCallback((event: MouseEvent): Vector | undefined => {
8 if (!canvasRef.current) { 13 if (!canvasRef.current) {
9 return; 14 return;
...@@ -33,6 +38,53 @@ export const Canvas: React.FC = () => { ...@@ -33,6 +38,53 @@ export const Canvas: React.FC = () => {
33 } 38 }
34 }, []); 39 }, []);
35 40
41 + const startPaint = useCallback((event: MouseEvent) => {
42 + const coordinates = getCoordinates(event);
43 + if (coordinates) {
44 + setIsPainting(true);
45 + setMousePosition(coordinates);
46 + }
47 + }, []);
48 +
49 + const paint = useCallback(
50 + (event: MouseEvent) => {
51 + // 드래그 방지
52 + event.preventDefault();
53 + event.stopPropagation();
54 +
55 + if (isPainting) {
56 + const newMousePosition = getCoordinates(event);
57 + if (mousePosition && newMousePosition) {
58 + drawLine(mousePosition, newMousePosition);
59 + setMousePosition(newMousePosition);
60 + }
61 + }
62 + },
63 + [isPainting, mousePosition]
64 + );
65 +
66 + const exitPaint = useCallback(() => {
67 + setIsPainting(false);
68 + }, []);
69 +
70 + useEffect(() => {
71 + if (canvasRef.current) {
72 + const canvas: HTMLCanvasElement = canvasRef.current;
73 +
74 + canvas.addEventListener('mousedown', startPaint);
75 + canvas.addEventListener('mousemove', paint);
76 + canvas.addEventListener('mouseup', exitPaint);
77 + canvas.addEventListener('mouseleave', exitPaint);
78 +
79 + return () => {
80 + canvas.removeEventListener('mousedown', startPaint);
81 + canvas.removeEventListener('mousemove', paint);
82 + canvas.removeEventListener('mouseup', exitPaint);
83 + canvas.removeEventListener('mouseleave', exitPaint);
84 + };
85 + }
86 + }, [startPaint, paint, exitPaint]);
87 +
36 return ( 88 return (
37 <div className='mx-3 px-2 py-1 rounded shadow'> 89 <div className='mx-3 px-2 py-1 rounded shadow'>
38 <canvas ref={canvasRef} width='512' height='384' /> 90 <canvas ref={canvasRef} width='512' height='384' />
......