@@ -6,12 +6,13 @@ import React, {
6
6
useMemo ,
7
7
useRef ,
8
8
useEffect ,
9
+ useCallback ,
9
10
} from "react" ;
10
11
import Konva from "konva" ;
11
12
import { v4 as uuidv4 } from "uuid" ;
12
13
import { KonvaEventObject } from "konva/lib/Node" ;
13
14
import { Vector2d } from "konva/lib/types" ;
14
-
15
+ import { BoardMode } from "@/types/board" ;
15
16
type Props = {
16
17
children : React . ReactNode ;
17
18
} ;
@@ -20,14 +21,6 @@ export type UserCursor = {
20
21
x : number ;
21
22
y : number ;
22
23
} ;
23
- export type ModeType =
24
- | "drawing"
25
- | "erasing"
26
- | "selecting"
27
- | "shapes"
28
- | "panning"
29
- | "teams"
30
- | "text" ;
31
24
32
25
export type ShapeType = "rectangle" | "circle" | "arrow" ;
33
26
export type Point = Vector2d ;
@@ -39,8 +32,8 @@ interface BoardContextType {
39
32
setTextColor : ( color : string ) => void ;
40
33
currentLineId : string ;
41
34
setCurrentLineId : ( id : string ) => void ;
42
- mode : ModeType ;
43
- setMode : ( mode : ModeType ) => void ;
35
+ mode : BoardMode ;
36
+ setBoardMode : ( mode : BoardMode ) => void ;
44
37
selectedShapeIds : string [ ] ;
45
38
setSelectedShapeIds : ( ids : string [ ] | ( ( prev : string [ ] ) => string [ ] ) ) => void ;
46
39
isShapeSelected : ( id : string ) => boolean ;
@@ -55,6 +48,21 @@ interface BoardContextType {
55
48
isOnline : boolean ;
56
49
setIsOnline : ( online : boolean ) => void ;
57
50
getPointerPosition : ( e : KonvaEventObject < MouseEvent > ) => Point | null ;
51
+ localPoints : number [ ] ;
52
+ setLocalPoints : ( points : number [ ] | ( ( prev : number [ ] ) => number [ ] ) ) => void ;
53
+ stagePosition : Vector2d ;
54
+ setStagePosition : (
55
+ position : Vector2d | ( ( prev : Vector2d ) => Vector2d )
56
+ ) => void ;
57
+ resetStagePosition : ( ) => void ;
58
+ editingText : string | null ;
59
+ setEditingText : ( text : string | null ) => void ;
60
+ textPosition : Point | null ;
61
+ setTextPosition : ( position : Point | null ) => void ;
62
+ currentTextId : string | null ;
63
+ setCurrentTextId : ( id : string | null ) => void ;
64
+ textareaRef : React . RefObject < HTMLTextAreaElement > ;
65
+ isPanning : React . MutableRefObject < boolean > ;
58
66
}
59
67
60
68
export const BoardContext = createContext < BoardContextType > (
@@ -66,14 +74,58 @@ export const BoardContextProvider: React.FC<Props> = ({ children }) => {
66
74
useState < React . RefObject < Konva . Stage | null > | null > ( null ) ;
67
75
const [ brushColor , setBrushColor ] = useState < string > ( "rgb(0,0,0)" ) ;
68
76
const [ currentLineId , setCurrentLineId ] = useState < string > ( uuidv4 ( ) ) ;
69
- const [ mode , setMode ] = useState < ModeType > ( "selecting" ) ;
77
+ const [ mode , setMode ] = useState < BoardMode > ( "selecting" ) ;
70
78
const [ selectedShapeIds , setSelectedShapeIds ] = useState < string [ ] > ( [ ] ) ;
71
79
const [ brushSize , setBrushSize ] = useState < number > ( 2 ) ;
72
80
const [ shapeType , setShapeType ] = useState < ShapeType > ( "rectangle" ) ;
73
81
const [ shapeColor , setShapeColor ] = useState ( "rgb(0,0,0)" ) ;
74
82
const [ textColor , setTextColor ] = useState ( "rgb(0,0,0)" ) ;
75
83
const [ textFontSize , setTextFontSize ] = useState < number > ( 24 ) ;
76
84
const [ isOnline , setIsOnline ] = useState < boolean > ( true ) ;
85
+ const [ localPoints , setLocalPoints ] = useState < number [ ] > ( [ ] ) ;
86
+ const [ stagePosition , setStagePosition ] = useState < Vector2d > ( { x : 0 , y : 0 } ) ;
87
+ const [ editingText , setEditingText ] = useState < string | null > ( null ) ;
88
+ const [ textPosition , setTextPosition ] = useState < Point | null > ( null ) ;
89
+ const [ currentTextId , setCurrentTextId ] = useState < string | null > ( null ) ;
90
+ const textareaRef = useRef < HTMLTextAreaElement > ( null ) ;
91
+ const isPanning = useRef < boolean > ( false ) ;
92
+
93
+ const getCursorForMode = ( mode : BoardMode ) : string => {
94
+ switch ( mode ) {
95
+ case "panning" :
96
+ if ( isPanning . current ) {
97
+ return "grabbing" ;
98
+ }
99
+ return "grab" ;
100
+ case "erasing" :
101
+ return "crosshair" ;
102
+ case "text" :
103
+ return "text" ;
104
+ case "selecting" :
105
+ case "drawing" :
106
+ case "shapes" :
107
+ return "default" ;
108
+ default :
109
+ return "default" ;
110
+ }
111
+ } ;
112
+
113
+ const setBoardMode = useCallback ( ( mode : BoardMode ) => {
114
+ setMode ( mode ) ;
115
+ const container = document . querySelector ( ".konvajs-content" ) as HTMLElement ;
116
+ if ( container ) {
117
+ container . style . cursor = getCursorForMode ( mode ) ;
118
+ }
119
+ if ( mode !== "text" ) {
120
+ setEditingText ( null ) ;
121
+ setTextPosition ( null ) ;
122
+ setCurrentTextId ( null ) ;
123
+ }
124
+ } , [ ] ) ;
125
+
126
+ const resetStagePosition = useCallback ( ( ) => {
127
+ setStagePosition ( { x : 0 , y : 0 } ) ;
128
+ } , [ ] ) ;
77
129
78
130
const isShapeSelected = ( id : string ) : boolean => {
79
131
return selectedShapeIds . includes ( id ) ;
@@ -101,7 +153,7 @@ export const BoardContextProvider: React.FC<Props> = ({ children }) => {
101
153
currentLineId,
102
154
setCurrentLineId,
103
155
mode,
104
- setMode ,
156
+ setBoardMode ,
105
157
selectedShapeIds,
106
158
setSelectedShapeIds,
107
159
isShapeSelected,
@@ -118,6 +170,19 @@ export const BoardContextProvider: React.FC<Props> = ({ children }) => {
118
170
textFontSize,
119
171
setTextFontSize,
120
172
getPointerPosition,
173
+ localPoints,
174
+ setLocalPoints,
175
+ stagePosition,
176
+ setStagePosition,
177
+ resetStagePosition,
178
+ editingText,
179
+ setEditingText,
180
+ textPosition,
181
+ setTextPosition,
182
+ currentTextId,
183
+ setCurrentTextId,
184
+ textareaRef,
185
+ isPanning,
121
186
} ) ,
122
187
[
123
188
stageRef ,
@@ -134,6 +199,14 @@ export const BoardContextProvider: React.FC<Props> = ({ children }) => {
134
199
textFontSize ,
135
200
setTextFontSize ,
136
201
getPointerPosition ,
202
+ localPoints ,
203
+ setLocalPoints ,
204
+ stagePosition ,
205
+ resetStagePosition ,
206
+ editingText ,
207
+ textPosition ,
208
+ currentTextId ,
209
+ setBoardMode ,
137
210
]
138
211
) ;
139
212
0 commit comments