xxxxxxxxxx
102
let theta;
let snowflakes = []; // array to hold snowflake objects
function setup() {
createCanvas(710, 400);
noStroke();
//mousePressed();
}
function draw() {
background(0);
//frameRate(30);
stroke(255);
// Let's pick an angle 0 to 90 degrees based on the mouse position
let a = (mouseX / width) * 90;
// Convert it to radians
theta = radians(a);
// Start the tree from the bottom of the screen
translate(width/2,height);
// Draw a line 120 pixels
line(0,0,0,-120);
// Move to the end of that line
translate(0,-120);
// Start the recursive branching!
branch(120);
push();
let t = frameCount / 60; // update time
// create a random number of snowflakes each frame
for (let i = 0; i < random(5); i++) {
snowflakes.push(new snowflake()); // append snowflake object
}
// loop through snowflakes with a for..of loop
for (let flake of snowflakes) {
flake.update(t); // update snowflake position
flake.display(); // draw snowflake
}
pop();
}
function branch(h) {
// Each branch will be 2/3rds the size of the previous one
h *= 0.66;
// All recursive functions must have an exit condition!!!!
// Here, ours is when the length of the branch is 2 pixels or less
if (h > 2) {
push(); // Save the current state of transformation (i.e. where are we now)
rotate(theta); // Rotate by theta
line(0, 0, 0, -h); // Draw the branch
translate(0, -h); // Move to the end of the branch
branch(h); // Ok, now call myself to draw two new branches!!
pop(); // Whenever we get back here, we "pop" in order to restore the previous matrix state
// Repeat the same thing, only branch off to the "left" this time!
push();
rotate(-theta);
line(0, 0, 0, -h);
translate(0, -h);
branch(h);
pop();
}
}
// snowflake class
function snowflake() {
// initialize coordinates
this.posX = 0;
this.posY = random(-1000, 100);
this.initialangle = random(0, 2 * PI);
this.size = random(1, 3);
// radius of snowflake spiral
// chosen so the snowflakes are uniformly spread out in area
this.radius = sqrt(random(pow(width, 2)));
this.update = function(time) {
// x position follows a circle
let w = 0.1; // angular speed
let angle = w * time + this.initialangle;
this.posX = width/2 + this.radius * sin(angle);
// different size snowflakes fall at slightly different y speeds
this.posY += pow(this.size, 0.5);
// delete snowflake if past end of screen
if (this.posY > height) {
let index = snowflakes.indexOf(this);
snowflakes.splice(index, 1);
}
};
this.display = function() {
ellipse(this.posX, this.posY, this.size);
};
}