【问题标题】:Images not loaded on first call in html canvas在 html 画布中第一次调用时未加载图像
【发布时间】:2015-09-02 21:56:45
【问题描述】:

我想以相同的顺序在画布中加载排序后的数组图像,为此我创建了一个加载函数并从那里调用它。

一切正常,但问题是它不会在第一次调用时在画布上绘制图像。

Here is a fiddle

使用我当前的代码,它不会向您显示图像,但是当您再次运行它时,它将创建并显示画布图像。

我在使用 ajax 加载图像的本地主机中遇到了同样的问题。

var ImagesArray = new Array("http://s4.postimg.org/dw8aujkkd/slim_Fit.png",
  "http://s27.postimg.org/l6mq3hboz/outer_collar1.png",
  "http://s22.postimg.org/e7alkm44x/inner_collar11.png",
  "http://s12.postimg.org/h4kgdjn4t/maincolar.png",
  "http://s13.postimg.org/edabwknfr/outer_fastening1.png");

//alert(ImagesArray.length);
MainMethods(ImagesArray);



function MainMethods(responseImages) {
  //alert(responseImages.length);
  var canvas = document.getElementById("product-image");

  canvas.height = ($(window).height()) - 120;
  canvas.width = canvas.height * 0.75;
  var heightscreen = ($(window).height()) - 120;
  var canvasheight = heightscreen;
  var canvaswidth = canvas.height * 0.75;
  canvaswidthdiv4 = 0;
  var widthNeeded = canvasheight * 0.75;

  var context = canvas.getContext('2d');


  var returnedImages = loadImages(responseImages);


  for (i = 0; i < returnedImages.length; i++) {
    console.log(returnedImages[i]);
    context.drawImage(returnedImages[i], canvaswidthdiv4, 55, widthNeeded, canvasheight);
  }



  // Image loading global variables
  var loadcount = 0;
  var loadtotal = 0;
  var preloaded = false;

  // Load images
  function loadImages(imagefiles) {
    // Initialize variables
    loadcount = 0;
    loadtotal = imagefiles.length;
    preloaded = false;

    // Load the images
    var loadedimages = [];
    for (var i = 0; i < imagefiles.length; i++) {
      // Create the image object
      var image = new Image();

      // Add onload event handler
      image.onload = function() {
        loadcount++;
        if (loadcount == loadtotal) {
          // Done loading
          preloaded = true;
        }
      };

      // Set the source url of the image
      image.src = imagefiles[i];

      // Save to the image array
      loadedimages[i] = image;
    }

    // Return an array of images
    return loadedimages;
  }

}
&lt;canvas id="product-image" width="700" height="823"&gt;&lt;/canvas&gt;

【问题讨论】:

  • 无法打开小提琴... nvm,愚蠢的错误
  • @Shocklo 是的,它是jsfiddle.net/mohib/wdfrrayh/1
  • @MohibSalahuddin 当编辑器提醒您必须将代码放在问题中时,这并不意味着指向代码的链接,而是实际代码;关于 SO 的问题应该是独立的。

标签: javascript jquery html canvas


【解决方案1】:

问题是您尝试绘制图像时尚未加载图像。

将drawImage 部分包装在一个函数中,并在预加载为真时调用它,这里你的布尔值什么都不做。

我稍微重构了您的代码,在您调用 loadImage() 函数后,您还遇到了 loadtotal 被重置为 0 的问题。所以 loadcount 永远不会是 === loadtotal 并且你无用的预加载永远不会切换到 true。

var ImagesArray = new Array ("http://s4.postimg.org/dw8aujkkd/slim_Fit.png",
                   "http://s27.postimg.org/l6mq3hboz/outer_collar1.png",
                   "http://s22.postimg.org/e7alkm44x/inner_collar11.png",
                   "http://s12.postimg.org/h4kgdjn4t/maincolar.png",
                   "http://s13.postimg.org/edabwknfr/outer_fastening1.png");

function MainMethods(responseImages) {

	var canvas = document.getElementById("product-image");

	canvas.height = ($(window).height()) - 120;
	canvas.width = canvas.height * 0.75;
	var canvasheight = ($(window).height()) - 120;
	var canvaswidth = canvas.height * 0.75;
	canvaswidthdiv4 = 0;
	var widthNeeded = canvasheight * 0.75;
	var context = canvas.getContext('2d');



	// an other error, if you set loadtotal to 0 after calling loadImages(), it will be set to 0 when images are loaded.
	// and loadcount won't ever be === loadtotal.
	var loadcount;
	var loadtotal;

	function loadImages(imagefiles) {
		loadcount = 0;
		loadtotal = imagefiles.length;

		var loadedimages = [];
		for (var i=0; i<imagefiles.length; i++) {
			var image = new Image();
 
			image.onload = function () {
				loadcount++;
				console.log(loadcount+'/'+ loadtotal);
				if (loadcount == loadtotal) {
                  // done loading all the images
					draw(loadedimages);
				}
			};
                
			image.src = imagefiles[i];

			loadedimages[i] = image;
		}
 
	}

	// Wrap your drawing in a function that will be called asynchronously
	function draw(loadedimages){
		for (var i = 0; i < loadedimages.length; i++) { 
			console.log(loadedimages[i]);
			context.drawImage(loadedimages[i], canvaswidthdiv4, 55, widthNeeded, canvasheight);
			}
		}

	// Once all your variables are set, you can load the images
	loadImages(responseImages);
}

MainMethods(ImagesArray);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas id="product-image"></canvas>

【讨论】:

    【解决方案2】:

    由于它似乎是特定于浏览器的问题,所以这里有一个让它工作的技巧:

    替换:MainMethods(ImagesArray);

    与:setTimeout(function () { MainMethods(ImagesArray); }, 0);

    将超时设置为 0 毫秒,它实际上会立即执行。

    JsFiddle : http://jsfiddle.net/wdfrrayh/3/

    在 IE、FF、Chrome 上测试

    【讨论】:

    • 当你在新标签上尝试它时你会发现它不起作用,实际上它只有在它存储在缓存中时才会显示。
    • 它适用于 Firefox 和 chrome。我猜你的问题与IE有关。
    • 我在 chrome 上;但是我在firefox上试过但它保持不变:(实际上它只显示它存储在缓存中时,它看起来可能是加载延迟时间影响它?
    • 实际上令人惊讶的是,当我进行硬刷新时,它在 3 个浏览器中的任何一个上都不起作用,当我只在从缓存中检索它时进行刷新时,所有这些都可以正常工作,但在清除缓存后它确实如此不是;因此,当我再次按运行时,它起作用了,我尝试将所有内容包装在 CallAgain 函数中并调用该函数两次,但这也无济于事,我在这里更新了jsfiddle.net/mohib/wdfrrayh/8
    • @MohibSalahuddin:抱歉,我没明白你所说的“硬刷新”是什么意思。
    【解决方案3】:

    image src 需要在我更新工作正常的函数之前执行的 drawImage 之后调用,

    下面是这个的工作代码

    function loadImages(sources, callback, jsondata) {
    
        var images = {};
        var loadedImages = 0;
        var numImages = 0;
    
        // get num of sources
        for(var src in sources) {
          numImages++;
        }
        for(var src in sources) {
          images[src] = new Image();
          images[src].onload = function() {
            if(++loadedImages >= numImages) {
              callback(images);
            }
          };
          images[src].src = sources[src];
        }
      }
    
      var canvas = document.getElementById('product-image');
    
        canvas.height = (jQuery(window).height()) -120;
          canvas.width = canvas.height * 0.75;
      var heightscreen = (jQuery(window).height()) -120;
      var canvasheight = heightscreen;
      var canvaswidth = canvas.height * 0.75;
      canvaswidthdiv4 = 0;
      var widthNeeded = canvasheight * 0.75;
    
      var context = canvas.getContext('2d');  
    
    
     var sources = new Array ("http://s4.postimg.org/dw8aujkkd/slim_Fit.png",
                   "http://s27.postimg.org/l6mq3hboz/outer_collar1.png",
                   "http://s22.postimg.org/e7alkm44x/inner_collar11.png",
                   "http://s12.postimg.org/h4kgdjn4t/maincolar.png",
                   "http://s13.postimg.org/edabwknfr/outer_fastening1.png");
    
    
          loadImages(sources, function(images) {
    
              for(var i=0; i < sources.length; i++){
                 context.drawImage(images[i], canvaswidthdiv4, 55,widthNeeded,canvasheight); 
              }
    
    
          });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多