How I would do this is to use the PImage.mask()
method. So PGraphics extends PImage meaning it gets the mask()
method as well. Check out the mask()
example here and documentation here.
You can think of PGraphics as just another processing window within your current window. To use the PGraphics, you preface your processing functions with the name of the PGraphics variable. You can also use PGraphics in most ways where you would use an image. I think the best way to explain this is to look at examples so here is one. Anyways if you already knew that sorry for wasting your time.
I would make one PGraphics be the gradient and the other be the mask to apply to gradient. You just draw the gradient to a PGraphics layer and then create a mask PGraphics that you can draw anything onto. Here the key is to remember is 0 alpha will be nothing and 255 alpha will show everything. Alpha is either the second or fourth argument to color(). Then use gradient.mask(mask);
. This all might make sense in the quick example I made below:
int X_AXIS = 1;
color c1, c2;
PGraphics gg; // gradient graphics
PGraphics mask;
void setup() {
size(512, 512, P2D);
gg = createGraphics(width, height);
mask = createGraphics(width, height);
c1 = color(204, 102, 0);
c2 = color(0, 102, 153);
}
void draw() {
gradient(gg, 0, 0, width, height, c1, c2, X_AXIS);
// image(gg, 0, 0); // displays gradient before mask
circleMask(mask);
// image(mask, 0, 0); // displays mask
gg.mask(mask);
image(gg, 0, 0); // displays gradient after mask
}
void gradient(PGraphics pg, int x, int y, float w, float h, color c1, color c2, int axis) {
pg.beginDraw();
pg.noFill();
if (axis == X_AXIS) {
for (int i = x; i <=x+w; i++) {
float amt = map(i, x, x+w, 0, 1);
color c = lerpColor(c1, c2, amt/map(mouseX*2, 0, 512, 0, 1));
pg.stroke(c);
pg.line(i, y, i, y+h);
}
}
pg.endDraw();
}
void circleMask(PGraphics pg) {
pg.beginDraw();
pg.background(0);
pg.noStroke();
pg.fill(255, 255);
pg.ellipse(width/2, height/2, 3*width/4, 3*height/4);
pg.endDraw();
}