HTML5画布:一起绘制

6
现在我正在使用HTML5画布开发绘图聊天程序,遇到了一个问题:两个或更多用户同时在同一画布上绘图。
画布每个属性只有一个实例,只有一个strokeStyle、一个fillStyle等等。当两位用户在同一画布上绘图时会产生混乱。
我尝试使用更多定位相同的画布,但何时以及如何交换两个画布的数据是一个问题。
有人知道其他方法吗,或者如何正确地在画布之间交换数据?
编辑:
我想我没有说清楚。现在我有画布、通过socket.io从服务器传来的消息和不同的绘画请求。当用户移动鼠标绘制线条时,画布现在获得lineWidth、strokeStyle、globalOpacity等。然而,由于画布一次只能有一个绘图者,来自服务器的绘画请求,包括另一种类型的绘图者,不能同时绘制。如果我们有足够多的用户,绘画将不流畅。
我打算编写一个队列或类似的东西来实现这个功能,但可能还有其他方法可以做到。

当您说“两个或更多用户在同一个画布上绘制”时,您是什么意思? - ExpExc
1个回答

7
每个客户端都需要向服务器发送绘图命令。服务器应该将这些命令广播给所有客户端。您需要一个方法来接收这些消息并进行绘制。
例如,如果用户可以设置诸如“笔划大小”和颜色等属性,则还需要广播这些更改。
您需要为用户的绘画注册鼠标监听器。它们应该调用用于绘画的方法,例如drawMoveTodrawLineTo,并且还应该在单个路径中缓冲这些命令,以便您可以在消息中向其他客户端广播完整的路径。
消息的示例可能包括:
{"clientId": 36, "penSize": 8, "color": "blue"}
{"clientId": 36, "command": {"moveTo", "x": 48, "y": 12}, 
                   "path": [{"moveTo", "x": 48, "y": 12}]}
{"clientId": 36, "command": {"lineTo", "x": 52, "y": 24}, 
                   "path": [{"lineTo", "x": 52, "y": 24}, 
                            {"moveTo", "x": 48, "y": 12}]}
{"clientId": 36, "command": {"lineTo", "x": 47, "y": 36}, 
                   "path": [{"lineTo", "x": 47, "y": 36},
                            {"lineTo", "x": 52, "y": 24},
                            {"moveTo", "x": 48, "y": 12}]}

你可以用一个数据结构来记录每个用户的"strokeAttributes"。然后,当你收到一条类型为moveTolineTo的消息时,你查询clientId以获取笔划属性,例如penSizecolor,然后调用与本地用户绘画时相同的方法,例如drawMoveTodrawLineTodraw方法必须根据消息(或鼠标侦听器)来自哪个客户端使用不同的笔画和属性。如果多个用户同时绘画,它将会变得很复杂。
建议使用WebSockets或者socket.io进行通信。
这里有一篇很好的文章,其中包含一个类似于你要求的应用程序的代码:基于纯JavaScript/HTML5/Canvas的多用户绘图板

我已经按照您所说的做了,或类似的操作。但是真正的问题在于我不知道如何很好地处理所有的绘画消息。我打算使用队列或类似的东西来实现不同用户的绘画。您对此有其他建议吗? - liuyanghejerry
1
你需要处理队列 - JS只提供单线程执行,所以如果某些事情恰好在同一时间发生或它们之间的差异小于10毫秒,则需要在服务器端解决。 - vincicat
我尝试按照 Jonas 描述的方式实现它,当一个用户在绘画时效果非常好,但是两个用户同时绘画时会产生奇怪的绘画图案。我认为为了让两个用户同时绘画,必须使用两个画布。这样说对吗? - Soroush Hakami
@SoroushHakami:不,你不需要两个画布来实现这个。 - Jonas
@SoroushHakami:在请求完成之前,您可以处理它。例如,如果用户在两分钟内画了一条长线,则应向服务器发送多个消息,并且其他客户端应该看到部分线条。每个消息中都有clientId,因此您可以看到消息来自哪个用户。 - Jonas
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接