|
|
/*
|
|
|
Yes—p5’s “frame buffers” are createGraphics() layers. In your sketch we can do three layers:
|
|
|
|
|
|
bgLayer—draw the gradient once (never clears).
|
|
|
|
|
|
leafLayer—redraw every frame for the animated leaves (clear each frame so motion is smooth).
|
|
|
|
|
|
clickLayer—optional persistent marks (e.g., mouse-added leaves/stars) that don’t clear.
|
|
|
|
|
|
I also made leaf() draw into a given buffer and added safe defaults so calls without args don’t break.
|
|
|
|
|
|
|
|
|
Key ideas:
|
|
|
|
|
|
Draw long-lived stuff (gradient) once to a buffer and reuse it.
|
|
|
|
|
|
For animated content, clear that buffer each frame (pg.clear()).
|
|
|
|
|
|
Compose with image() in the order you want (background → persistent → animated).
|
|
|
*/
|
|
|
|
|
|
let x1 = 30, y1 = 0, x4 = 480, y4 = 0;
|
|
|
let x2, y2, x3, y3;
|
|
|
|
|
|
let bgLayer, leafLayer, clickLayer;
|
|
|
|
|
|
function setup() {
|
|
|
createCanvas(1024, 800);
|
|
|
angleMode(RADIANS);
|
|
|
|
|
|
// off-screen buffers
|
|
|
bgLayer = createGraphics(width, height);
|
|
|
leafLayer = createGraphics(width, height);
|
|
|
clickLayer= createGraphics(width, height);
|
|
|
|
|
|
// paint the gradient ONCE to bgLayer
|
|
|
const c1 = color(50);
|
|
|
const c2 = color(212, 91, 70);
|
|
|
for (let y = 0; y < height; y++) {
|
|
|
const n = map(y, 0, height, 0, 1);
|
|
|
const newc = lerpColor(c1, c2, n);
|
|
|
bgLayer.stroke(newc);
|
|
|
bgLayer.line(0, y, width, y);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
function draw() {
|
|
|
// clear the animated layer each frame (transparent)
|
|
|
leafLayer.clear();
|
|
|
|
|
|
// draw animated leaves into leafLayer
|
|
|
leaf(leafLayer); // uses defaults (0,0,0,1)
|
|
|
leaf(leafLayer, 200, 200, PI/4, 1);
|
|
|
leaf(leafLayer, 500, 400, PI/4, -1);
|
|
|
leaf(leafLayer, 100, 700); // uses defaults
|
|
|
|
|
|
// composite the layers to the main canvas
|
|
|
image(bgLayer, 0, 0);
|
|
|
image(clickLayer,0, 0);
|
|
|
image(leafLayer, 0, 0);
|
|
|
}
|
|
|
|
|
|
// draw a leaf into a specified buffer (pg)
|
|
|
function leaf(pg, leafX=0, leafY=0, leafRotation=0, scaleFactor=1) {
|
|
|
pg.push();
|
|
|
pg.translate(leafX, leafY);
|
|
|
pg.rotate(leafRotation);
|
|
|
pg.scale(scaleFactor, 1);
|
|
|
|
|
|
x2 = 100 * sin(frameCount * 0.5) + 1;
|
|
|
y2 = 100 * sin(frameCount * 0.005) + 10;
|
|
|
x3 = 180 * sin(frameCount * 0.005) + 10;
|
|
|
y3 = 150 * sin(frameCount * 0.005) + 10;
|
|
|
|
|
|
pg.noStroke();
|
|
|
pg.fill(160, 82, 45);
|
|
|
|
|
|
pg.beginShape();
|
|
|
pg.curveVertex(x1, y1);
|
|
|
pg.curveVertex(x1, y1);
|
|
|
pg.curveVertex(x2, y2);
|
|
|
pg.curveVertex(x3, y3);
|
|
|
pg.curveVertex(x4, y4);
|
|
|
pg.curveVertex(x4, y4);
|
|
|
pg.endShape();
|
|
|
|
|
|
pg.beginShape();
|
|
|
pg.curveVertex(x1, y1);
|
|
|
pg.curveVertex(x1, y1);
|
|
|
pg.curveVertex(x2, -y2);
|
|
|
pg.curveVertex(x3, -y3);
|
|
|
pg.curveVertex(x4, y4);
|
|
|
pg.curveVertex(x4, y4);
|
|
|
pg.endShape();
|
|
|
|
|
|
pg.pop();
|
|
|
}
|
|
|
|
|
|
// optional: add persistent clicks to their own buffer
|
|
|
function mousePressed() {
|
|
|
clickLayer.push();
|
|
|
clickLayer.noStroke();
|
|
|
clickLayer.fill(255, 230); // slight glow
|
|
|
clickLayer.ellipse(mouseX, mouseY, 10, 10);
|
|
|
clickLayer.pop();
|
|
|
}
|