Creating buttons in a for-loop, each with a different mousePressed function in p5

Viewed 289

I want to have four buttons. Each button has a name and a value. When each of the buttons are pressed, I want to execute a function that takes the buttons value as a parameter.

The function I want to call is not really import here, but lets say:

 function fun(value) {
     console.log(value)
}

I have this working using this code.

  //   // create 4 buttons
  createButton('fabrics', 'fabrics')
    .position(50, 50 + 25 * 1)
    .mousePressed(function() {
      fun('fabrics');
    })

  createButton('leather', 'leather')
    .position(50, 50 + 25 * 2)
    .mousePressed(function() {
      fun('leather');
    })

  createButton('wood', 'wood')
    .position(50, 50 + 25 * 3)
    .mousePressed(function() {
      fun('wood');
    })

  createButton('metal', 'metal')
    .position(50, 50 + 25 * 4)
    .mousePressed(function() {
      fun('metal');
    })

It just seems absolutely silly to do it in this way and not use a for-loop. I tried it in a for-loop:

  //   // create 4 buttons
  names = ['fabric', 'leather', 'wood', 'metal'];
  for (let i = 0; i < 4; i++) {
    name = names[i]
    createButton(name, name)
      .position(50, fabric[0].height + 25 * (i + 1))
      .mousePressed(function() {fun(name);})
  }

This creates 4 buttons, at the required position, however the mousePressed fires the fun function with metal as a parameter. In other words, while position loops as I'd expect, mousePressed for each button is updated tot he latest fun(name) for each iteration.

What is a better way to do this in p5?

1 Answers

To give each button its own mouse pressed function you will need to wrap the function in a closure. Try something like this:

function setup() {
  createCanvas(400, 400);
  background(220);
 var names = ['fabric', 'leather', 'wood', 'metal'];
  for (let i = 0; i < 4; i++) {
    name = names[i]
    createButton(name, name)
      .position(50, 125 + 25 * (i + 1))
      .mousePressed(createMousePressedFunction(name))
  }
}

function createMousePressedFunction(name){
return function() {fun(name);}
}

 function fun(value) {
     console.log(value)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.8.0/addons/p5.dom.min.js"></script>

Related