[英]JavaScript - Uncaught TypeError: Type error
我正在尝试破坏一个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
context.putImageData(tileData[0], 0 ,0); // Sample paint
这是http://jsfiddle.net/47XUA/上方的代码示例
您的问题是tileData
的第一个元素不是ImageData
对象, 而是一个纯数字 ! 初始化数组时,您使用了:
var tileData = [totalTiles];
这意味着tileData[0]
等于totalTiles
的值,即数字483
。 您向putImageData
提供了一个数字而不是ImageData
对象,浏览器在混乱中抛出错误。 如果您查看数组其余部分中的任何其他元素,就会发现它已成功按预期填充ImageData
对象; 只有数组中的第一个元素是数字。
你可能打算这样做:
var tileData = new Array(totalTiles);
这将创建具有指定的length
属性的数组,而不是将数组中的第一个值设置为数字。 就个人而言,我将进行一些性能测试,以查看它是否仍然有用。 使用var tileData = [];
也可能会很好
当传递到语句中的变量或对象的类型不是该命令所期望的类型,并且无法将其转换为有效值时,将导致类型错误。
有关错误的完整定义,请参见此处 。
因此,很可能上下文或tileData的格式不正确,或者为null或未定义
这可能是赛车状况 。 仅在加载图像./images/all_tiles.png
时才使用drawImage。 但是,在触发onload 之前 ,您正在上下文中使用图像数据。 尝试将onload处理程序之后的所有内容移动到onload处理程序中。
这里的问题是在执行脚本的其余部分之后,会调用imageObj.onload()
函数。
这意味着对getImageData()
查询返回的是未定义的,因为调用时画布中没有图像数据。
解决此问题的一种简单方法是将其余脚本imageObj.onload
在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.
这样可以确保在context.drawImage()
之后进行对getImageData()
任何调用。
您在这里可能还存在一个问题,即您没有绘制图像以覆盖画布。 换行:
context.drawImage(imageObj, imageWidth, imageHeight);
至
context.drawImage(imageObj, 0, 0);
编辑:您还具有ImageWidth
和imageWidth
(高度相同)。 重命名这些。
编辑:在这里使用new Array(totalTiles)
保留数组大小会导致问题。 当我们将新的图块图像推送到数组时,它推送到预分配数组的末尾(从tileData[totalTiles]
)。 通过删除size参数可以轻松解决此问题。 否则,除了使用push()
我们还可以循环将图像数据复制到数组中,例如: tileData[n] = getImageData(...)
,从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
谢谢!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.