HTML Canvas:两个客户端同时编写

时间:2014-01-18 20:31:58

标签: javascript html5 node.js canvas html5-canvas

我在使用 nodejs 作为服务器之间的服务器实现在线 HTML5 Canvas时遇到了问题。

单个用户可以单独绘画没有问题,但当其他客户端进入时,同时绘制时,会发生以下情况: HTML5 Canvas problem with two clients

Client1 是第一个客户端鼠标的(X,Y)位置, Client2 是第二个客户端的(X,Y)位置。因此,当第二个客户端绘制时,我的程序在两点之间画一条线

在这里,您可以浏览客户端JS代码,其中 draw 函数负责绘制从nodejs服务器接收的数据:

App.draw = function(x, y, type, color, clear) {

    if(clear != true) {

        App.ctx.strokeStyle = color;

        if (type === "dragstart") {

            App.ctx.beginPath();

    //alert("Me muevo a X: " + x + " e Y: " + y);

            return App.ctx.moveTo(x, y);

        } else if (type === "drag") {

            App.ctx.lineTo(x, y);

            return App.ctx.stroke();

        } else {

            return App.ctx.closePath();
        }

    } else {

        // Store the current transformation matrix
        App.ctx.save();

        // Use the identity matrix while clearing the canvas
        App.ctx.setTransform(1, 0, 0, 1, 0, 0);
        App.ctx.clearRect(0, 0, App.canvas.width, App.canvas.height);

        // Restore the transform
        App.ctx.restore();

    }

};

1 个答案:

答案 0 :(得分:3)

当您共享相同的路径时,路径将由一组混合点组成,包括两个客户端。

为避免这种情况,您可以使用以下两种技术之一:

解决方案1 ​​

每次收到新点时(每个客户端)完全完成一次笔画。这会将当前路径减少到只有一个笔划:

App.ctx.beginPath();
App.ctx.moveTo(oldX, oldY);  /// previous point for this client
App.ctx.lineTo(x, y);
App.ctx.strokeStyle = color;
App.ctx.stroke();

解决方案2

使用两个相互叠加的画布。为每个客户分配一个图层。这样它们就完全相互独立,如果你需要将结果保存为图像,你可以根据需要将它们合并为一个:

<强> HTML:

<div class="wrapper">
    <canvas id="client1" ... ></canvas>
    <canvas id="client2" ... ></canvas>
</div>

<强> CSS:

.wrapper {
    position:relative;
    }
.wrapper > canvas {
    position:absolute;
    left:0;
    top:0;
    }

然后使用分配给每个客户端的不同上下文变量。一种方法可以是:

App.ctx = [ctx1, ctx2];

然后在你的函数中使用参数client作为索引(在这种情况下为0或1):

App.draw = function(client, x, y, type, color, clear) {

    if(clear != true) {

        App.ctx[client].strokeStyle = color;

        if (type === "dragstart") {

            App.ctx[client].beginPath();

    //alert("Me muevo a X: " + x + " e Y: " + y);

            return App.ctx[client].moveTo(x, y);

        } else if (type === "drag") {

            App.ctx[client].lineTo(x, y);
            App.ctx[client].stroke();     /// this has no return value

            return;

        } else {

            App.ctx[client].closePath();
            return
        }

    } else {

        // Store the current transformation matrix
        App.ctx[client].save();

        // Use the identity matrix while clearing the canvas
        App.ctx[client].setTransform(1, 0, 0, 1, 0, 0);
        App.ctx[client].clearRect(0, 0, App.canvas.width, App.canvas.height);

        // Restore the transform
        App.ctx[client].restore();
    }
};

希望这有帮助。