我正在尝试打破spritesheet,好吧,它不会像它应该的那样将它放入2D数组中。在我的代码结束时,在console.log附近,它会吐出ImageData ...但是当它尝试putImageData时......我得到Uncaught TypeError: Type error
帮助?
这是我的代码:
$(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
答案 0 :(得分:4)
您的问题是tileData
的第一个元素不是ImageData
对象,它是一个简单的数字!初始化阵列时,您使用了:
var tileData = [totalTiles];
这意味着tileData[0]
等于totalTiles
的值,即483
。您向ImageData
提供了一个数字而不是putImageData
对象,并且浏览器在混乱中抛出错误。如果你查看数组其余部分中的任何其他元素,你会看到它已成功填充了ImageData
个对象,如你所愿;只有数组中的第一个元素是数字。
你可能打算这样做:
var tileData = new Array(totalTiles);
将创建具有指定length
属性的数组,而不是将数组中的第一个值设置为数字。就个人而言,我会进行一些性能测试,看看它是否有用;你也可以使用var tileData = [];
答案 1 :(得分:3)
答案 2 :(得分:0)
这可能是比赛条件。仅在加载图像./images/all_tiles.png
时才使用drawImage。但是您正在使用上的图像数据 onload触发。尝试将onload处理程序之后的所有内容移动到onload处理程序中。
答案 3 :(得分: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);
编辑:您还有ImageWidth
和imageWidth
(身高相同)。重命名这些。
编辑:此处使用new Array(totalTiles)
保留数组大小导致问题。当我们将新的tile图像推送到数组时,它会推到预分配数组的末尾(从tileData[totalTiles]
开始)。通过删除size参数可以很容易地解决这个问题。否则,我们可以将图像数据复制到数组中,而不是使用push()
,例如:tileData[n] = getImageData(...)
,从tileData[0]
开始。
答案 4 :(得分: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
谢谢!