将预加载的图像绘制到画布中

时间:2013-02-18 10:24:07

标签: javascript html canvas

再一次,完全超出了我的深度,但我需要预先加载一些图像,然后在加载“所有元素(包括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
    }

2 个答案:

答案 0 :(得分: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')
}

screenImage var由$(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]或其他一些图像/控制台相关输出(取决于浏览器)。

答案 1 :(得分:1)

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

以下是我认为合适的一个:https://gist.github.com/eikes/3925183