Showing
1 changed file
with
98 additions
and
18 deletions
1 | -import React, { useCallback, useEffect, useRef, useState } from 'react'; | 1 | +import React, { useCallback, useContext, useEffect, useRef, useState } from 'react'; |
2 | -import { Vector } from './types'; | 2 | +import SocketContext from '../../contexts/SocketContext'; |
3 | +import { MessageType, RawMessage } from '../common/types'; | ||
4 | +import { BrushData, Vector } from './types'; | ||
3 | 5 | ||
4 | // 참고 : https://basketdeveloper.tistory.com/79 | 6 | // 참고 : https://basketdeveloper.tistory.com/79 |
5 | 7 | ||
... | @@ -8,6 +10,7 @@ interface CanvasProps { | ... | @@ -8,6 +10,7 @@ interface CanvasProps { |
8 | } | 10 | } |
9 | 11 | ||
10 | export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => { | 12 | export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => { |
13 | + const socket = useContext(SocketContext); | ||
11 | const canvasRef = useRef<HTMLCanvasElement>(null); | 14 | const canvasRef = useRef<HTMLCanvasElement>(null); |
12 | 15 | ||
13 | const [mousePosition, setMousePosition] = useState<Vector>({ x:0, y:0 }); | 16 | const [mousePosition, setMousePosition] = useState<Vector>({ x:0, y:0 }); |
... | @@ -56,6 +59,22 @@ export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => { | ... | @@ -56,6 +59,22 @@ export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => { |
56 | if (coordinates) { | 59 | if (coordinates) { |
57 | setIsPainting(true); | 60 | setIsPainting(true); |
58 | setMousePosition(coordinates); | 61 | setMousePosition(coordinates); |
62 | + | ||
63 | + const rawMessage: RawMessage = { | ||
64 | + type: MessageType.DRAW_MOVE, | ||
65 | + message: coordinates | ||
66 | + }; | ||
67 | + socket.emit('msg', rawMessage, () => {}); | ||
68 | + | ||
69 | + const nextRawMessage: RawMessage = { | ||
70 | + type: MessageType.DRAW_SET, | ||
71 | + message: { | ||
72 | + size: 5, | ||
73 | + color: '000000', | ||
74 | + drawing: true | ||
75 | + } as BrushData | ||
76 | + }; | ||
77 | + socket.emit('msg', nextRawMessage, () => {}); | ||
59 | } | 78 | } |
60 | }, []); | 79 | }, []); |
61 | 80 | ||
... | @@ -69,6 +88,13 @@ export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => { | ... | @@ -69,6 +88,13 @@ export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => { |
69 | const newMousePosition = getCoordinates(event); | 88 | const newMousePosition = getCoordinates(event); |
70 | if (mousePosition && newMousePosition) { | 89 | if (mousePosition && newMousePosition) { |
71 | drawLine(mousePosition, newMousePosition); | 90 | drawLine(mousePosition, newMousePosition); |
91 | + | ||
92 | + const rawMessage: RawMessage = { | ||
93 | + type: MessageType.DRAW_MOVE, | ||
94 | + message: newMousePosition | ||
95 | + }; | ||
96 | + socket.emit('msg', rawMessage, () => {}); | ||
97 | + | ||
72 | setMousePosition(newMousePosition); | 98 | setMousePosition(newMousePosition); |
73 | } | 99 | } |
74 | } | 100 | } |
... | @@ -77,32 +103,86 @@ export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => { | ... | @@ -77,32 +103,86 @@ export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => { |
77 | ); | 103 | ); |
78 | 104 | ||
79 | const exitPaint = useCallback(() => { | 105 | const exitPaint = useCallback(() => { |
106 | + const rawMessage: RawMessage = { | ||
107 | + type: MessageType.DRAW_SET, | ||
108 | + message: { | ||
109 | + size: 5, | ||
110 | + color: '000000', | ||
111 | + drawing: false | ||
112 | + } as BrushData | ||
113 | + }; | ||
114 | + socket.emit('msg', rawMessage, () => {}); | ||
115 | + | ||
80 | setIsPainting(false); | 116 | setIsPainting(false); |
81 | }, []); | 117 | }, []); |
82 | 118 | ||
119 | + const handleDrawSet = useCallback((rawMessage: RawMessage) => { | ||
120 | + if (rawMessage.type === MessageType.DRAW_SET) { | ||
121 | + const data = rawMessage.message as BrushData; | ||
122 | + setIsPainting(data.drawing); | ||
123 | + } | ||
124 | + }, []); | ||
125 | + | ||
126 | + const handleDrawMove = useCallback((rawMessage: RawMessage) => { | ||
127 | + if (rawMessage.type === MessageType.DRAW_MOVE) { | ||
128 | + const data = rawMessage.message as Vector; | ||
129 | + if (isPainting) { | ||
130 | + drawLine(mousePosition, data); | ||
131 | + } | ||
132 | + setMousePosition(data); | ||
133 | + } | ||
134 | + }, [isPainting, mousePosition]) | ||
135 | + | ||
83 | useEffect(() => { | 136 | useEffect(() => { |
84 | - if (canvasRef.current && isDrawer) { | 137 | + if (canvasRef.current) { |
85 | - const canvas: HTMLCanvasElement = canvasRef.current; | 138 | + if (isDrawer) { |
139 | + const canvas: HTMLCanvasElement = canvasRef.current; | ||
86 | 140 | ||
87 | - canvas.addEventListener('mousedown', startPaint); | 141 | + canvas.addEventListener('mousedown', startPaint); |
88 | - canvas.addEventListener('mousemove', paint); | 142 | + canvas.addEventListener('mousemove', paint); |
89 | - canvas.addEventListener('mouseup', exitPaint); | 143 | + canvas.addEventListener('mouseup', exitPaint); |
90 | - canvas.addEventListener('mouseleave', exitPaint); | 144 | + canvas.addEventListener('mouseleave', exitPaint); |
91 | - | 145 | + |
92 | - return () => { | 146 | + return () => { |
93 | - canvas.removeEventListener('mousedown', startPaint); | 147 | + canvas.removeEventListener('mousedown', startPaint); |
94 | - canvas.removeEventListener('mousemove', paint); | 148 | + canvas.removeEventListener('mousemove', paint); |
95 | - canvas.removeEventListener('mouseup', exitPaint); | 149 | + canvas.removeEventListener('mouseup', exitPaint); |
96 | - canvas.removeEventListener('mouseleave', exitPaint); | 150 | + canvas.removeEventListener('mouseleave', exitPaint); |
97 | - }; | 151 | + }; |
98 | - } else { | 152 | + } |
99 | - // 받아서 그리기 | ||
100 | } | 153 | } |
101 | }, [isDrawer, startPaint, paint, exitPaint]); | 154 | }, [isDrawer, startPaint, paint, exitPaint]); |
102 | 155 | ||
156 | + useEffect(() => { | ||
157 | + if (!isDrawer) { | ||
158 | + socket.on('msg', handleDrawSet); | ||
159 | + socket.on('msg', handleDrawMove); | ||
160 | + | ||
161 | + return () => { | ||
162 | + socket.off('msg', handleDrawSet); | ||
163 | + socket.off('msg', handleDrawMove); | ||
164 | + } | ||
165 | + } | ||
166 | + }, [isDrawer, handleDrawMove]); | ||
167 | + | ||
168 | + const handleClearWhenStart = useCallback((rawMessage: RawMessage) => { | ||
169 | + if (rawMessage.type === MessageType.GAME_START) { | ||
170 | + clearCanvas(); | ||
171 | + setIsPainting(false); | ||
172 | + // TODO: 펜 굵기, 색 설정하게 되면 여기에 초기화 넣기 | ||
173 | + } | ||
174 | + }, []); | ||
175 | + | ||
176 | + useEffect(() => { | ||
177 | + socket.on('msg', handleClearWhenStart); | ||
178 | + return () => { | ||
179 | + socket.off('msg', handleClearWhenStart); | ||
180 | + } | ||
181 | + }, []); | ||
182 | + | ||
103 | return ( | 183 | return ( |
104 | <div className='mx-3 px-2 py-1 rounded shadow'> | 184 | <div className='mx-3 px-2 py-1 rounded shadow'> |
105 | - <canvas ref={canvasRef} width='512' height='384' /> | 185 | + <canvas ref={canvasRef} width='640' height='480' /> |
106 | </div> | 186 | </div> |
107 | ); | 187 | ); |
108 | } | 188 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or login to post a comment