react-board-drawing-hook
v1.0.0
Published
🎨 Collaborative canvas drawing React hook with WebSocket support. Perfect for whiteboards, drawing apps, and real-time collaboration.
Maintainers
Readme
🎨 React Board Drawing Hook
React хук для создания коллаборативной рисовальной доски с поддержкой WebSocket. Идеально подходит для онлайн-досок, рисовалок и real-time совместной работы.
✨ Возможности
- 🖱️ Полная поддержка мыши - рисование, перемещение, изменение размера, вращение
- 🎨 Различные инструменты - кисть, линии, прямоугольники, круги, текст, изображения
- 🔒 Блокировка объектов - предотвращает одновременное редактирование
- 🌐 Любой WebSocket - Socket.IO, Native WebSocket, или свой адаптер
- 📦 TypeScript - полная типизация
- ⚡ Производительность - оптимизированные перерисовки
- 🎯 Легкий - 0 зависимостей (кроме React)
📦 Установка
npm install react-board-drawing-hook
# или
yarn add react-board-drawing-hook🚀 Быстрый старт
1. Простой пример без сервера
import {
useBoardDrawing,
NativeWebSocketAdapter,
} from 'react-board-drawing-hook';
function Whiteboard() {
const canvasRef = useRef(null);
const wsAdapter = new NativeWebSocketAdapter('ws://localhost:8080');
const {
tool,
setTool,
handleMouseDown,
handleMouseMove,
handleMouseUp,
objects,
} = useBoardDrawing({
boardId: 'room-123',
userId: 1,
userName: 'Alice',
canvasRef,
webSocketService: wsAdapter,
});
return (
<div>
<div className='toolbar'>
<button onClick={() => setTool('pen')}>✏️ Pen</button>
<button onClick={() => setTool('rectangle')}>⬜ Rectangle</button>
<button onClick={() => setTool('circle')}>⚪ Circle</button>
<button onClick={() => setTool('text')}>📝 Text</button>
</div>
<canvas
ref={canvasRef}
width={1920}
height={1080}
style={{ width: '100%', height: '600px', border: '1px solid #ccc' }}
onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove}
onMouseUp={handleMouseUp}
onMouseLeave={handleMouseUp}
/>
</div>
);
}2. С Socket.IO
import {
useBoardDrawing,
SocketIOBoardAdapter,
} from 'react-board-drawing-hook';
const adapter = new SocketIOBoardAdapter({
url: 'https://your-server.com',
path: '/socket.io',
reconnection: true,
});
function App() {
return <Whiteboard />; // Тот же компонент
}📖 API
useBoardDrawing(props)
Параметры
| Параметр | Тип | Обязательный | Описание |
| ------------------ | ------------------------------ | ------------ | ----------------- |
| boardId | string \| number | ✅ | ID доски |
| userId | number | ✅ | ID пользователя |
| userName | string | ✅ | Имя пользователя |
| canvasRef | RefObject<HTMLCanvasElement> | ✅ | Ссылка на canvas |
| webSocketService | BoardWebSocketService | ✅ | WebSocket адаптер |
| config | BoardDrawingConfig | ❌ | Конфигурация |
Возвращаемое значение
{
// Состояния
tool: DrawingTool;
color: string;
fillColor: string;
lineWidth: number;
fontSize: number;
isDrawing: boolean;
selectedObjectId: string | null;
interactionMode: InteractionMode;
objects: BoardObject[];
usersOnline: Array<{ id: number; name: string }>;
isConnected: boolean;
editingTextId: string | null;
// Сеттеры
setTool: (tool: DrawingTool) => void;
setColor: (color: string) => void;
setFillColor: (color: string) => void;
setLineWidth: (width: number) => void;
setFontSize: (size: number) => void;
setSelectedObjectId: (id: string | null) => void;
setEditingTextId: (id: string | null) => void;
// Обработчики событий
handleMouseDown: (e: React.MouseEvent<HTMLCanvasElement>) => void;
handleMouseMove: (e: React.MouseEvent<HTMLCanvasElement>) => void;
handleMouseUp: (e: React.MouseEvent<HTMLCanvasElement>) => void;
handleDoubleClick: (e: React.MouseEvent<HTMLCanvasElement>) => void;
// Методы
deleteSelectedObject: () => void;
addImage: (imageUrl: string) => void;
updateObjectContent: (objectId: string, content: string) => void;
clearCanvas: () => void;
exportAsJSON: () => string;
importFromJSON: (json: string) => void;
redrawCanvas: () => void;
}🔧 Создание своего адаптера
import { BaseWebSocketAdapter, BoardObject } from 'react-board-drawing-hook';
class MyCustomAdapter extends BaseWebSocketAdapter {
connect(boardId: string | number, userId: number, userName: string) {
// Ваша реализация
}
disconnect() {
// Ваша реализация
}
createObject(object: BoardObject) {
// Ваша реализация
}
// ... остальные методы
}🎯 Примеры
Изменение размера canvas
const { handleMouseDown, handleMouseMove, handleMouseUp } = useBoardDrawing({
// ...
config: {
canvasSize: {
width: 3840,
height: 2160,
},
},
});Отключение клавиатурных сокращений
const { ... } = useBoardDrawing({
// ...
config: {
enableKeyboardShortcuts: false,
enableGlobalListeners: false
}
});Загрузка изображения
const { addImage } = useBoardDrawing({ ... });
// Из input file
<input
type="file"
accept="image/*"
onChange={(e) => {
const file = e.target.files?.[0];
if (file) {
const url = URL.createObjectURL(file);
addImage(url);
}
}}
/>
// По URL
<button onClick={() => addImage('https://example.com/image.jpg')}>
Add Image
</button>🧪 Тестирование
npm test📄 Лицензия
MIT
🤝 Контрибьюция
PRs приветствуются! Читайте CONTRIBUTING.md
