Click event on two shape

If I have two rect one over enother, partially, if a click in the common area, how can I select the last above rectangle?
like in this example:
https://editor.p5js.org/Clingonboy/sketches/ja_VJNrg4
Have I do andle myself wich is the last rect drowed to considering the above one?
Thanks for your help.

1 Like

possibly there is a misunderstanding,
once the rect’s are drawn they are not separable objects,
so if they overlap and you do a “boolen rect mouse over” method
there will be a conflict about the area where they overlap.

1 Like

Thank for the clarification. It’s what I was afraid of, but it had to be like this because it is a Canvas.
Thanks

It all depends on your code

you can solve this of course

let’s say you have stored all rects in arrays like

float [] x
float [] y
float [] w
float [] h

let’s say there are 10.
you draw them from 0 to 9 in a for loop


for(int i............{
   rect(x.................
}

Check the mouse

Now you check the mouse

from 0 to 9 in a for loop

void mousePressed() {
  numberOfDetectedRect = -1;  // unknown 
  for(int i............{
     if(mouseX>........{
         // detection
         numberOfDetectedRect = i; 
         return;  // !!!!!!!!!!!!!!!!!!!!!!! ??????????????????????
     }
  }
}

Now the point is:

you can either leave the for loop using return or break on the first occurance of a match

OR stay in the for loop so that the 2nd occurance gets also detected

in an overlapping situation this means:

  • the first occurance = rect underneath
  • the 2nd occurance = rect above / drawn last [this is what you WANT]

When you want to have the 2nd rect selected, you don’t want return / break in your for loop.

Remark

depending on your goal you could also monitor both rects occurances so that you know we have a click in the overlapping section of rects #3 and #7 :wink:

Chrisir

2 Likes

Your explanation is very clear and useful, Thanks

1 Like

I would also work without the arrays.

You have

  rect(50,50,50,50);
  rect(75,75,50,50);

The result just depends on which rect you check first or if you just use if.. or if...else if....:

e.g. in an overlapping situation where both checks give you true:

if(mouseX>50&&mouseX<50+50&&mouseY>.......... ) currentRect = 1; 
if(mouseX>75&&mouseX<75+50&&mouseY>.......... ) currentRect = 2;   // this one is chosen

is different from :

if(mouseX>50&&mouseX<50+50&&mouseY>.......... ) currentRect = 1; // this one is chosen 
else if(mouseX>75&&mouseX<75+50&&mouseY>.......... ) currentRect = 2;

Because with else if (2nd example) the 2nd if-clause is not looked at when the 1st one is true.

Chrisir

2 Likes

here is an example

// Array of rects 
int lenArray=10;

float [] x = new float[lenArray]; 
float [] y = new float[lenArray];
float [] w = new float[lenArray];
float [] h = new float[lenArray];

// marker 
int numberOfDetectedRect = -1; 

// leave yes/no
boolean leaveTheForLoopImmediately = false; 

// ------------------------------------------------------------------
// processing core functions

void setup() {
  size(400, 400);

  // pre-init 
  for (int i=0; i<x.length; i++) {
    x[i]=130 + 26*i; 
    y[i]=150 + 3*i; 
    w[i]=20; 
    h[i]=30;
  }//for

  // init separately
  x[0]=50; 
  y[0]=50; 
  w[0]=50; 
  h[0]=50; 

  x[1]=75; 
  y[1]=75; 
  w[1]=50; 
  h[1]=50;

  // this was in the old code: 
  //rect(50, 50, 50, 50);
  //rect(75, 75, 50, 50);
}

void draw() {
  background(220); 

  showHelpText();
  showRectangles();
}

// ------------------------------------------------------------------
// functions called by draw() 

void showRectangles() {
  // show all rectangles 

  for (int i=0; i<x.length; i++) {

    strokeWeight(1); 
    // if the rect is the selected one we set strokeWeight to 4
    if (numberOfDetectedRect==i) {
      strokeWeight(4);
    }
    fill(color(10, 55, 10, 50));
    rect(x[i], y[i], 
      w[i], h[i]);
    // show text for the rect
    fill(0); 
    text(i, 
      x[i]+3, y[i]-3);
  }//for
  // reset strokeWeight
  strokeWeight(1);
}//func 

void showHelpText() {
  // show Help Text
  fill(0);
  text ("Test for overlapping rects; \nleaveTheForLoopImmediately is "
    +leaveTheForLoopImmediately
    +".\nHit any key to toggle.\nClick a rect to select it.", width/2-22, 44);
}

// ------------------------------------------------------------------
// Inputs 

void mousePressed() {
  numberOfDetectedRect = -1;  // unknown 
  for (int i=0; i<x.length; i++) {
    // detection? 
    if (mouseX>x[i]&&
      mouseX<x[i]+w[i]&& 
      mouseY>y[i]&&
      mouseY<y[i]+h[i]) {
      // detection
      // set marker 
      numberOfDetectedRect = i;
      // leave here yes/no
      if (leaveTheForLoopImmediately) {
        return; // !!!!!!!!!!!!!!!!!!!!!!!
      }//if
    }//if
  }//for
}//func

void keyPressed() {
  leaveTheForLoopImmediately = 
    ! leaveTheForLoopImmediately;
}
//
1 Like