2012-07-18 126 views
2

我想破坏一张spritesheet,并且不会像它应该将它放入二维数组中。在我的代码结尾,console.log附近,它吐出ImageData ...但是当它试图putImageData ...我得到Uncaught TypeError: Type errorJavaScript - 未捕获TypeError:类型错误

帮助?

,这里是我的代码:

$(document).ready(function() { 
    console.log("Client setup..."); 
    canvas = document.getElementById("canvas"); 
    context = canvas.getContext("2d"); 
    canvas.tabIndex = 0; 
    canvas.focus(); 
    console.log("Client focused."); 

    var imageObj = new Image(); 
    imageObj.src = "./images/all_tiles.png"; 
    imageObj.onload = function() { 
    context.drawImage(imageObj, imageWidth, imageHeight); 
    }; 

    var allLoaded = 0; 
    var tilesX = ImageWidth/tileWidth; 
    var tilesY = ImageHeight/tileHeight; 
    var totalTiles = tilesX * tilesY;   
    var tileData = [totalTiles]; // Array with reserved size 
    for(var i=0; i<tilesY; i++) 
    { 
     for(var j=0; j<tilesX; j++) 
     {   
     // Store the image data of each tile in the array. 
     tileData.push(context.getImageData(j*tileWidth, i*tileHeight, tileWidth, tileHeight)); 
     allLoaded++; 
     } 
    } 

    if (allLoaded == totalTiles) { 
    console.log("All done: " + allLoaded); 
    console.log(tileData[1]); 
    context.putImageData(tileData[0], 0 ,0); // Sample paint 
    } 


}); 

错误发生在context.putImageData(tileData[0], 0 ,0); // Sample paint

下面是代码示例小提琴上述http://jsfiddle.net/47XUA/

回答

4

你的问题是,tileData第一个元素是不是一个ImageData对象,这是一个简单的数字!当你初始化数组您使用:

var tileData = [totalTiles]; 

这意味着tileData[0]等于totalTiles的价值,这是多少483。您提供的是一个数字,而不是ImageData对象,并且浏览器发生混淆错误。如果您查看阵列其余部分中的任何其他元素,您会发现它正如您所期望的那样成功地填充了ImageData对象;只有数组中的第一个元素是一个数字。

你大概的意思做:

var tileData = new Array(totalTiles); 

这将创建而非阵列的数量设置的第一个值与指定length属性的数组。就我个人而言,我会运行一些性能测试,看看它是否有用;您可能也可以使用var tileData = [];

+0

那......什么都没做。还是一样。 – nn2 2012-07-18 18:56:04

+1

澄清,它仍然产生相同的'类型错误'?我的叉不(在Chrome和FF):http://jsfiddle.net/HBzH7/ – apsillers 2012-07-18 18:57:48

+0

我没有看到'context.putImageData(tileData [1],0,0);'画布上的图像? – nn2 2012-07-18 19:12:32

0

这可能是一个赛车条件。只有在加载了图像./images/all_tiles.png时才使用drawImage。但是,您正在使用上下文的图像数据,然后在的onload启动。尝试将onload处理程序之后的所有内容移入onload处理程序。

+0

不,那没用。同样的错误。我把它放在onload之间。 – nn2 2012-07-18 11:25:09

+0

你有这个在线的例子吗? – devnull69 2012-07-18 11:25:54

+0

是的,这里是http://jsfiddle.net/47XUA/ – nn2 2012-07-18 11:37:23

0

这里的问题是imageObj.onload()函数在脚本的其余部分执行后被调用。

这意味着对getImageData()的查询返回未定义,因为调用时画布中没有图像数据。

一个简单的方法来解决这个问题是时封装剩下的脚本在imageObj.onload功能,像这样:

$(document).ready(function() { 
console.log("Client setup..."); 
canvas = document.getElementById("canvas"); 
context = canvas.getContext("2d"); 
canvas.tabIndex = 0; 
canvas.focus(); 
console.log("Client focused."); 

var imageObj = new Image(); 
imageObj.src = "./images/all_tiles.png"; 

imageObj.onload = function() { 

    context.drawImage(imageObj, 0, 0); 

    var allLoaded = 0; 
    var tilesX = imageWidth/tileWidth; 
    var tilesY = imageHeight/tileHeight; 
    var totalTiles = tilesX * tilesY;   
    var tileData = new Array(); // Array with NO reserved size 
    for(var i=0; i<tilesY; i++) 
    { 
    for(var j=0; j<tilesX; j++) 
    {   
     // Store the image data of each tile in the array. 
     tileData.push(context.getImageData(j*tileWidth, i*tileHeight, tileWidth, tileHeight)); 
     allLoaded++; 
    } 
    } 

    context.putImageData(tileData[0], 0 ,0); // Sample paint 
}; // End 'imageObj.onload()' scope. 

}); // End document ready function scope. 

这可以确保getImageData()任何呼叫后context.drawImage()

你也可以是由这里的一个问题是,您没有绘制图像来覆盖画布。更改行:

context.drawImage(imageObj, imageWidth, imageHeight); 

context.drawImage(imageObj, 0, 0); 

编辑:您也有ImageWidthimageWidth(同为高)。重命名这些。

编辑:保留数组大小在这里与new Array(totalTiles)是造成问题。当我们将新的平铺图片推送到数组时,它将推到预分配数组的末尾(从tileData[totalTiles]开始)。这很容易通过去除大小参数来解决。否则,而不是使用push()我们可以将图像数据复制到一个循环中的阵列中,例如:tileData[n] = getImageData(...),从tileData[0]开始。

+0

我仍然得到同样的错误。 :S – nn2 2012-07-18 17:54:06

+0

Weiiiiiird ..这里看看这个。 http://pastebin.com/0Un9f6Vc这里有两个版本,以前的版本是你的代码。你可以比较他们线为线。这对我行得通。我正在将jsFiddle图像(从页面的左上角)绘制到画布中,为白色部分成像并将其绘制回图像。您应该看到输出中的jsFiddle图像从(10,0)直到(30,30) – Aesthete 2012-07-18 22:11:20

+0

中缺少一块我可以弄到小提琴吗? – nn2 2012-07-18 22:23:35

3

当传入某个语句的变量或对象不是该命令预期的类型,并且无法将其转换为有效的类型时,会导致类型错误。

有关错误的完整定义,请参阅here

所以最有可能的情况下或tileData是格式不正确或为空或未定义

0

我使用Chrome。

context.drawImage(spritesheet.image, 0, 0, 4608, 768);// Works 
context.drawImage(spritesheet.image, 768, 0, 768, 768, 4608, 768); // Doesn't work: Uncaught TypeError: Type error 

谢谢!