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

draw preloaded image into canvas

本文关键字:绘制 布中 图像 加载      更新时间:2023-09-26

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

问题

这个问题是因为您将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包装的元素。如果您尝试使用本机函数(即Element.appendChild())附加screenImage,则会出现类似的错误。

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

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

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