// tree https://editor.p5js.org/mtchl/sketches/ryyW2U5Fx // leaf https://editor.p5js.org/projects/SkBQYKdVW // note: canvasWidth and canvasHeight will be defined before this script runs const num_across = 20; const num_down = 10; const cell_width = canvasWidth / num_across; const cell_height = canvasHeight / num_down; let x_grid_locations = []; let y_grid_locations = []; const frameMax = 60; let recording = false; let gifRecorder = null; const buffersPerFrame = 3; let random_seed = 0; /* helper function */ String.prototype.hashCode = function() { var hash = 0, i, chr; if (this.length === 0) return hash; for (i = 0; i < this.length; i++) { chr = this.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; // Convert to 32bit integer } return hash; }; /* getNoiseValue arguments: x: current grid location across y: current grid location down loop: can be any value from 0-1 and will loop name: the "name" of the lookup table. probably change this each time. min/max: the minimum and maximum of the value to return smoothness: 1 means elements are not related. larger numbers cause groupings. */ function getNoiseValue(x, y, loop, name, min, max, smoothness) { let hashNumber = name.hashCode(); let xoff = cos(2*PI*loop); let yoff = sin(2*PI*loop); let noiseVal = noise(xoff + x / smoothness, yoff + y / smoothness, (0 + hashNumber)); return map(noiseVal, 0, 1, min, max); } function storeGridPoints(param1, param2) { x_grid_locations = new Array(num_across+1); y_grid_locations = new Array(num_down+1); for (let i = 0; i < num_across+1; i++) { let x = map(i, 0, num_across, 0, width); x_grid_locations[i] = x; } for (let i = 0; i < num_down+1; i++) { let y = map(i, 0, num_down, 0, height); y_grid_locations[i] = y; } } function setup () { let main_canvas = createCanvas(canvasWidth, canvasHeight); main_canvas.parent('canvasContainer'); storeGridPoints(); random_seed = random(); } function mousePressed() { if(recording == false) { recording = true; gifRecorder = new p5recorder(frameMax, "wallpaper.gif", 25, 0, buffersPerFrame); } } function branch(depth){ if (depth < 10) { line(0,0,0,-height/12); // draw a line going up { translate(0,-height/12); // move the space upwards rotate(random(-0.05,0.05)); // random wiggle if (random(1.0) < 0.6){ // branching rotate(0.3); // rotate to the right scale(0.8); // scale down push(); // now save the transform state branch(depth + 1); // start a new branch! pop(); // go back to saved state rotate(-0.6); // rotate back to the left push(); // save state branch(depth + 1); // start a second new branch pop(); // back to saved state } else { // no branch - continue at the same depth branch(depth); } } } } function drawLeaf() { push(); translate(-50, -50); stroke(50,140,48); strokeWeight(2); arc(50, 60, 40, 40, 0, PI, OPEN); noFill(); arc(65, 60, 40, 80, PI/1.5, 3*PI/2, OPEN);//leaf vein arc(65,60,70,80,PI,3*PI/2,OPEN); arc(70,20,10,80,PI/2,PI,OPEN); fill(50,140,48); strokeWeight(1); triangle(46, 75, 69, 62, 44, 68); triangle(44, 68, 32, 60, 46, 75); triangle(45, 60, 65, 44, 45, 51); triangle(45, 60, 33, 44, 45, 51); triangle(49,36,43,30,47,40); triangle(49,36,65,31,47,40); pop(); } function draw () { let animation_max_frames = frameMax; if(recording) { animation_max_frames = frameMax * buffersPerFrame; } let cur_frame = frameCount % animation_max_frames; let cur_frac = map(cur_frame, 0, animation_max_frames, 0, 1); background("#99d9ff"); fill(0, 130, 0); rect(0, 3*height/4, width, height); fill(0); stroke(0); resetFocusedRandom(random_seed); strokeWeight(int(0.02 * height)); for(let i=0; i<4; i++) { let x_disp = map(i, -1, 4, 0, width); push(); translate(x_disp, 0.90 * height); branch(0); pop(); } noStroke(); // debug show the grid /* stroke(10); for (let i = 0; i < num_down; i=i+1) { for (let j = 0; j < num_across; j=j+1) { let y1 = y_grid_locations[i]; let x1 = x_grid_locations[j]; let y2 = y_grid_locations[i+1]; let x2 = x_grid_locations[j+1]; line(x1, y1, x2, y1); line(x1, y1, x1, y2); } } */ // draw the background circles let white_ellipse_radius = 0.78 * cell_width; let inner_ellipse_radius = 0.50 * cell_width; for (let i = 2; i < num_down-4; i=i+1) { for (let j = 0; j < num_across; j=j+1) { let y1 = y_grid_locations[i]; let x1 = x_grid_locations[j]; let xloc = x1 + cell_width/2; let yloc = y1 + cell_height/2; fill("#ffffff"); // ellipse(xloc, yloc, white_ellipse_radius); fill("#99d9ff"); let cur_shift_x = getNoiseValue(i, j, cur_frac, "cur_shift_x", -0.4, 0.4, 10); let cur_shift_y = getNoiseValue(i, j, cur_frac, "cur_shift_y", -0.4, 0.4, 10); // let cur_radius = getNoiseValue(i, j, cur_frac, "cur_radius", 0.3, 0.7, 100); // inner_ellipse_radius = cur_radius * cell_width; let shifted_x = xloc + cur_shift_x * cell_width; let shifted_y = yloc + cur_shift_y * cell_width; // ellipse(shifted_x, shifted_y, inner_ellipse_radius); let leaf_spin = getNoiseValue(i, j, 0, "leaf_spin", -PI/4, PI/2, 1); push(); translate(shifted_x, shifted_y); rotate(leaf_spin); let scale_factor = 0.8 * height / 480; scale(scale_factor); drawLeaf(); pop(); } } /* // draw the brown and red circles let teal_ellipse_radius = 0.7 * cell_width; let bright2_ellipse_radius = 0.58 * cell_width; let violet_ellipse_radius = 0.38 * cell_width; for (let i = 0; i < num_down+1; i=i+1) { for (let j = 0; j < num_across; j=j+1) { let y1 = y_grid_locations[i]; let x1 = x_grid_locations[j]; fill("#98ffec"); ellipse(x1, y1, teal_ellipse_radius); fill("#feffff"); ellipse(x1, y1, bright2_ellipse_radius); fill("#A1DEE5"); ellipse(x1, y1, violet_ellipse_radius); } } */ // drawLeaf(); if(recording) { gifRecorder.addBuffer(); } } function keyTyped() { if (key == '!') { saveBlocksImages(); } else if (key == '@') { saveBlocksImages(true); } }