Javascript 使用nodeJS的跨浏览器画布未找到函数的签名

Javascript 使用nodeJS的跨浏览器画布未找到函数的签名,javascript,html,node.js,canvas,Javascript,Html,Node.js,Canvas,我试图在一个页面上构建一个画布,每当用户在其上绘制一些东西时,该画布就会自动更新。但是,下面的代码(来自index.html)似乎导致了错误 socket.on("drawn_complete",function(data){ ctx.putImageData(data.image,0,0); console.log("Everthing worked technically"); }); 以下是在我的控制台中输出的错误: Uncaught TypeError: Faile

我试图在一个页面上构建一个画布,每当用户在其上绘制一些东西时,该画布就会自动更新。但是,下面的代码(来自index.html)似乎导致了错误

  socket.on("drawn_complete",function(data){
    ctx.putImageData(data.image,0,0);
    console.log("Everthing worked technically");
});
以下是在我的控制台中输出的错误:

Uncaught TypeError: Failed to execute 'putImageData' on 'CanvasRenderingContext2D': No function was found that matched the signature provided
my data.image是从以下代码返回的内容:

ctx.getImageData(0,0,200,100); // ctx is canvas.getContext("2d")
这是我的html中的画布:

 <canvas id="myCanvas" width="200" height="100"
style="border:1px solid #000000;">
</canvas>
当用户在“我的画布”中按住并移动鼠标时,将显示绘图:

代码如下:

  c.onmousedown = function(evt){
moving = true
};
c.onmousemove = function(evt){
    if(moving == true)
    {
        console.log("holding and moving");

        var x = evt.clientX - rect.left;
        var y = evt.clientY - rect.top;
        console.log("X: " + x + " Y: " + y);
        ctx.fillRect(x,y,1,1);
        socket.emit("drawing",{"image": ctx.getImageData(0,0,200,100)});

    }
};
c.onmouseup = function(evt){
    moving = false;
};
更新

以下是enitre脚本:

<script>

window.onload = function(){
var socket = io.connect("http://localhost:1337");
socket.on("drawn_complete",function(data){
    ctx.putImageData(data.image,0,0);
    console.log("Everthing worked technically");
});


var c = document.getElementById("myCanvas");
var moving = false;
console.log(c);
 var ctx = c.getContext("2d");
 var rect = c.getBoundingClientRect();
c.onmousedown = function(evt){
moving = true
};
c.onmousemove = function(evt){
    if(moving == true)
    {
        console.log("holding and moving");

        var x = evt.clientX - rect.left;
        var y = evt.clientY - rect.top;
        console.log("X: " + x + " Y: " + y);
        ctx.fillRect(x,y,1,1);
        socket.emit("drawing",{"image": ctx.getImageData(0,0,200,100)});

    }
};
c.onmouseup = function(evt){
    moving = false;
};
};



</script>
看起来控制台仍然抛出相同的错误

更新(2) 正如@Palanik建议的那样,我尝试序列化对象。我知道下面的代码并不完全是他推荐的,但是我只想强调一些非常特别的东西:

发件人:

接受者

}))

这里有趣的一点是imageData的console.log打印出一个具有与imageData相同的确切属性的项目。高度、宽度和毛坯。请看这里:

{"height":100,"width":200,"data":{"0":0,"1":0,"2":0,"3":0,"4":0,"5 etc... }
从这里我可以看到,我可以拿回物体。如果我在java,一个演员就足够了

ImageData object = (ImageData) imageData // Is there a way to do this?

ImageData可能不可移植。在发送之前尝试序列化imagedata,并在接收端反序列化和创建imagedata

==更新===

比如:

发件人 接受者
imgData=ctx.getImageData(myData.width,myData.height);
对于(变量i=0;i

这是未经测试的代码。您可以尝试一下。

这里的解决方案是使用
canvas.toDataURL()

这将返回一个Base64编码的图像字符串(头部带有MIME类型和编码)

您可以愉快地将这些编码字符串传递给服务器或从服务器传递出去。
您也可以在常规HTML
中使用它们

此外,您还可以将
传递给dataurl
两个参数:

 canvas.toDataURL("image/jpeg", 0.5);`
其中,第一个参数是请求的文件类型,第二个参数是请求的图像质量级别(介于0和1之间)

但是,不能保证任何浏览器都会支持您所要求的内容,而且您可能会得到一个.png文件(不管怎样,这很可能是您在游戏中想要的透明文件)

另外,Android 2.2浏览器和更低版本、IE9以及我认为Mobile Safari 5.1(原始iPad)都不支持
。toDataURL


我对iPad的看法可能是错误的,但它们不支持其他结合使用的HTML5 API。

在客户端,如何初始化画布的
ctx
?@jibsales ctx=canvas.getContext(“2d”)对不起,我应该更具体一些。你在哪里?这可能与套接字还没有准备好有关。我已经包括了整个脚本。检查updates@bula当您进行更新时,您不必使用粗体:Update#并在进行一些更改后再次放入相同的代码。您可以编辑以前的文本并保留一个干净的问题,而不是将imagedata字符串化。使用宽度、高度和像素数据创建新的obj并将其序列化。稍后从宽度、高度和像素数据创建新的ImageData。如何在javascript中序列化对象?我所能找到的只是Stringif我只是觉得你可能对我的更新感兴趣,因为我觉得它真的很奇怪。如果我没有错的话,我想你的代码也会产生同样的结果?我已经试过了。结果是:Uncaught NotSupportedError:实现不支持请求的对象或操作类型。index.html:15(匿名函数)index.html:15 EventEmitter.emit socket.io.js:633 SocketNamespace.onPacket socket.io.js:2248 socket.onPacket socket.io.js:1930 Transport.onPacket socket.io.js:1332 Transport.onData socket.io.js:1303 websocket.onmessage这又是一个令人惊讶且深入的答案。谢谢,对不起。我认为接受这个答案会给你带来赏金。我已经给你赏金了。很抱歉,为什么要使用
toDataURL
技巧?提到“您可以使用另一个元素作为图像源”。@cherouvim如果您阅读问题中包含的代码,您将看到它是通过WebSocket传输的。这当然不是每个人都要考虑的问题;在另一个画布上使用画布或图像作为绘制操作的源完全可以。。。除非您试图通过WebSocket更新每个人的画布,或者进行编辑。或者,您可能希望通过云保存来保持状态。。。这背后有很多原因;它们只是不是特定的。
socket.on("drawn_complete",function(data){
imageData = JSON.parse(data.image);
console.log(imageData);
ctx.putImageData(imageData,0,0);
console.log("Everthing worked technically");
{"height":100,"width":200,"data":{"0":0,"1":0,"2":0,"3":0,"4":0,"5 etc... }
ImageData object = (ImageData) imageData // Is there a way to do this?
canvasData = ctx.getImageData(0,0,200,100)}
myData = {
        height : canvasData.height,
        width : canvasData.width,
        raw : canvasData.data
};
socket.emit("drawing",{"image": myData});
imgData = ctx.getImageData(myData.width, myData.height);
for (var i = 0; i < myData.raw.length) {
        imgData.data[i] = myData.raw[i];
}
ctx.putImageData(imgData, 0, 0);
var canvas = getMyCanvas(),
    ctx = canvas.getContext("2d"),
    encodedImageData = canvas.toDataURL(),
    image = new Image();

image.src = encodedImageData;
ctx.drawImage(image, x, y, w, h...);
 canvas.toDataURL("image/jpeg", 0.5);`