float globalRadious = 200;
PGraphics mask;
ArrayList<Hole> holes;
void setup(){
size(500, 500);
smooth();
frameRate(30);
noStroke();
mask = createGraphics(width, height);
holes = new ArrayList<Hole>();
for(int i = 0; i < 300; i++){
holes.add(new Hole());
}
}
void draw(){
background(64);
translate(width / 2, height / 2);
mask.beginDraw();
mask.background(255);
mask.pushMatrix();
mask.translate(width / 2, height / 2);
mask.fill(64);
mask.noStroke();
fill(153, 14, 42);
ellipse(0, 0, globalRadious * 2, globalRadious * 2);
for(Hole hole: holes){
hole.update();
ellipse(hole.pos.x, hole.pos.y, hole.diameter + 10, hole.diameter + 10);
mask.ellipse(hole.pos.x, hole.pos.y, hole.diameter, hole.diameter);
}
mask.popMatrix();
mask.endDraw();
blend(mask, 0, 0, width, height, 0, 0, width, height, DARKEST);
}
class Hole {
PVector pos;
float maxDiameter;
float diameterSpeed;
float diameterOffset;
float diameter;
Hole(){
float posRadian = map(random(1), 0, 1, 0, TWO_PI);
float posRadious = map(pow(random(1), 1.0 / 3.0), 0, 1, 0, globalRadious);
pos = new PVector(posRadious * cos(posRadian), posRadious * sin(posRadian));
maxDiameter = map(random(1), 0, 1, 20, 50);
diameterSpeed = map(random(1), 0, 1, PI / 8, PI / 4);
diameterOffset = map(random(1), 0, 1, 0, TWO_PI);
diameter = 0.0;
}
void update(){
diameter = maxDiameter * map(sin(diameterSpeed * frameCount + diameterOffset), -1, 1, 0, 1);
}
}