暂时没有橡皮擦功能,可以扩展,仅作为一个模板
效果图
cavs.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多人画板</title>
</head>
<body>
<div class="container">
<p>
问:为什么没有之前的记录,答:之前傻到用mysql去存画板信息把e盘玩炸了就把储存删了
现在取在线最长用户的画板去给
</p>
</div>
<canvas style="border: none; " id="canvas" width="800" height="600" style="border: 1px solid #000;"></canvas>
<div>
<!-- <button onclick="clearMy()">清除1</button> -->
<button onclick="clearAll()">清除所有</button>
<label>画笔粗细:</label>
<input type="range" min="1" max="20" value="5" onchange="setLineWidth(this.value)">
<label>画笔颜色:</label>
<input type="color" value="#000000" onchange="setLineColor(this.value)">
<!-- <button onclick="fill()">填充纯色</button> -->
</div>
<button onclick="sendmap()">投射</button>
</div>
<script>
//这里投射的意思就是把自己的画板发出去给别人,投射的自动会调
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
// var socket = new WebSocket('ws://localhost:3003');
// 这里本地玩
var socket = new WebSocket('ws://192.168.2.218:3003');
//在局域网里分享这个画板请吧ip改成你的无线局域网ip cmd里输入ipconfig查看
var lineWidth = 5;
var lineColor = '#000000';
let previousState = null; // 记录之前用户的画板状态信息
function setLineWidth(width) {
lineWidth = width;
}
function setLineColor(color) {
lineColor = color;
}
function clearMy() {
socket.send(JSON.stringify({ action: 'clearMy' }));
}
function clearAll() {
context.clearRect(0, 0, canvas.width, canvas.height);
socket.send(JSON.stringify({ action: 'clearAll' }));
}
function fill() {
socket.send(JSON.stringify({ action: 'fill' }));
}
canvas.addEventListener('mousedown', function (e) {
var x = e.pageX - canvas.offsetLeft;
var y = e.pageY - canvas.offsetTop;
context.beginPath();
context.moveTo(x, y);
socket.send(JSON.stringify({
action: 'start',
x: x,
y: y,
}));
});
canvas.addEventListener('mousemove', function (e) {
var x = e.pageX - canvas.offsetLeft;
var y = e.pageY - canvas.offsetTop;
if (e.buttons === 1) {
context.lineTo(x, y);
context.lineWidth = lineWidth;
context.strokeStyle = lineColor;
context.stroke();
socket.send(JSON.stringify(
{
action: 'draw',
x: x,
y: y,
lineWidth: lineWidth,
lineColor: lineColor,
}));
}
});
socket.onmessage = function (event) {
if (event.data == "有新用户来了") {
// 这里就草草了事了,勿喷
sendmap()
}
var data = JSON.parse(event.data);
drawCavs(data)
};
function drawCavs(data) {
switch (data.action) {
case 'start':
context.beginPath();
context.moveTo(data.x, data.y);
break;
case 'draw':
context.lineTo(data.x, data.y);
context.lineWidth = data.lineWidth;
context.strokeStyle = data.lineColor;
context.stroke();
break;
case 'clearMy':
context.clearRect(0, 0, canvas.width, canvas.height);
break;
case 'clearAll':
context.clearRect(0, 0, canvas.width, canvas.height);
break;
case 'map':
let cavsdata = data.cavsdata;
console.log(cavsdata)
let imageDataArray = new Uint8ClampedArray(cavsdata.data);
let newImageData = context.createImageData(cavsdata.width, cavsdata.height);
console.log(imageDataArray, "创建了像素数组")
for (var i = 0; i < imageDataArray.length; i += 4) {
newImageData.data[i] = imageDataArray[i];
newImageData.data[i + 1] = imageDataArray[i + 1];
newImageData.data[i + 2] = imageDataArray[i + 2];
newImageData.data[i + 3] = imageDataArray[i + 3];
}
console.log(newImageData);
context.putImageData(newImageData, 0, 0);
break;
}
}
function sendmap() {
//发送自己的画板信息
let cavsdata = context.getImageData(0, 0, canvas.width, canvas.height);
console.log(cavsdata)
let dataToSend = {
width: cavsdata.width,
height: cavsdata.height,
data: Array.from(cavsdata.data)
// // 将像素数据数组转换为普通数组
};
socket.send(JSON.stringify({
action: 'map',
cavsdata: dataToSend
}));
}
// 如果你想研究下兼容手机的触摸操作也可
</script>
</body>
</html>
cavs.js(node的js,使用前请安装ws库) npm i ws
var WebSocket = require('ws');
var wss = new WebSocket.Server({ port: 3003 });
const storage = {}; // 创建对象来存储每个用户的画板状态
console.log('// - 3003端口 画板服务开启..');
var DrawAry = [];
wss.on('connection', function connection(ws) {
console.log('客户端连接--'); //打印客户端连接
// 当客户端连接给这个新的客户端发送
// ws.send("欢迎");
getmapu();
ws.onlineTime = new Date();
var id = ''; // add a var to store the id
ws.on('message', function incoming(message) {
var data = JSON.parse(message);
switch (data.action) {
case 'start':
case 'draw':
case 'clearMy':
case 'clearAll':
case 'map':
case 'fill':
wss.clients.forEach(function each(client) {
DrawAry.push(data)
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(data)); // 将数据转换为字符串后再发送
}
});
break;
}
});
function getmapu() {
// 拿到最老用户的画板内容,这里吧画板内容给所有人了,原计划是只给新人的,但是也草草了事了
var longestOnlineUser = null;
var maxOnlineTime = 0;
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
var onlineTime = new Date() - client.onlineTime;
if (onlineTime > maxOnlineTime) {
maxOnlineTime = onlineTime;
longestOnlineUser = client;
}
}
});
if (longestOnlineUser) {
longestOnlineUser.send('有新用户来了');
}
}
});