Overnap

캔버스 그림 통신 구현

import React, { useCallback, useEffect, useRef, useState } from 'react';
import { Vector } from './types';
import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
import SocketContext from '../../contexts/SocketContext';
import { MessageType, RawMessage } from '../common/types';
import { BrushData, Vector } from './types';
// 참고 : https://basketdeveloper.tistory.com/79
......@@ -8,6 +10,7 @@ interface CanvasProps {
}
export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => {
const socket = useContext(SocketContext);
const canvasRef = useRef<HTMLCanvasElement>(null);
const [mousePosition, setMousePosition] = useState<Vector>({ x:0, y:0 });
......@@ -56,6 +59,22 @@ export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => {
if (coordinates) {
setIsPainting(true);
setMousePosition(coordinates);
const rawMessage: RawMessage = {
type: MessageType.DRAW_MOVE,
message: coordinates
};
socket.emit('msg', rawMessage, () => {});
const nextRawMessage: RawMessage = {
type: MessageType.DRAW_SET,
message: {
size: 5,
color: '000000',
drawing: true
} as BrushData
};
socket.emit('msg', nextRawMessage, () => {});
}
}, []);
......@@ -69,6 +88,13 @@ export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => {
const newMousePosition = getCoordinates(event);
if (mousePosition && newMousePosition) {
drawLine(mousePosition, newMousePosition);
const rawMessage: RawMessage = {
type: MessageType.DRAW_MOVE,
message: newMousePosition
};
socket.emit('msg', rawMessage, () => {});
setMousePosition(newMousePosition);
}
}
......@@ -77,32 +103,86 @@ export const Canvas: React.FC<CanvasProps> = ({ isDrawer }) => {
);
const exitPaint = useCallback(() => {
const rawMessage: RawMessage = {
type: MessageType.DRAW_SET,
message: {
size: 5,
color: '000000',
drawing: false
} as BrushData
};
socket.emit('msg', rawMessage, () => {});
setIsPainting(false);
}, []);
const handleDrawSet = useCallback((rawMessage: RawMessage) => {
if (rawMessage.type === MessageType.DRAW_SET) {
const data = rawMessage.message as BrushData;
setIsPainting(data.drawing);
}
}, []);
const handleDrawMove = useCallback((rawMessage: RawMessage) => {
if (rawMessage.type === MessageType.DRAW_MOVE) {
const data = rawMessage.message as Vector;
if (isPainting) {
drawLine(mousePosition, data);
}
setMousePosition(data);
}
}, [isPainting, mousePosition])
useEffect(() => {
if (canvasRef.current && isDrawer) {
const canvas: HTMLCanvasElement = canvasRef.current;
if (canvasRef.current) {
if (isDrawer) {
const canvas: HTMLCanvasElement = canvasRef.current;
canvas.addEventListener('mousedown', startPaint);
canvas.addEventListener('mousemove', paint);
canvas.addEventListener('mouseup', exitPaint);
canvas.addEventListener('mouseleave', exitPaint);
return () => {
canvas.removeEventListener('mousedown', startPaint);
canvas.removeEventListener('mousemove', paint);
canvas.removeEventListener('mouseup', exitPaint);
canvas.removeEventListener('mouseleave', exitPaint);
};
} else {
// 받아서 그리기
canvas.addEventListener('mousedown', startPaint);
canvas.addEventListener('mousemove', paint);
canvas.addEventListener('mouseup', exitPaint);
canvas.addEventListener('mouseleave', exitPaint);
return () => {
canvas.removeEventListener('mousedown', startPaint);
canvas.removeEventListener('mousemove', paint);
canvas.removeEventListener('mouseup', exitPaint);
canvas.removeEventListener('mouseleave', exitPaint);
};
}
}
}, [isDrawer, startPaint, paint, exitPaint]);
useEffect(() => {
if (!isDrawer) {
socket.on('msg', handleDrawSet);
socket.on('msg', handleDrawMove);
return () => {
socket.off('msg', handleDrawSet);
socket.off('msg', handleDrawMove);
}
}
}, [isDrawer, handleDrawMove]);
const handleClearWhenStart = useCallback((rawMessage: RawMessage) => {
if (rawMessage.type === MessageType.GAME_START) {
clearCanvas();
setIsPainting(false);
// TODO: 펜 굵기, 색 설정하게 되면 여기에 초기화 넣기
}
}, []);
useEffect(() => {
socket.on('msg', handleClearWhenStart);
return () => {
socket.off('msg', handleClearWhenStart);
}
}, []);
return (
<div className='mx-3 px-2 py-1 rounded shadow'>
<canvas ref={canvasRef} width='512' height='384' />
<canvas ref={canvasRef} width='640' height='480' />
</div>
);
}
\ No newline at end of file
......