react-board-drawing-hook 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,246 @@
1
+ # 🎨 React Board Drawing Hook
2
+
3
+ [![npm version](https://img.shields.io/npm/v/react-board-drawing-hook.svg)](https://www.npmjs.com/package/react-board-drawing-hook)
4
+ [![npm downloads](https://img.shields.io/npm/dm/react-board-drawing-hook.svg)](https://www.npmjs.com/package/react-board-drawing-hook)
5
+ [![license](https://img.shields.io/npm/l/react-board-drawing-hook.svg)](https://github.com/yourusername/react-board-drawing-hook/blob/main/LICENSE)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue.svg)](https://www.typescriptlang.org/)
7
+
8
+ React Ρ…ΡƒΠΊ для создания ΠΊΠΎΠ»Π»Π°Π±ΠΎΡ€Π°Ρ‚ΠΈΠ²Π½ΠΎΠΉ Ρ€ΠΈΡΠΎΠ²Π°Π»ΡŒΠ½ΠΎΠΉ доски с ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ WebSocket.
9
+ ИдСально ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для ΠΎΠ½Π»Π°ΠΉΠ½-досок, рисовалок ΠΈ real-time совмСстной Ρ€Π°Π±ΠΎΡ‚Ρ‹.
10
+
11
+ ## ✨ ВозмоТности
12
+
13
+ - πŸ–±οΈ **Полная ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° ΠΌΡ‹ΡˆΠΈ** - рисованиС, ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅, ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€Π°, Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅
14
+ - 🎨 **Π Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ инструмСнты** - ΠΊΠΈΡΡ‚ΡŒ, Π»ΠΈΠ½ΠΈΠΈ, ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊΠΈ, ΠΊΡ€ΡƒΠ³ΠΈ, тСкст, изобраТСния
15
+ - πŸ”’ **Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ²** - ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠ΅ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅
16
+ - 🌐 **Π›ΡŽΠ±ΠΎΠΉ WebSocket** - Socket.IO, Native WebSocket, ΠΈΠ»ΠΈ свой Π°Π΄Π°ΠΏΡ‚Π΅Ρ€
17
+ - πŸ“¦ **TypeScript** - полная типизация
18
+ - ⚑ **ΠŸΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ** - ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Π΅ пСрСрисовки
19
+ - 🎯 **Π›Π΅Π³ΠΊΠΈΠΉ** - 0 зависимостСй (ΠΊΡ€ΠΎΠΌΠ΅ React)
20
+
21
+ ## πŸ“¦ Установка
22
+
23
+ ```bash
24
+ npm install react-board-drawing-hook
25
+ # ΠΈΠ»ΠΈ
26
+ yarn add react-board-drawing-hook
27
+ ```
28
+
29
+ ## πŸš€ Быстрый старт
30
+
31
+ ### 1. ΠŸΡ€ΠΎΡΡ‚ΠΎΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π±Π΅Π· сСрвСра
32
+
33
+ ```tsx
34
+ import {
35
+ useBoardDrawing,
36
+ NativeWebSocketAdapter,
37
+ } from 'react-board-drawing-hook';
38
+
39
+ function Whiteboard() {
40
+ const canvasRef = useRef(null);
41
+ const wsAdapter = new NativeWebSocketAdapter('ws://localhost:8080');
42
+
43
+ const {
44
+ tool,
45
+ setTool,
46
+ handleMouseDown,
47
+ handleMouseMove,
48
+ handleMouseUp,
49
+ objects,
50
+ } = useBoardDrawing({
51
+ boardId: 'room-123',
52
+ userId: 1,
53
+ userName: 'Alice',
54
+ canvasRef,
55
+ webSocketService: wsAdapter,
56
+ });
57
+
58
+ return (
59
+ <div>
60
+ <div className='toolbar'>
61
+ <button onClick={() => setTool('pen')}>✏️ Pen</button>
62
+ <button onClick={() => setTool('rectangle')}>⬜ Rectangle</button>
63
+ <button onClick={() => setTool('circle')}>βšͺ Circle</button>
64
+ <button onClick={() => setTool('text')}>πŸ“ Text</button>
65
+ </div>
66
+
67
+ <canvas
68
+ ref={canvasRef}
69
+ width={1920}
70
+ height={1080}
71
+ style={{ width: '100%', height: '600px', border: '1px solid #ccc' }}
72
+ onMouseDown={handleMouseDown}
73
+ onMouseMove={handleMouseMove}
74
+ onMouseUp={handleMouseUp}
75
+ onMouseLeave={handleMouseUp}
76
+ />
77
+ </div>
78
+ );
79
+ }
80
+ ```
81
+
82
+ ### 2. Π‘ Socket.IO
83
+
84
+ ```tsx
85
+ import {
86
+ useBoardDrawing,
87
+ SocketIOBoardAdapter,
88
+ } from 'react-board-drawing-hook';
89
+
90
+ const adapter = new SocketIOBoardAdapter({
91
+ url: 'https://your-server.com',
92
+ path: '/socket.io',
93
+ reconnection: true,
94
+ });
95
+
96
+ function App() {
97
+ return <Whiteboard />; // Π’ΠΎΡ‚ ΠΆΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚
98
+ }
99
+ ```
100
+
101
+ ## πŸ“– API
102
+
103
+ ### `useBoardDrawing(props)`
104
+
105
+ #### ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹
106
+
107
+ | ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ | Π’ΠΈΠΏ | ΠžΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ | ОписаниС |
108
+ | ------------------ | ------------------------------ | ------------ | ----------------- |
109
+ | `boardId` | `string \| number` | βœ… | ID доски |
110
+ | `userId` | `number` | βœ… | ID ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ |
111
+ | `userName` | `string` | βœ… | Имя ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ |
112
+ | `canvasRef` | `RefObject<HTMLCanvasElement>` | βœ… | Бсылка Π½Π° canvas |
113
+ | `webSocketService` | `BoardWebSocketService` | βœ… | WebSocket Π°Π΄Π°ΠΏΡ‚Π΅Ρ€ |
114
+ | `config` | `BoardDrawingConfig` | ❌ | ΠšΠΎΠ½Ρ„ΠΈΠ³ΡƒΡ€Π°Ρ†ΠΈΡ |
115
+
116
+ #### Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅
117
+
118
+ ```typescript
119
+ {
120
+ // Бостояния
121
+ tool: DrawingTool;
122
+ color: string;
123
+ fillColor: string;
124
+ lineWidth: number;
125
+ fontSize: number;
126
+ isDrawing: boolean;
127
+ selectedObjectId: string | null;
128
+ interactionMode: InteractionMode;
129
+ objects: BoardObject[];
130
+ usersOnline: Array<{ id: number; name: string }>;
131
+ isConnected: boolean;
132
+ editingTextId: string | null;
133
+
134
+ // Π‘Π΅Ρ‚Ρ‚Π΅Ρ€Ρ‹
135
+ setTool: (tool: DrawingTool) => void;
136
+ setColor: (color: string) => void;
137
+ setFillColor: (color: string) => void;
138
+ setLineWidth: (width: number) => void;
139
+ setFontSize: (size: number) => void;
140
+ setSelectedObjectId: (id: string | null) => void;
141
+ setEditingTextId: (id: string | null) => void;
142
+
143
+ // ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΈ событий
144
+ handleMouseDown: (e: React.MouseEvent<HTMLCanvasElement>) => void;
145
+ handleMouseMove: (e: React.MouseEvent<HTMLCanvasElement>) => void;
146
+ handleMouseUp: (e: React.MouseEvent<HTMLCanvasElement>) => void;
147
+ handleDoubleClick: (e: React.MouseEvent<HTMLCanvasElement>) => void;
148
+
149
+ // ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹
150
+ deleteSelectedObject: () => void;
151
+ addImage: (imageUrl: string) => void;
152
+ updateObjectContent: (objectId: string, content: string) => void;
153
+ clearCanvas: () => void;
154
+ exportAsJSON: () => string;
155
+ importFromJSON: (json: string) => void;
156
+ redrawCanvas: () => void;
157
+ }
158
+ ```
159
+
160
+ ## πŸ”§ Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ своСго Π°Π΄Π°ΠΏΡ‚Π΅Ρ€Π°
161
+
162
+ ```ts
163
+ import { BaseWebSocketAdapter, BoardObject } from 'react-board-drawing-hook';
164
+
165
+ class MyCustomAdapter extends BaseWebSocketAdapter {
166
+ connect(boardId: string | number, userId: number, userName: string) {
167
+ // Π’Π°ΡˆΠ° рСализация
168
+ }
169
+
170
+ disconnect() {
171
+ // Π’Π°ΡˆΠ° рСализация
172
+ }
173
+
174
+ createObject(object: BoardObject) {
175
+ // Π’Π°ΡˆΠ° рСализация
176
+ }
177
+
178
+ // ... ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹
179
+ }
180
+ ```
181
+
182
+ ## 🎯 ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹
183
+
184
+ ### ИзмСнСниС Ρ€Π°Π·ΠΌΠ΅Ρ€Π° canvas
185
+
186
+ ```tsx
187
+ const { handleMouseDown, handleMouseMove, handleMouseUp } = useBoardDrawing({
188
+ // ...
189
+ config: {
190
+ canvasSize: {
191
+ width: 3840,
192
+ height: 2160,
193
+ },
194
+ },
195
+ });
196
+ ```
197
+
198
+ ### ΠžΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€Π½Ρ‹Ρ… сокращСний
199
+
200
+ ```tsx
201
+ const { ... } = useBoardDrawing({
202
+ // ...
203
+ config: {
204
+ enableKeyboardShortcuts: false,
205
+ enableGlobalListeners: false
206
+ }
207
+ });
208
+ ```
209
+
210
+ ### Π—Π°Π³Ρ€ΡƒΠ·ΠΊΠ° изобраТСния
211
+
212
+ ```tsx
213
+ const { addImage } = useBoardDrawing({ ... });
214
+
215
+ // Из input file
216
+ <input
217
+ type="file"
218
+ accept="image/*"
219
+ onChange={(e) => {
220
+ const file = e.target.files?.[0];
221
+ if (file) {
222
+ const url = URL.createObjectURL(file);
223
+ addImage(url);
224
+ }
225
+ }}
226
+ />
227
+
228
+ // По URL
229
+ <button onClick={() => addImage('https://example.com/image.jpg')}>
230
+ Add Image
231
+ </button>
232
+ ```
233
+
234
+ ## πŸ§ͺ ВСстированиС
235
+
236
+ ```bash
237
+ npm test
238
+ ```
239
+
240
+ ## πŸ“„ ЛицСнзия
241
+
242
+ MIT
243
+
244
+ ## 🀝 ΠšΠΎΠ½Ρ‚Ρ€ΠΈΠ±ΡŒΡŽΡ†ΠΈΡ
245
+
246
+ PRs ΠΏΡ€ΠΈΠ²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‚ΡΡ! Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ [CONTRIBUTING.md](CONTRIBUTING.md)
@@ -0,0 +1,254 @@
1
+ import * as react from 'react';
2
+
3
+ /**
4
+ * КОНБВАНВЫ Π₯ΠžΠ›Π‘Π’Π
5
+ */
6
+ declare const CANVAS_WIDTH = 1600;
7
+ declare const CANVAS_HEIGHT = 900;
8
+ /**
9
+ * ВИПЫ ΠžΠ‘ΠͺΠ•ΠšΠ’ΠžΠ’
10
+ */
11
+ type ObjectType = 'text' | 'image' | 'rectangle' | 'circle' | 'line' | 'pencil';
12
+ /**
13
+ * Π˜ΠΠ‘Π’Π Π£ΠœΠ•ΠΠ’Π« Π Π˜Π‘ΠžΠ’ΠΠΠ˜Π―
14
+ */
15
+ type DrawingTool = 'select' | 'pencil' | 'line' | 'rectangle' | 'circle' | 'text' | 'eraser';
16
+ /**
17
+ * Π Π•Π–Π˜ΠœΠ« Π’Π—ΠΠ˜ΠœΠžΠ”Π•Π™Π‘Π’Π’Π˜Π―
18
+ */
19
+ type InteractionMode = 'none' | 'move' | 'rotate' | 'resize' | 'draw';
20
+ /**
21
+ * ΠœΠΠ ΠšΠ•Π Π« Π˜Π—ΠœΠ•ΠΠ•ΠΠ˜Π― Π ΠΠ—ΠœΠ•Π Π
22
+ */
23
+ type ResizeHandle = 'nw' | 'ne' | 'sw' | 'se' | 'n' | 's' | 'e' | 'w' | 'rotate';
24
+ /**
25
+ * ВОЧКА НА Π₯ΠžΠ›Π‘Π’Π•
26
+ */
27
+ interface Point {
28
+ x: number;
29
+ y: number;
30
+ }
31
+ /**
32
+ * ΠžΠ‘ΠͺΠ•ΠšΠ’ НА Π”ΠžΠ‘ΠšΠ• (BoardObject)
33
+ */
34
+ interface BoardObject {
35
+ id: string;
36
+ type: ObjectType;
37
+ x: number;
38
+ y: number;
39
+ width: number;
40
+ height: number;
41
+ rotation: number;
42
+ locked_by: number | null;
43
+ locked_by_name: string | null;
44
+ content?: string;
45
+ fontSize?: number;
46
+ color?: string;
47
+ imageUrl?: string;
48
+ aspectRatio?: number;
49
+ fillColor?: string;
50
+ strokeColor?: string;
51
+ strokeWidth?: number;
52
+ x2?: number;
53
+ y2?: number;
54
+ points?: Point[];
55
+ userId?: number;
56
+ timestamp?: number;
57
+ }
58
+ /**
59
+ * ΠžΠ³Ρ€Π°Π½ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π³Ρ€Π°Π½ΠΈΡ†Π°ΠΌΠΈ холста.
60
+ */
61
+ declare function clampObjectToCanvas(obj: BoardObject): BoardObject;
62
+ /**
63
+ * ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠ΅Ρ‚, ΠΌΠΎΠΆΠ΅Ρ‚ Π»ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚.
64
+ */
65
+ declare function canEditObject(obj: BoardObject, userId: number): boolean;
66
+ /**
67
+ * Π“Π΅Π½Π΅Ρ€ΠΈΡ€ΡƒΠ΅Ρ‚ ΡƒΠ½ΠΈΠΊΠ°Π»ΡŒΠ½Ρ‹ΠΉ ID для Π½ΠΎΠ²ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°.
68
+ */
69
+ declare function generateObjectId(): string;
70
+ /**
71
+ * Π’Ρ€Π°Ρ‰Π°Π΅Ρ‚ Ρ‚ΠΎΡ‡ΠΊΡƒ Π²ΠΎΠΊΡ€ΡƒΠ³ Ρ†Π΅Π½Ρ‚Ρ€Π° Π½Π° Π·Π°Π΄Π°Π½Π½Ρ‹ΠΉ ΡƒΠ³ΠΎΠ».
72
+ */
73
+ declare function rotatePoint(x: number, y: number, cx: number, cy: number, angle: number): {
74
+ x: number;
75
+ y: number;
76
+ };
77
+ /**
78
+ * Π˜Π·ΠΌΠ΅Π½ΡΠ΅Ρ‚ Ρ€Π°Π·ΠΌΠ΅Ρ€ изобраТСния Π‘ БОΠ₯Π ΠΠΠ•ΠΠ˜Π•Πœ ΠŸΠ ΠžΠŸΠžΠ Π¦Π˜Π™.
79
+ */
80
+ declare function resizeImageWithAspectRatio(obj: BoardObject, handle: ResizeHandle, deltaX: number, deltaY: number, original: BoardObject): BoardObject;
81
+ /**
82
+ * Π‘Π’ΠžΠ‘ΠžΠ”ΠΠ«Π™ РЕБАЙЗ Π‘ ΠŸΠžΠ”Π”Π•Π Π–ΠšΠžΠ™ ΠŸΠ•Π Π•Π’ΠžΠ ΠžΠ’Π
83
+ */
84
+ declare function resizeObjectFree(obj: BoardObject, handle: ResizeHandle, deltaX: number, deltaY: number, original: BoardObject): BoardObject;
85
+ /**
86
+ * РЕБАЙЗ Π›Π˜ΠΠ˜Π˜
87
+ */
88
+ declare function resizeLineObject(obj: BoardObject, handle: ResizeHandle, deltaX: number, deltaY: number, original: BoardObject): BoardObject;
89
+ /**
90
+ * ВычисляСт Π³Ρ€Π°Π½ΠΈΡ†Ρ‹ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° (Bounding Box).
91
+ */
92
+ declare function getObjectBoundingBox(obj: BoardObject): {
93
+ minX: number;
94
+ minY: number;
95
+ maxX: number;
96
+ maxY: number;
97
+ };
98
+ /**
99
+ * ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° попадания Ρ‚ΠΎΡ‡ΠΊΠΈ Π² ΠΏΠΎΠ²Π΅Ρ€Π½ΡƒΡ‚Ρ‹ΠΉ ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ
100
+ */
101
+ declare function isPointInRotatedRectangle(x: number, y: number, obj: BoardObject): boolean;
102
+ /**
103
+ * РасстояниС ΠΎΡ‚ Ρ‚ΠΎΡ‡ΠΊΠΈ Π΄ΠΎ ΠΎΡ‚Ρ€Π΅Π·ΠΊΠ°
104
+ */
105
+ declare function distanceToLine(px: number, py: number, x1: number, y1: number, x2: number, y2: number): number;
106
+ /**
107
+ * ΠŸΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° попадания Ρ‚ΠΎΡ‡ΠΊΠΈ Π² ΠΎΠ±ΡŠΠ΅ΠΊΡ‚
108
+ */
109
+ declare function isPointInObject(x: number, y: number, obj: BoardObject, userId: number): boolean;
110
+
111
+ interface BoardEventHandlers {
112
+ onConnectionChange?: (connected: boolean) => void;
113
+ onObjectLocked?: (objectId: string, userId: number, userName: string) => void;
114
+ onObjectUnlocked?: (objectId: string) => void;
115
+ onObjectCreated?: (object: BoardObject) => void;
116
+ onObjectUpdated?: (object: BoardObject) => void;
117
+ onObjectDeleted?: (objectId: string) => void;
118
+ onUserJoined?: (userId: number, userName: string) => void;
119
+ onUserLeft?: (userId: number, userName: string) => void;
120
+ onError?: (error: Error, context?: any) => void;
121
+ }
122
+ interface BoardWebSocketService {
123
+ connect(boardId: string | number, userId: number, userName: string): void;
124
+ disconnect(): void;
125
+ isConnected(): boolean;
126
+ createObject(object: BoardObject): void;
127
+ updateObject(object: BoardObject): void;
128
+ deleteObject(objectId: string): void;
129
+ lockObject(objectId: string): void;
130
+ unlockObject(objectId: string): void;
131
+ setEventHandlers(handlers: BoardEventHandlers): void;
132
+ }
133
+ declare abstract class BaseWebSocketAdapter implements BoardWebSocketService {
134
+ protected handlers: BoardEventHandlers;
135
+ protected connected: boolean;
136
+ abstract connect(boardId: string | number, userId: number, userName: string): void;
137
+ abstract disconnect(): void;
138
+ abstract createObject(object: BoardObject): void;
139
+ abstract updateObject(object: BoardObject): void;
140
+ abstract deleteObject(objectId: string): void;
141
+ abstract lockObject(objectId: string): void;
142
+ abstract unlockObject(objectId: string): void;
143
+ isConnected(): boolean;
144
+ setEventHandlers(handlers: BoardEventHandlers): void;
145
+ protected handleError(error: Error, context?: any): void;
146
+ }
147
+
148
+ interface UseBoardDrawingProps {
149
+ boardId: string | number;
150
+ userId: number;
151
+ userName: string;
152
+ canvasRef: React.RefObject<HTMLCanvasElement | null>;
153
+ webSocketService: BoardWebSocketService;
154
+ onObjectsUpdated?: (objects: BoardObject[]) => void;
155
+ onObjectLocked?: (objectId: string, userId: number, userName: string) => void;
156
+ onObjectUnlocked?: (objectId: string) => void;
157
+ onUserJoined?: (userId: number, userName: string) => void;
158
+ onUserLeft?: (userId: number, userName: string) => void;
159
+ config?: {
160
+ enableKeyboardShortcuts?: boolean;
161
+ enableGlobalListeners?: boolean;
162
+ maxImageSize?: number;
163
+ defaultColors?: {
164
+ stroke?: string;
165
+ fill?: string;
166
+ lineWidth?: number;
167
+ fontSize?: number;
168
+ };
169
+ };
170
+ }
171
+ declare const useBoardDrawing: ({ boardId, userId, userName, canvasRef, webSocketService, onObjectLocked, onObjectUnlocked, onUserJoined, onUserLeft, config, }: UseBoardDrawingProps) => {
172
+ tool: DrawingTool;
173
+ color: string;
174
+ fillColor: string;
175
+ lineWidth: number;
176
+ fontSize: number;
177
+ isDrawing: boolean;
178
+ selectedObjectId: string | null;
179
+ interactionMode: InteractionMode;
180
+ objects: BoardObject[];
181
+ usersOnline: {
182
+ id: number;
183
+ name: string;
184
+ }[];
185
+ isConnected: boolean;
186
+ editingTextId: string | null;
187
+ setTool: react.Dispatch<react.SetStateAction<DrawingTool>>;
188
+ setColor: react.Dispatch<react.SetStateAction<string>>;
189
+ setFillColor: react.Dispatch<react.SetStateAction<string>>;
190
+ setLineWidth: react.Dispatch<react.SetStateAction<number>>;
191
+ setFontSize: react.Dispatch<react.SetStateAction<number>>;
192
+ setSelectedObjectId: react.Dispatch<react.SetStateAction<string | null>>;
193
+ setEditingTextId: react.Dispatch<react.SetStateAction<string | null>>;
194
+ handleMouseDown: (e: React.MouseEvent<HTMLCanvasElement>) => void;
195
+ handleMouseMove: (e: React.MouseEvent<HTMLCanvasElement>) => void;
196
+ handleMouseUp: (e: React.MouseEvent<HTMLCanvasElement>) => void;
197
+ handleDoubleClick: (e: React.MouseEvent<HTMLCanvasElement>) => void;
198
+ deleteSelectedObject: () => void;
199
+ addImage: (imageUrl: string) => void;
200
+ updateObjectContent: (objectId: string, content: string) => void;
201
+ clearCanvas: () => void;
202
+ exportAsJSON: () => string;
203
+ importFromJSON: (json: string) => void;
204
+ redrawCanvas: () => void;
205
+ };
206
+ declare global {
207
+ interface CanvasRenderingContext2D {
208
+ roundRect(x: number, y: number, w: number, h: number, r: number): CanvasRenderingContext2D;
209
+ }
210
+ }
211
+
212
+ declare class NativeWebSocketAdapter extends BaseWebSocketAdapter {
213
+ private ws;
214
+ private url;
215
+ private reconnectAttempts;
216
+ private maxReconnectAttempts;
217
+ private reconnectTimeout;
218
+ constructor(url: string);
219
+ connect(boardId: string | number, userId: number, userName: string): void;
220
+ private attemptReconnect;
221
+ private handleMessage;
222
+ disconnect(): void;
223
+ private send;
224
+ createObject(object: BoardObject): void;
225
+ updateObject(object: BoardObject): void;
226
+ deleteObject(objectId: string): void;
227
+ lockObject(objectId: string): void;
228
+ unlockObject(objectId: string): void;
229
+ }
230
+
231
+ interface SocketIOAdapterConfig {
232
+ url: string;
233
+ path?: string;
234
+ transports?: string[];
235
+ reconnection?: boolean;
236
+ reconnectionAttempts?: number;
237
+ reconnectionDelay?: number;
238
+ }
239
+ declare class SocketIOBoardAdapter extends BaseWebSocketAdapter {
240
+ private socket;
241
+ private config;
242
+ constructor(config: SocketIOAdapterConfig);
243
+ connect(boardId: string | number, userId: number, userName: string): void;
244
+ disconnect(): void;
245
+ createObject(object: BoardObject): void;
246
+ updateObject(object: BoardObject): void;
247
+ deleteObject(objectId: string): void;
248
+ lockObject(objectId: string): void;
249
+ unlockObject(objectId: string): void;
250
+ }
251
+
252
+ declare const VERSION = "1.0.0";
253
+
254
+ export { BaseWebSocketAdapter, BoardEventHandlers, BoardObject, BoardWebSocketService, CANVAS_HEIGHT, CANVAS_WIDTH, DrawingTool, InteractionMode, NativeWebSocketAdapter, ObjectType, Point, ResizeHandle, SocketIOAdapterConfig, SocketIOBoardAdapter, UseBoardDrawingProps, VERSION, canEditObject, clampObjectToCanvas, distanceToLine, generateObjectId, getObjectBoundingBox, isPointInObject, isPointInRotatedRectangle, resizeImageWithAspectRatio, resizeLineObject, resizeObjectFree, rotatePoint, useBoardDrawing };