Поддерживаются многостраничные PDF и изображения PNG / JPG
Бесплатная доска без лагов
Пригласите друзей в режиме редактора или наблюдателя
Участники по этой ссылке могут рисовать, двигать фигуры и загружать PDF/PNG файлы.
Участники видят все изменения в реальном времени, могут приближать и двигать камеру, но не могут редактировать.
Простая регистрация без почты и СМС
Регистрация необязательна — она нужна только чтобы закреплять и сохранять список своих досок за вашим ником.
Вы вошли как
@user
Управление вашими рабочими пространствами
Готовый WebSocket + HTTP сервер на Node.js для мгновенной синхронизации
server.js (код ниже), ваш ПК станет полноценным сервером досок с WebSocket-синхронизацией между всеми подключившимися людьми.
server.js (Node.js):
const http = require('http');
const fs = require('fs');
const path = require('path');
const { WebSocketServer } = require('ws');
const PORT = process.env.PORT || 3000;
const boards = new Map(); // Хранение состояния досок в RAM
const server = http.createServer((req, res) => {
// Раздаем freeboard.html по корневому адресу
if (req.url === '/' || req.url.startsWith('/?')) {
fs.readFile(path.join(__dirname, 'freeboard.html'), (err, data) => {
if (err) {
res.writeHead(500);
return res.end('Put freeboard.html in the same folder as server.js');
}
res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
res.end(data);
});
} else {
res.writeHead(404);
res.end('Not found');
}
});
const wss = new WebSocketServer({ server });
wss.on('connection', (ws) => {
let currentBoardId = 'default';
ws.on('message', (raw) => {
try {
const msg = JSON.parse(raw);
if (msg.type === 'join') {
currentBoardId = msg.boardId || 'default';
ws.boardId = currentBoardId;
if (boards.has(currentBoardId)) {
ws.send(JSON.stringify({ type: 'sync', state: boards.get(currentBoardId) }));
}
} else if (msg.type === 'update' && msg.boardId) {
boards.set(msg.boardId, msg.state);
// Рассылаем обновление всем участникам на этой же доске
wss.clients.forEach((client) => {
if (client !== ws && client.readyState === 1 && client.boardId === msg.boardId) {
client.send(JSON.stringify({ type: 'sync', state: msg.state }));
}
});
}
} catch (e) {}
});
});
server.listen(PORT, '0.0.0.0', () => {
console.log(`FreeBoard запущен: http://localhost:${PORT}`);
});
freeboard.html и server.js.npm i ws && node server.jsЧтобы сайт открывался мгновенно и в России, и в Европе без блокировок провайдеров, используйте tuna.am, localtonet или связку FRP + дешёвый VPS (подробная инструкция приведена в чате ниже).