HTML 5 canvas DrawImage only working after refresh

I have an issue with drawing to the canvas, I have an array of image information that i loop through and create image objects from. On each images onload event i draw it to the canvas, however this will only work after a refresh (once the images are in the cache it seems).

Here is a snippet from my code

var image = new Image();
image.src = img.src; //got from elsewhere, need to draw a background image first
image.onload = function () {
    var canvas = document.createElement('canvas');
    canvas.width = img.width;
    canvas.height = img.height;
    img.parentNode.replaceChild(canvas, img);

    var context = canvas.getContext('2d');   
    context.drawImage(image, 0, 0, canvas.width, canvas.height);
    context.globalCompositeOperation = 'source-over';

    //looping through my image info
for (var index in anaglyphs){
        var anaglyph = anaglyphs[index];
        if (anaglyph === undefined) continue;

        //If x, y, height and width values are set in Image then set in mask
        //otherwise use defaults
        var x = 0;
        if (anaglyph.x !== undefined) x = anaglyph.x;
        var y = 0;
        if (anaglyph.y !== undefined) y = anaglyph.y;
        var width = canvas.width;
        if (anaglyph.width !== undefined) width = anaglyph.width;
        var height = canvas.height;
        if (anaglyph.height !== undefined) height = anaglyph.height;
        var alpha = new Image();

        //Use of an intimidate function to stop javascripts closure
        //overriding the variables before the onload event fired. Creating
        //temporary variables in the intimidate function, which executes 
        //immediately, and storing the desired values inside them for callback.
        (function (){
            var xPos = x;
            var yPos = y;
            var maskWidth = width;
            var maskHeight = height;
            alpha.onload = function () {
                context.drawImage(this, xPos, yPos, maskHeight, maskWidth);
            };    
        })();
        alpha.src = "data:"+anaglyph.content+";base64,"+encode64(anaglyph.data);
    }
};

After a refresh it works fine and it will continue to work fine if I open the webpage using that script again, however it will fail again if I clear the cache and reopen the page. It only needs to work in the latest version of Firefox.

Thanks

Answers


Try putting alpha.src inside your closure:

(function (anaglyph,x,y,width,height){
    var xPos = x;
    var yPos = y;
    var maskWidth = width;
    var maskHeight = height;
    alpha.onload = function () {
        context.drawImage(this, xPos, yPos, maskHeight, maskWidth);
    };    
    alpha.src = "data:"+anaglyph.content+";base64,"+encode64(anaglyph.data);
})(anaglyph,x,y,width,height);

BTW, why use a closure?

How about just a simple image loader with callback instead (just an example):

// callback -- after all images are loaded
function draw(images){
    // or whatever you want in your callback
    context.drawImage(images.image1, 10, 10, 50,50 );
    context.drawImage(images.image2, 10, 100, 50,50);
}

var images = {};

var URLs = {
  image1: 'ship.jpg',
  image2: 'houseicon.png'
};

LoadImages(URLs, draw );

function LoadImages(URLs, callback) {
  var loaded = 0;
  var needed = 0;
  for(var url in URLs) { needed++; }
  for(var url in URLs) {
    images[url] = new Image();
    images[url].onload = function() {
      if(++loaded >= numImages) {
        callback(images);
      }
    };
    images[url].src = URLs[url];
  }
}

Need Your Help

Create Up and Down arrow icons or buttons using pure CSS

html css css3 arrow arrow-keys

I am trying to create below shown "up and down" control buttons using pure CSS and no Background image.

ASP.NET MVC 3 multiple Models to single Form

asp.net-mvc asp.net-mvc-3 forms multiple-tables

I'm learning ASP.NET MVC 3 and trying to create a View with a single form which is made up of multiple Models linked together by a foreign key. The end goal is to have the single form insert into a...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.