Change rectangles seperately in for loop

Hi,

I wanted to make a screen full of rectangles which if you hover over them with your mouse, start to rotate (I’m not done with the rotating part yet). Right now I have the rectangles but if you hover over them with your mouse it’s not only one rectangle that changes, but every rectangle that’s after the rectangle you have your mouse on.

So my question is:
How do I change my code so the only rectangle that changes is the one you have your mouse on?

This is my code:

void setup() {
  size(800, 620);
}

void draw() {
  background(#000000);
  int size = 40;

  fill(#fee445);
  noStroke();
  
  for (int i = 20; i < width; i += 60) {
    for (int j = 20; j < height; j += 60) {
      rect(i, j, size, size);

  if (mouseX > i && mouseX < i+size && mouseY > j && mouseY < j+size){
    fill(#ffffff);
  }

    }
  }
}
1 Like

you might need the rectangle to be a ( little bit intelligent ) object
the right way would be a class Rect and a array rects of class Rect
where in class can have memory of

  • position,
  • detect mouse over and
  • remember clicked
  • color
  • rotation angle…

sorry, it might be too early to start with classes??
a slower, first step into this, might be array and functions…

2 Likes

You don’t need a class or array

Just before drawing the rect have an if-clause that checks out the distance between mouse and circle (use if(dist(mouseX,mouseY....) < 40) {.....} ).

In this if-clause you do the rotation:

pushMatrix
translate 
rotate
rect
popMatrix

(See reference for the commands)

There’s a little more to think of but not much.

Regards, Chrisir :wink:

2 Likes

Thank you very much! :grin:

1 Like

I don’t know if I’m doing something wrong but is it possible that when the mouse is on a rectangle, only this rectangle changes instead of every rectangle?

what is your actual code? still like you post in your topic?

1 Like
void setup() {
  size(800, 620);
}

void draw() {
  background(#000000);
  int grootte = 40;

  fill(#fee445);
  noStroke();

  for (int i = 20; i < width; i += 60) {
    for (int j = 20; j < height; j += 60) {
      if (dist(25, 25, mouseX, mouseY) < 40) {
        fill(#ffffff);
      }
      rect(i, j, grootte, grootte);

    }
  }
}
1 Like

try:

int size = 40, off = 20;

void setup() {
  size(800, 620);
}

void draw() {
  background(0);
  noStroke();
  for (int i = off; i < width; i += size+off) {
    for (int j = off; j < height; j += size+off) {
      fill(200,200,0);
      if (mouseX > i && mouseX < i+size && mouseY > j && mouseY < j+size) fill(0,0,200);
      rect(i, j, size, size);
    }
  }
}

but as mentioned that is only change while mouse over,
for a permanent change on click need some memory for each object

3 Likes

Thank you! :slightly_smiling_face: Yes, I only need it with mouse over.

1 Like

good, now you see both code versions,
what would you say your mistake was?

2 Likes

I think,
The rectangle was in the wrong place and the color the rectangle is and has to become had to be inside the for loop.

1 Like

No. That was not the reason.

The reason was this:

You had this line:

      if (dist(25, 25, mouseX, mouseY) < 40) {
        fill(#ffffff);
      }

but once the color was set to fill(#ffffff); it went never back. That was the problem.

That got corrected like this:

      fill(200,200,0);
      if (mouseX > i && mouseX < i+size && mouseY > j && mouseY < j+size) 
             fill(0,0,200);

Here, the initial color is set fill(200,200,0); always and then the if-clause can change this color.

Thus we always can get both colors.

Another way would be

      if (mouseX > i && mouseX < i+size && mouseY > j && mouseY < j+size) 
             fill(0,0,200);
          else 
            fill(200,200,0);

I hope this helps.

Chrisir

1 Like

yes, understand, still to wrap that up i want show a featured class rect array version,

// https://discourse.processing.org/t/scalable-grid-with-rectangles/7256
// https://discourse.processing.org/t/better-grid-performance/7314
// https://discourse.processing.org/t/gryd-system-graphic-design/10457
// https://discourse.processing.org/t/change-rectangles-seperately-in-for-loop/10908/2
// use backup memory array for resize/reinit grid but remember selected rects

int x = 30, y = x, w = 50, h = w, off= 5, grid = 10, many = grid*grid;
float rang = 0, strokew=1.0;
boolean auto = false;//false;//true;
boolean shownum    = false;    // key [n]
boolean showFPS    = true;
boolean togfill    = false;

// color setup:
color bg  = color(200, 200, 0);
color stk = color(0, 0, 200);
color fillsel = color(0, 200, 0);
color fillnsel= color(200, 0, 200);

Myrect[]   myrects   = new Myrect[many];
Mybackup[] myselects = new Mybackup[many];  // temporary memory

void setup() {
  size(800, 520);
  noSmooth();
  set_grid(true);     // init
  String help = "";
  help += "use: mouse LEFT to select, mouse RIGHT to deselect\n";
  help += "key UP DOWN RIGHT LEFT for position\n";
  help += "key +  -  for grid size\n";
  help += "key n toggle shownumber\n";
  help += "key f toggle fill\n";
  help += "____MouseWheel Plus Plus ____\n";
  help += "use key [x] [y] [w] [h] [o] for position and size\n";
  help += "use key [r] rotate / key [s] stroke width\n";
  help += "and turn mouse wheel";
  println(help);
}

void draw() {
  background(bg);
  fill(0);
  if (showFPS ) text(nf(frameRate, 1, 1), 10, 10);
  for (int i = 0; i < many; i++) myrects[i].drawit();               // draw each rect ( and check on mouse over + click )
}

class Mybackup {
  boolean selected=false;
}

class Myrect {
  int x, y, id;//, w, h, off, rang; from global
  boolean selected=false;
  Myrect (int x, int y, int id) {
    this.x = x; 
    this.y = y;
    this.id = id;
  }
  void drawit() {
    if ( strokew > 0.2 )  { strokeWeight(strokew); stroke(stk); }
    else                  noStroke();
    if ( selected )  fill(fillsel);
    else             fill(fillnsel);
    if ( togfill )   noFill();
    push();
    translate(x,y);
    rotate(rang);
    rect(-(w-off)/2,-(h-off)/2, (w-off), (h-off));
    fill(0);   // black text
    if (shownum) text(id, -w/8, +h/8);
    pop();
    sel();
  }
  boolean over() {
    return( x-(w-off)/2 < mouseX && mouseX < x+(w-off)/2 && y-(h-off)/2 < mouseY && mouseY < y+(h-off)/2 );
  }
  void sel() {
    if ( over() ) {
      if (  selected && mousePressed && mouseButton == RIGHT) selected=false;
      if ( !selected && mousePressed && mouseButton == LEFT)  selected=true;
    }
  }
}

void set_wh() {
  // use x,y,grid as master and auto adjust rectangles (w,h) to window:
  println(" width= "+width+", height= "+height+", grid= "+grid);
  w = ( width  - 2 * x ) / grid-off;   
  println(" w= "+w+", x= "+x+", ( grid * w + 2 * x )= "+(grid*w+2*x));
  h = ( height - 2 * y ) / grid-off;
  println(" h= "+h+", y= "+y+", ( grid * h + 2 * y )= "+(grid*h+2*y));
}

void set_grid(boolean init) {
  if ( auto ) set_wh();
  if ( init )  for (int i = 0; i < many; i++)  myselects[i]=new Mybackup();                     // init backup memory
  else         for (int i = 0; i < many; i++)  myselects[i].selected = myrects[i].selected;     // backup
  for (int i = 0; i < many; i++)  myrects[i]=new Myrect(x+(i%grid)*w, y+(floor(i/grid))*h, i);  // resize
  if ( !init ) for (int i = 0; i < many; i++)  myrects[i].selected = myselects[i].selected;     // restore
}

void keyPressed() {
  if      ( keyCode == UP )    y--;
  else if ( keyCode == DOWN )  y++;
  else if ( keyCode == LEFT )  x--;
  else if ( keyCode == RIGHT ) x++;
  else if ( key     == '+' )   { w++; h++; }
  else if ( key     == '-' )   { w--; h--; }
  //h=w;              // quadrat only
  auto = false;     // confirm
  set_grid(false);  // resize
  if ( key == 'n' ) shownum = !shownum;
  if ( key == 'f' ) togfill = !togfill;
}

void mouseWheel(MouseEvent event) {
  float e = event.getCount(); //println(e);
  if ( keyPressed && key == 'x' ) { 
    x += e ;
    println(" key x: x "+x);
  }
  if ( keyPressed && key == 'y' ) { 
    y += e;
    println(" key y: y "+y);
  }
  if ( keyPressed && key == 'w' ) { 
    w += e;
    w=constrain(w,0,width);
    println(" key w: w "+w);
  }
  if ( keyPressed && key == 'h' ) { 
    h += e;
    h=constrain(h,0,height);
    println(" key h: h "+h);
  }
  if ( keyPressed && key == 'o' ) { 
    off += e;
    off=constrain(off,0,w);
    println(" key o: off "+off);
  }
  if ( keyPressed && key == 'r' ) { 
    rang += e*0.03;
    println(" key r: rang "+int(degrees(rang)));
  }
  if ( keyPressed && key == 's' ) { 
    strokew += e*0.1;
    strokew = constrain(strokew,0,w/2);
    println(" key s: strokew "+nf(strokew,1,1));
  }
}

1 Like