1

再一次,完全超出了我的深度,但我需要预加载一些图像,然后在加载“所有元素(包括 xml 文件等)”时将它们添加到页面中。图像和参考存储在一个数组中以供以后访问。尝试从该数组中绘制和图像会引发错误,但我知道它是可用的,因为我可以追加到页面:

preloadImages: function (loadList, callback) {
    var img;
    var loadedFiles = [];
     var remaining = loadList.length;
   $(loadList).each(function(index, address ) {
     img = new Image();
    img.onload = function() {
         --remaining;
          if (remaining <= 0) {
                callback(loadedFiles);
            }
         };
 img.src = loadList[index];
     loadedFiles.push({file: 'name of image to be loaded', image: img }); //Store the image name for later refernce and the image
    });


}

//WHEN CERTAIN OTHER CONDITIONS EXIST I CALL THE FUNCTION BELOW

buildScreen: function ( imageLocs, image){
//THIS FUNCTION LOOPS THROUGH imageLocs (XML) AND CREATES CANVAS ELEMENTS, ADDING CLASSES ETC AND DRAWS PART OF A SPRITE (image) 
        //INTO THE CANVASES CREATED
    var ctx = $('ID of CANVAS').get(0).getContext("2d");
    var x =  'position x in imageLocs'
        var y =  'position y in imageLocs'
        var w =  'width in imageLocs'
        var h =  'position x in imageLocs'
        ctx.drawImage(image, x,y, w, h, 0, 0, w, h); //THIS THROWS AN ERROR 'TypeError: Value could not be converted to any of: HTMLImageElement, HTMLCanvasElement, HTMLVideoElement'
        //$(image).appendTo("#innerWrapper") //YET I KNOW THAT IT IS AVAILABE AS THIS LINE ADDS THE IMAGE TO THE PAGE
    }
4

2 回答 2

3

问题

问题是因为您将 jQuery 对象传递给本机函数,在这种情况下ctx.drawImage,drawImage 将仅支持本机对象。

startSequence : function(){
  $('#innerWrapper').empty();
  var screenImageRef = $.grep(ST.imageFilesLoaded, function(e){ 
    return e.file == 'AtlasSheet'
  });
  var screenImage = $(screenImageRef[0].image);
  var imageLocsRef = $.grep(ST.xmlFilesLoaded, function(e){ 
    return e.file == 'IMAGELOCS'
  });
  var imageLocs = $(imageLocsRef[0].xml);
  //$(screenImage).appendTo("#innerWrapper") //appends screenImage 
  Utilis.buildScreen('1', imageLocs, screenImage, ST.didYouSeeIt, 'ST')
}

您的screenImagevar 由 创建$(screenImageRef[0].image),这将返回一个包装原生图像对象的 jQuery 对象。要返回原始原生图像对象,请使用以下命令:

screenImage.get(0)

或者

screenImage[0]

前者是jQuery支持的方式。

解决方案

因此,对您的代码的修复应该是,更改以下行:

Utilis.buildScreen('1', imageLocs, screenImage.get(0), ST.didYouSeeIt, 'ST');

或者更改 buildScreen 方法中的行:

ctx.drawImage(image.get(0), x,y, w, h, 0, 0, w, h);

...无论你喜欢哪个。

调试时的困惑

附加图像时一切似乎都可以正常工作的原因是因为您使用 jQuery 来附加图像,并且 jQuery 支持传递 jQuery 包装的元素。如果您尝试附加您screenImage使用的本机函数,即Element.appendChild()您会遇到类似的错误。

只是为了在将来提供帮助,最好始终使用console.log找出变量实际具有的类型/结构。console.log在您以前的var 上使用image会给出一个奇怪的 jQuery 包装器对象转储(可能已经敲响了警钟),而不是预期的[object HTMLImageElement]或其他一些与图像/控制台相关的输出(取决于浏览器)。

于 2013-02-18T11:45:40.677 回答
1

我认为您的图像预加载器不太正确,因为它对img所有图像使用相同的变量。

这是我知道效果很好的一个:https ://gist.github.com/eikes/3925183

于 2013-02-18T10:51:47.790 回答