Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML Canvas: Multiple getContext plotting at same time

I'm building a tool using websockets which allows multiple users to "draw" on each others' canvases. The user draws on a canvas, and an object containing mousedown/mouseup events and coordinates is pushed to other users instantaneously. This is then plotted on their canvases, which gives the effect of having multiple users drawing in the same place.

It works as described: you can watch somebody draw something, then draw something which will appear within their canvas. The problem occurs when you draw at the same moment as somebody else.

For each user, it creates a new context for each user's canvas using:

oekaki['canvas'] = document.getElementById('canvas');
oekaki['ctx'][unique_user_id] = oekaki['canvas'].getContext("2d");

When you draw at the same moment as another user, the canvases madly draw lines between your and their coordinates, despite it using the different contexts.

Why is this the case? Do I have to do something else to accommodate multiple lines being plotted at once? Is it not possible to create multiple contexts in this way?

Any help would be most appreciated.

like image 226
eddz Avatar asked Dec 07 '11 14:12

eddz


1 Answers

The HTML5 Canvas spec says, for getContext():

If the getContext() method has already been invoked on this element for the same contextId, return the same object as was returned that time, and abort these steps. The additional arguments are ignored.

You don't have a different context per user, it's the same one. The last path position is being altererd by each new event, and I'm guessing you're not using beginPath and moveTo to reset the path on each new event. Try something like this instead:

// on some event, want to draw to (x, y) now:
var ctx = oekaki.canvas.getContext('2d');
var user = oekaki.user[unique_user_id];
ctx.beginPath();
ctx.moveTo(user.lastX, user.lastY);
ctx.lineTo(x, y);
// ctx.strokeStyle = ..., ctx.stroke(), etc, etc...
user.lastX = x;
user.lastY = y;
like image 63
James Clark Avatar answered Sep 21 '22 23:09

James Clark