1
+ /* eslint-disable react-hooks/exhaustive-deps */
1
2
import { useEffect , useRef , useState } from "react" ;
2
3
import "./App.css" ;
3
4
import { io } from "socket.io-client" ;
@@ -7,60 +8,76 @@ const socket = io("http://localhost:8000");
7
8
import Sidebar from "./components/Sidebar" ;
8
9
import Canvas from "./components/Canvas" ;
9
10
import Menu from "./components/Menu" ;
11
+ import EraserCursor from "./components/EraserCursor" ;
12
+ import { useRecoilValue , useRecoilState } from "recoil" ;
13
+ import { eraserState , cursorPosition } from "./atoms" ;
10
14
11
15
function App ( ) {
12
-
13
- const [ showMenu , setShowMenu ] = useState ( false ) ;
14
-
15
- function toggleMenu ( ) {
16
+ const [ showMenu , setShowMenu ] = useState ( false ) ;
17
+ const eraserMode = useRecoilValue ( eraserState ) ;
18
+ const [ position , setPosition ] = useRecoilState ( cursorPosition ) ;
19
+ const [ ctx , setCtx ] = useState ( null ) ;
20
+ const [ startX , setStartX ] = useState ( 0 ) ;
21
+ const [ startY , setStartY ] = useState ( 0 ) ;
22
+ const [ isDrawing , setIsDrawing ] = useState ( false ) ;
23
+ const [ penColor , setPenColor ] = useState ( "#000000" ) ;
24
+
25
+ function toggleMenu ( ) {
16
26
setShowMenu ( ! showMenu ) ;
17
27
}
18
28
19
29
const canvasRef = useRef ( null ) ;
20
30
const sidebarRef = useRef ( null ) ;
21
- let color = '#000000'
22
- let ctx ;
23
- let canvas ;
24
31
let lineWidth ;
25
32
26
- function drawLine ( sx , sy , ex , ey , color , lineWidth ) {
33
+ function drawLine ( sx , sy , ex , ey , penColor , lineWidth ) {
27
34
ctx . moveTo ( sx , sy ) ;
28
35
ctx . lineTo ( ex , ey ) ;
29
36
ctx . lineCap = "round" ;
30
37
ctx . lineWidth = lineWidth ;
31
- ctx . strokeStyle = color ;
38
+ ctx . strokeStyle = penColor ;
32
39
ctx . stroke ( ) ;
33
40
}
34
41
35
- useEffect ( ( ) => {
36
- canvas = canvasRef . current ;
37
- let isDrawing = false ;
38
- let startX = 0 ;
39
- let startY = 0 ;
40
- ctx = canvas . getContext ( "2d" ) ;
41
-
42
- canvas . width = canvas . getBoundingClientRect ( ) . width ;
43
- canvas . height = canvas . getBoundingClientRect ( ) . height ;
42
+ useEffect ( ( ) => {
43
+ const canvas = canvasRef . current ;
44
+ if ( canvas ) {
45
+ const context = canvas . getContext ( "2d" ) ;
46
+ canvas . width = canvas . getBoundingClientRect ( ) . width ;
47
+ canvas . height = canvas . getBoundingClientRect ( ) . height ;
48
+ setCtx ( context ) ;
49
+ }
50
+ } , [ canvasRef . current ] ) ;
44
51
52
+ useEffect ( ( ) => {
53
+ if ( ! ctx ) return ;
54
+ const canvas = canvasRef . current ;
45
55
function handleMousemove ( e ) {
56
+ // if eraseMode is set the position of the eraser cursor
57
+ if ( eraserMode ) {
58
+ setPosition ( ( ) => ( { x : e . clientX , y : e . clientY } ) ) ;
59
+ }
60
+
46
61
if ( ! isDrawing ) return ;
47
62
const endX = e . clientX - canvas . getBoundingClientRect ( ) . left ;
48
63
const endY = e . clientY - canvas . getBoundingClientRect ( ) . top ;
49
- drawLine ( startX , startY , endX , endY , color ) ;
50
- socket . emit ( "draw" , { startX, startY, endX, endY, color , lineWidth } ) ;
51
- startX = endX ;
52
- startY = endY ;
64
+ drawLine ( startX , startY , endX , endY , penColor ) ;
65
+ socket . emit ( "draw" , { startX, startY, endX, endY, penColor , lineWidth } ) ;
66
+ setStartX ( endX ) ;
67
+ setStartY ( endY ) ;
53
68
}
54
69
55
70
function handleMousedown ( e ) {
56
- isDrawing = true ;
57
- startX = e . clientX - canvas . getBoundingClientRect ( ) . left ;
58
- startY = e . clientY - canvas . getBoundingClientRect ( ) . top ;
71
+ setIsDrawing ( true ) ;
72
+ let X = e . clientX - canvas . getBoundingClientRect ( ) . left ;
73
+ let Y = e . clientY - canvas . getBoundingClientRect ( ) . top ;
74
+ setStartX ( X ) ;
75
+ setStartY ( Y ) ;
59
76
}
60
77
function handleMouseup ( ) {
61
- isDrawing = false ;
62
- startX = 0 ;
63
- startY = 0 ;
78
+ setIsDrawing ( false ) ;
79
+ setStartX ( 0 ) ;
80
+ setStartY ( 0 ) ;
64
81
ctx . beginPath ( ) ;
65
82
}
66
83
@@ -73,7 +90,7 @@ function App() {
73
90
canvas . removeEventListener ( "mousedown" , handleMousedown ) ;
74
91
canvas . removeEventListener ( "mouseup" , handleMouseup ) ;
75
92
} ;
76
- } , [ color ] ) ;
93
+ } , [ penColor , eraserMode , position , ctx , isDrawing , startX , startY ] ) ;
77
94
78
95
useEffect ( ( ) => {
79
96
socket . on ( "draw" , ( data ) => {
@@ -82,62 +99,66 @@ function App() {
82
99
data . startY ,
83
100
data . endX ,
84
101
data . endY ,
85
- data . color ,
102
+ data . penColor ,
86
103
data . lineWidth
87
104
) ;
88
105
} ) ;
89
-
106
+
90
107
socket . on ( "clear" , ( ) => {
91
108
clearRect ( ) ;
92
109
} ) ;
93
-
94
- return ( ) => {
95
- socket . off ( "draw" ) ;
96
- socket . off ( "clear" ) ;
97
- }
98
- } , [ ] ) ;
110
+
111
+ return ( ) => {
112
+ socket . off ( "draw" ) ;
113
+ socket . off ( "clear" ) ;
114
+ } ;
115
+ } , [ socket , ctx ] ) ;
99
116
100
117
function clearRect ( ) {
101
- ctx . clearRect ( 0 , 0 , canvas . width , canvas . height ) ;
118
+ if ( ctx ) {
119
+ ctx . clearRect ( 0 , 0 , canvasRef . current . width , canvasRef . current . height ) ;
120
+ }
102
121
}
103
122
104
- function clearOnClick ( ) {
123
+ function clearOnClick ( ) {
105
124
clearRect ( ) ;
106
- socket . emit ( ' clear' )
125
+ socket . emit ( " clear" ) ;
107
126
}
108
127
109
128
function addStroke ( e ) {
110
129
if ( e . target . id === "penColor" ) {
111
130
const newColor = e . target . value ;
112
- color = newColor ;
113
- ctx . strokeStyle = newColor ;
114
-
131
+ setPenColor ( newColor ) ;
132
+ if ( ctx ) {
133
+ ctx . strokeStyle = newColor ;
134
+ }
115
135
}
116
136
}
117
137
118
138
function addLineWidth ( e ) {
119
139
if ( e . target . id === "lineWidth" ) {
120
140
lineWidth = e . target . value ;
121
- ctx . lineWidth = lineWidth ;
141
+ if ( ctx ) {
142
+ ctx . lineWidth = lineWidth ;
143
+ }
122
144
}
123
145
}
124
146
125
147
return (
126
148
< div id = "container" >
127
149
< Sidebar
128
150
addStroke = { addStroke }
129
-
130
151
addLineWidth = { addLineWidth }
131
152
clearOnClick = { clearOnClick }
132
153
ref = { sidebarRef }
133
154
id = "clear"
134
155
toggleMenu = { toggleMenu }
135
156
> </ Sidebar >
136
157
< Canvas canvasRef = { canvasRef } > </ Canvas >
158
+ { eraserMode && < EraserCursor > </ EraserCursor > }
137
159
{ showMenu && < Menu > </ Menu > }
138
160
</ div >
139
161
) ;
140
162
}
141
163
142
- export default App ;
143
-
164
+ export default App ;
0 commit comments