#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    16
    Rep Power
    0

    [Solved] Closure inside a loop


    Leaving this here for posterity: I didn't actually have to resort to a new function (!!!) all I had to do was what itborg said and change

    context.drawImage(imgObj, wehey, goooo);
    to
    context.drawImage(this, wehey, goooo);

    Big thanks, guys truely appreciate the help. I was way to focused on adding another function to the mix, that I forgot about that part.



    I'm having a hard time trying to solve this. I suspect that it has to do with closure inside a loop, but I can not for the life of me get it to work...I have been throwing everything I have at it, I've tried to add a new function to it with return function() etc, etc. nothing works. Please help:


    Code:
    <!DOCTYPE HTML>
    <html>
      <head>
        <style>
          body {
            margin: 0px;
            padding: 0px;
          }
          #myCanvas {
            border: 1px solid #9C9898;
          }
        </style>
      </head>
      <body>
        <canvas id="myDrawingCanvas" width="825" height="700"></canvas>
        <script>
    var imgs = new Array();
    imgs[0] = 'black0.png';
    imgs[1] = 'black1.png';
    imgs[2] = 'black2.png';
    imgs[3] = 'black3.png';
    imgs[4] = 'black4.png';
    imgs[5] = 'black5.png';
    var wehey = 0;
    var cellswide=2;
    var cellshigh=2;
    var thisWidth = 50;
    var thisHeight = 50;
    var goooo = 0;
    var i = 0;
    
    drawingCanvas = document.getElementById('myDrawingCanvas');
    context = drawingCanvas.getContext('2d');
    
    	for(cellwidthcount=0;cellwidthcount<cellswide*cellshigh;cellwidthcount++){
    		var imgObj = new Image();
    		imgObj.onload = function() {
    if(wehey == cellswide * thisWidth){
    wehey = 0;
    goooo = goooo + thisHeight;
    }
    context.drawImage(imgObj, wehey, goooo);
    wehey = wehey + thisWidth;
    }
    	i = i + 1;
            imgObj.src = imgs[i];
    	}
    
        </script>
      </body>
    </html>
    Last edited by Grandum; November 20th, 2012 at 12:24 PM. Reason: solved
  2. #2
  3. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    16
    Rep Power
    0
    I just realized I forgot to write what my problem was

    imgObj.src = imgs[i];

    will not change when looping.

    I want it to loop out this:
    imgObj.src = imgs[1];
    imgObj.src = imgs[2];
    imgObj.src = imgs[3];
    imgObj.src = imgs[4];

    But all I get is
    imgObj.src = imgs[4];
    imgObj.src = imgs[4];
    imgObj.src = imgs[4];
    imgObj.src = imgs[4];

    any help would be greatly appreciated.
  4. #3
  5. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    Hi,

    yeah, that's a common problem. A loop does not introduce a new scope, so when you define a new variable inside the loop, it's in fact always the same variable that belongs to the scope the loop is in.

    As an example:
    Code:
    var functions = [];
    for (var i = 0; i < 2; i++) {
    	var x = i;
    	functions.push(function () {
    		alert(x);
    	});
    }
    functions[0]();
    functions[1]();
    You think you've created two variables "x", each one being local to the "for" block. But that's not the case. You have one variable x (belonging to the root level in this case).

    You can get around this by introducing a new scope with a function:
    Code:
    var functions = [];
    for (var i = 0; i < 2; i++) {
    	(function (j) {		// create a new function, call it and pass i
    		var x = j;		// now x is really a local variable
    		functions.push(function () {
    			alert(x);
    		});
    	})(i);
    }
    functions[0]();
    functions[1]();
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2012
    Posts
    4
    Rep Power
    0
    Hii Jacques1

    imgObj is Declared every time in loop.
    So When the images are loading the imgObj on -
    context.drawImage(imgObj, wehey, goooo);
    is always the last one.

    change this line to -
    context.drawImage(this, wehey, goooo);

    By the way - you are loosing the first image when you doing this :
    i = i + 1;
    imgObj.src = imgs[i];

    because imgs[0] is never used...

    Hope that help

    Comments on this post

    • Winters agrees
  8. #5
  9. CSS & JS/DOM Adept
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jul 2004
    Location
    USA (verifiably)
    Posts
    20,128
    Rep Power
    4304
    Originally Posted by Grandum
    Leaving this here for posterity: I didn't actually have to resort to a new function (!!!) all I had to do was what itborg said and change

    context.drawImage(imgObj, wehey, goooo);
    to
    context.drawImage(this, wehey, goooo);

    Big thanks, guys truely appreciate the help. I was way to focused on adding another function to the mix, that I forgot about that part.
    Welcome to DevShed Forums, Grandum.

    Next time please say that in a new reply instead of just editing the thread's first post.
    Spreading knowledge, one newbie at a time.

    Check out my blog. | Learn CSS. | PHP includes | X/HTML Validator | CSS validator | Common CSS Mistakes | Common JS Mistakes

    Remember people spend most of their time on other people's sites (so don't violate web design conventions).

IMN logo majestic logo threadwatch logo seochat tools logo