PGraphics recreation safely

if a PGraphics object is recreated with a different size, does the user need to invoke setup() again or is it safe to just keep calling draw()

1 Like

Just keep calling draw()

for example, if i take the Draggable Cube example

i give it an initial size of 200, 200

the cube appears at 100, 100

resize it to, say 120, 120

the cube is still drawn at 100, 100

should the cube instead be drawn to 60, 60 after the resize?

class Applications_DraggableExample extends Window {
  float bx;
  float by;
  int boxSizeX = 20;
  int boxSizeY = 20;
  boolean overBox = false;
  boolean locked = false;
  float xOffset = 0.0;
  float yOffset = 0.0;
    
  @Override
  void setup() {
    graphics.beginDraw();
    // if this is called after a resize then
    // the user will lose the current position of the box after a resize
    bx = width/2.0;
    by = height/2.0;
    // move rectMode into draw as PGraphics recreation seems to reset rectMode
    graphics.endDraw();
  }
  
  @Override
  void draw() { 
    graphics.beginDraw();
    graphics.background(0);
    // reset rectMode here
    graphics.rectMode(RADIUS);
    
    // we risk loosing the box entirely if the user resizes the graphics object
    // to less than bx, by
    // if this happens the user will need to resize the graphics object
    // move the box to a suitible location
    // then resize the graphics object again
    
    // Test if the cursor is over the box 
    if (mouseX > bx-boxSizeX && mouseX < bx+boxSizeX && 
        mouseY > by-boxSizeY && mouseY < by+boxSizeY) {
      overBox = true;
      if(!locked) { 
        graphics.stroke(255); 
        graphics.fill(153);
      } 
    } else {
      graphics.stroke(153);
      graphics.fill(153);
      overBox = false;
    }
    
    // Draw the box
    graphics.rect(bx, by, boxSizeX, boxSizeY);
    graphics.endDraw();
  }
  
  @Override
  void mousePressed() {
    if(overBox) { 
      locked = true; 
      graphics.fill(255, 255, 255);
    } else {
      locked = false;
    }
    xOffset = mouseX-bx; 
    yOffset = mouseY-by; 
  
  }
  
  @Override
  void mouseDragged() {
    if(locked) {
      bx = mouseX-xOffset; 
      by = mouseY-yOffset; 
    }
  }
  
  @Override
  void mouseReleased() {
    locked = false;
  }
}```

That’s right

You give a box always the center position.

This means when you shrink it it stays at its center but its left edge moves right

I assume that graphics is a PGraphics object

to clear it just say graphics.background(0);

see https://www.processing.org/reference/PGraphics.html

ok, how would i modify this example in order to incorporate that, eg would i need some sort of scaled coordinates system?

What do you want to achieve?

Where are you stuck?

im wondering how to correctly handle coordinates for resizable off screen PGraphics objects

In 3D?

Can you provide a minimal
runnable example of your question?

like, if the height and width can change during runtime, how would i need to account for this?

Read again my last post

There are two ways to make a sketch “responsive”, the first one is to always recalculate the exact position. So, in your example, you are calculating the positions of bx and by in setup, but it should be always calculated in draw() to be able to take the change of width and height into account.

Second, it is possible to use scale(int) (docs) on your PGraphics to scale it to the right size and always use your initial parameters. But for that you would have to listen for the window resize and adjust the scale parameter accordingly.

And as @Chrisir already mentioned: Try to provide a very simple example everyone can run directly inside Processing, otherwise people are not willing to dig into your code and try to find out whats wrong.

I am not sure why you have a PGraphics in the first place…

When you resize the PGraphics in a 3D context I think the perspective would be wrong.

I think when you display a PGraphics with image() command it depends whether you use imageMode (CENTER) or (CORNER) (can’t remember exactly). When you use a box though there is no such thing as boxMode().

Therefore when you make your box 30 px smaller you need to move it left 15 px (half the change) to simulate a boxMode CORNER, which means left alignment of the box.

Regards

Chrisir

here is an example of an left aligned box (without PGraphics)

change box size with + and -

see how the position and size both have to change to make it left aligned (in keyPressedThroughout())

Regards,

Chrisir :wink:

// pos of red box 
float x, y, z; 

// pos of blue box
float x2, y2, z2;
float w2, h2, d2; // size 

void setup() {
  size(700, 700, P3D);
  background(0); 

  x=width/2-167;
  y=height/2+225;
  z=-120;

  x2=width/2-167;
  y2=height/2+225;
  z2=-120;

  w2=60; 
  h2=110;
  d2=90;

  x2 += w2;
} 

void draw() {
  background(0); 

  showBoxFixed();

  showBoxResize();

  keyPressedThroughout();
}

void showBoxFixed() {
  // box 
  pushMatrix();
  translate(x, y, z); 
  stroke(111);
  fill(255, 0, 0); 
  box(60, 260, 90); 
  // box(45, 3, 3);
  popMatrix();
}

void showBoxResize() {
  // box 
  pushMatrix();
  translate(x2, y2, z2); 
  stroke(255);
  fill(0, 0, 255); 
  box(w2, h2, d2); 
  // box(45, 3, 3);
  popMatrix();
}

void keyPressedThroughout() {
  if (!keyPressed) 
    return;

  if (key=='+') {
    w2+=2;
    x2+=1;
  }
  if (key=='-') {
    if (w2>2) {
      w2-=2;
      x2-=1;
    }
  }//
}