2012-07-18 189 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 

謝謝!