Problem with "this" scope while using OOP in p5.dom Element method

Hi there.

I am trying to modulate my code into objects, but I am having a problem with the this scope. Inside the constructor of my BackgroungTools class I define some class' members, as shown below:

BackgroundTools = function() {
        this.isBackgroundToolsOn = false

        this.backgroundButton = createButton('Background')
        this.backgroundButton.position(20,20)
        this.backgroundButton.mouseClicked(this.toggleBackgroundTools)

        this.backgroundSliderRed = createSlider(0,255)
        this.backgroundSliderRed.position(20,50)
        this.backgroundSliderRed.hide()
        console.log(this)
}

BackgroundTools.prototype.toggleBackgroundTools = function() {
    console.log(this)
    if (this.isBackgroundToolsOn) {
            this.backgroundSliderRed.hide()
            this.isBackgroundToolsOn = false
    } else {
            this.backgroundSliderRed.show()
            this.isBackgroundToolsOn = true
    }
}

Later, I then instantiate this class inside the setup function of p5:

function setup() {
    canvas = createCanvas(800,600)
    background(0)
    backgroundTools = new BackgroundTools()
}

function draw() {
}

When this is printed in the Constructor we get what is expected (a pointer to the current object). But when I click in the button and the method toggleBackgroundTools is called, the this inside it isn't what we expect to be: it isn't a pointer to the current object, but it's something that prints in the console this: [top: Window[0], window: Window[0], location: Location, external: Object, chrome: Object…]

I think that the method mouseClicked from p5.Element sort of change the scope of this. But I want to access the class' members in toggleBackgroundTools method.

Someone has went through this before? Any ideas on how can I deal with this?

Thanks!

Answers

  • This question was answered in Stackoverflow.

    To fix it, and get the this right scope, I should use this.backgroundButton.mouseClicked(this.toggleBackgroundTools.bind(this)).

    More about this subject can also be found in this Stackoverflow answer.

  • edited November 2014

    Oh I was a little l8 to found out the same answer too. You can also see an explanation here:
    http://forum.processing.org/two/discussion/8380/issues-with-my-anthill-program#Item_9

    Nevertheless, my attempt example below: 8-X

    // forum.processing.org/two/discussion/8399/
    // problem-with-this-scope-while-using-oop-in-p5-dom-element-method
    
    var backgroundTools;
    
    function setup() {
      createCanvas(400, 300);
      noLoop(), background(0);
      backgroundTools = new BackgroundTools();
    }
    
    function mouseClicked() {
    }
    
    function BackgroundTools() {
      this.isSliderRedActive = false;
    
      this.redBGButton = createButton('Red Button');
      const cx = width  - this.redBGButton.width*.75 >> 1;
      const cy = height - this.redBGButton.height >> 1;
    
      this.redBGButton
        .position(cx, cy)
          .style('font-size', '16px')
            .style('color', 'white')
              .style('background', 'red')
                .mouseClicked(BackgroundTools.prototype.toggleRedBG.bind(this));
    
      this.redBGSlider = createSlider(0, 0xff);
    
      this.redBGSlider
        .position(width  - this.redBGSlider.width*.95 >> 1, cy*1.2)
          .attribute('hidden', true)
            .elt.onchange = BackgroundTools.prototype.changeRedBG.bind(this);
    }
    
    BackgroundTools.prototype.toggleRedBG = function() {
      (this.isSliderRedActive ^= true)
        ? this.redBGSlider.show() : this.redBGSlider.hide();
    }
    
    BackgroundTools.prototype.changeRedBG = function() {
      const valRed = this.redBGSlider.value();
      background(valRed, 0, 0);
      print(valRed);
    }
    
Sign In or Register to comment.