0

I have found an API that'll make working with CANVAS a lot easier. It allows selection and modification of individual elements on the canvas very easily. It's EaselJS. The API doc is here. http://easeljs.com/docs/

I am Ok with the API so far. What confuses me is actually some javascript in there. The part that's in bold or within * *(couldn't get the formatting to work) What kind of javascript structure is this?

(function(target){...content...})(bitmap) and in the content, it references bitmap, which is something outside.

HERE IS THE CODE

   for(var i = 0; i < 100; i++){
    bitmap = new Bitmap(image);
    container.addChild(bitmap);
    bitmap.x = canvas.width * Math.random()|0;
    bitmap.y = canvas.height * Math.random()|0;
    bitmap.rotation = 360 * Math.random()|0;
    bitmap.regX = bitmap.image.width/2|0;
    bitmap.regY = bitmap.image.height/2|0;
    bitmap.scaleX = bitmap.scaleY = bitmap.scale = Math.random()*0.4+0.6;
    bitmap.mouseEnabled = true;
    bitmap.name = "bmp_"+i;

(function(target) {

*bitmap.onPress = function(evt) *

        {if (window.console && console.log) { console.log("press!"); }
        target.scaleX = target.scaleY = target.scale*1.2;
        container.addChild(target);
        // update the stage while we drag this target
        //Ticker provides a central heartbeat for stage to listen to
        //At each beat, stage.tick is called and the display list re-rendered
        Ticker.addListener(stage);
        var offset = {x:target.x-evt.stageX, y:target.y-evt.stageY};

        evt.onMouseMove = function(ev) {
            target.x = ev.stageX+offset.x;
            target.y = ev.stageY+offset.y;
            if (window.console && console.log) { console.log("move!"); }
        }
        evt.onMouseUp = function() {
            target.scaleX = target.scaleY = target.scale;
            // update the stage one last time to render the scale change, then stop updating:
            stage.update();
            Ticker.removeListener(stage);
            if (window.console && console.log) { console.log("up!"); }
        }

** }})(bitmap); **

    bitmap.onClick = function() { if (window.console && console.log) { console.log("click!"); } }
}
William Sham
  • 12,849
  • 11
  • 50
  • 67
  • I've gone through their code at least 50 times and still have problems understanding some of their code. If you are a novice-intermediate programmer it can be hard to decipher. – puk Dec 06 '11 at 21:15

1 Answers1

1
(function(target){...content...})(bitmap) 

is creating a lexical scope for content so that any var or function declarations in content do not leak into the global scope. Inside content, target is just another name for bitmap.

You can think of this as similar to

function init(target) { ...content... }

and then an immediate call to it passing bitmap as the actual value of the target parameter but the first version interferes with the global scope even less -- it doesn't define init as a name in the global scope.

EDIT: I think the purpose is not lexical scoping, but to make sure that the event handlers point to the right bitmap, instead of the last bitmap the for loop deals with. init(bitmap);

See Event handlers inside a Javascript loop - need a closure? for more detail.

Community
  • 1
  • 1
Mike Samuel
  • 118,113
  • 30
  • 216
  • 245
  • if target is another name for bitmap WHEN it's inside the function...what in the first line after function, they use bitmap.onPress = function(evt) – William Sham Jun 15 '11 at 21:03
  • @William Sham, it looks like an event handler definition. http://www.quirksmode.org/js/introevents.html – Mike Samuel Jun 15 '11 at 21:19
  • I understand that's an event handler. But why bitmap.onPress instead of target.onPress...I tried both, at the surface, both seems to work..just don't know if there's other implications – William Sham Jun 15 '11 at 21:22
  • @William Sham, They could use bitmap instead of target in the first line, but it's not critical since the assignment happens before the for loop proceeds to the next bitmap. That is not the case for the uses of target inside the event handler body since the event handler is called well after the loop has finished running. – Mike Samuel Jun 15 '11 at 21:49
  • I see. That's interesting. Thanks for your answer – William Sham Jun 15 '11 at 21:57