我几乎做了一个多用户的素描本。
我的问题是,由于我一次只能绘制一条线,所以如果有两个或更多用户同时绘制,则该线在鼠标之间跳跃。每个用户如何拥有自己的电话?
这是客户端JS代码。我知道它写得不好,但这是我第一次尝试。
document.addEventListener('DOMContentLoaded', function(event){
var startMoveX = new Array();
var startMoveY = new Array();
var socket = io.connect();
socket.on('draw',function(data){
outDraw(data);
});
canvas = document.getElementById('myCanvas');
ctx = canvas.getContext("2d");
ctx.canvas.width = window.innerWidth;
ctx.canvas.height = window.innerHeight;
var drawing = false;
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {
canvas.addEventListener('touchmove', function(e){
var mouseX = Math.round(e.targetTouches[0].clientX);
var mouseY = Math.round(e.targetTouches[0].clientY);
var status = document.getElementById('status');
status.innerHTML = mouseX+" | "+mouseY;
if(drawing) draw(e)
}, false);
canvas.addEventListener("touchstart", function (e) {
moveBol = true;
drawing = true;
startMoveX.pop();
startMoveY.pop();
startMoveX.push(Math.round(e.targetTouches[0].clientX));
startMoveY.push(Math.round(e.targetTouches[0].clientY));
ctx.moveTo(startMoveX[0], startMoveY[0]);
}, false);
canvas.addEventListener("touchend", function (e) {drawing = false;}, false);
canvas.addEventListener("mousecancel", function (e) {drawing = false;}, false);
} else {
canvas.addEventListener('mousemove', function(e){
var mouseX = e.clientX - ctx.canvas.offsetLeft;
var mouseY = e.clientY - ctx.canvas.offsetTop;
var status = document.getElementById('status');
status.innerHTML = mouseX+" | "+mouseY;
if(drawing) draw(e)
}, false);
canvas.addEventListener("mousedown", function (e) {
drawing = true;
moveBol = true;
startMoveX.pop();
startMoveY.pop();
startMoveX.push(e.clientX - ctx.canvas.offsetLeft);
startMoveY.push(e.clientY - ctx.canvas.offsetTop);
ctx.moveTo(startMoveX[0], startMoveY[0]);
}, false);
canvas.addEventListener("mouseup", function (e) {drawing = false;}, false);
canvas.addEventListener("mouseout", function (e) {drawing = false;}, false);
}
function draw(e) {
if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|BB|PlayBook|IEMobile|Windows Phone|Kindle|Silk|Opera Mini/i.test(navigator.userAgent)) {
cX = Math.round(e.targetTouches[0].clientX);
cY = Math.round(e.targetTouches[0].clientY);
} else {
cX = e.clientX - canvas.offsetLeft;
cY = e.clientY - canvas.offsetTop;
}
ctx.lineTo(cX, cY);
ctx.stroke();
if (moveBol){
socket.emit('draw',{x:cX,y:cY, preX: startMoveX[0], preY: startMoveY[0]});
console.log(moveBol);
moveBol = false;
} else {
socket.emit('draw',{x:cX,y:cY});
console.log(moveBol);
}
}
function outDraw(e) {
ctx.moveTo(e.preX, e.preY);
ctx.lineTo(e.x, e.y);
ctx.stroke();
}
});
最佳答案
您有两个选择。
每帧一次重画所有当前活动的绘制路径,并以屏幕外的画布为背景。一条线完成后,将该线绘制到背景上。使用requestAnimationFrame更新显示。
要么
仅使用beginPath绘制线段,但您需要保留上一点。
例如
// creates named users that draw to the canvas context ctx
ctx = canvas.getContext("2d"); // I assume canvas is in scope
var users = { // cant have users that start with _
_addUser(name){
if(typeof this[name] === "function"){
throw new ReferenceError("Can not use the user name '"+name+"'");
}
this[name] = {
lastX : null,
lastY : null,
draw(x,y){
ctx.beginPath();
ctx.moveTo(this.lastX,this.lastY);
ctx.lineTo(x,y);
ctx.stroke();
},
addPoint(x,y){
if(this.lastX !== null){ // new line start
this.draw(x,y);
}
this.lastX = x;
this.lastY = y;
},
endPoint(x,y){
if(this.lastX === null){ // incase it is just a point
this.lastX = x;
this.lastY = y;
}
this.draw(x,y);
this.lastX = null; // end the line
}
}
return this[name];
}
}
users._createUser("User1");
users._createUser("User2");
然后为任何用户绘制图形,您只需要用户名和点以及行结束的时间即可。
用于鼠标下移和跟随鼠标移动
user = "User1";
// mousemove and mousedown events should call
users[user].addPoint(x,y); // add a point if mouse is down
socket.send(JSON.stringify({user, x, y, type : "add"});
对于mouseup事件
// when the mouseup
users[user].endPoint(x,y);
socket.send(JSON.stringify({user, x, y, type : "end"});
用于获取套接字数据
// if from a socket (should have the user name or id passed with the packet)
// Assuming data is as a JSON string as above
socket.onmessage = function(event){
var data = JSON.parse(event.data); // should be wrapped in try catch and security checks
user = data.user; //
if(users[user]){
if(data.type === "add"){ // add point
users[user].addPoint(data.x, data.y); // add a point
}else if(data.type === "end"){
users[user].endPoint(data.x, data.y);
}
}
}
关于javascript - 如何在一个2d Canvas 上下文中一次绘制多条线?多用户画板,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42013911/