You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

189 lines
4.9 KiB

let snowflake_max_r = 12;
let snowflake_min_r = 7;
let snowflake_max_count = 500;
class Background{
bgColor: p5.Color = p.color(100, 100, 255);
snowflakes: Snowflake[]
foregroundSnowflakes: Snowflake[]
backgroundSnowflakes: Snowflake[]
wind_direction: number = 0
ground: Ground = new Ground()
constructor() {
this.snowflakes = [];
for (let i = 0; i < snowflake_max_count; i++){
this.snowflakes.push(this.getNewSnowflake());
}
this.snowflakes.sort((a, b) => {
if (a.radius < b.radius){
return -1;
}
if (a.radius > b.radius){
return 1;
}
return 0;
});
this.backgroundSnowflakes = this.snowflakes.slice(0, snowflake_max_count * 2 / 3);
this.foregroundSnowflakes = this.snowflakes.slice(snowflake_max_count * 2 / 3, snowflake_max_count);
this.updateSettings();
}
getNewSnowflake(){
return new Snowflake(
p.random(p.width),
p.random(-snowflake_max_r, p.height),
p.random(snowflake_min_r, snowflake_max_r),
);
}
updateSettings(){
let allowed_snowflakes_count = $('#snow_intensity').val() as number;
let visible_snowflakes = p.shuffle(this.snowflakes.filter(s => !s.hidden));
let hidden_snowflakes = p.shuffle(this.snowflakes.filter(s => s.hidden));
let snowflakes_to_add = allowed_snowflakes_count - visible_snowflakes.length;
if (snowflakes_to_add > 0){
for (let i = 0; i < snowflakes_to_add; i++){
hidden_snowflakes[i].hidden = false;
}
}
if (snowflakes_to_add < 0){
for (let i = 0; i < p.abs(snowflakes_to_add); i++){
visible_snowflakes[i].hidden = true;
}
}
this.bgColor.setBlue(
p.map(
allowed_snowflakes_count,
0, snowflake_max_count,
255, 170
)
);
}
update(){
this.ground.update();
this.wind_direction = p.sin(p.frameCount / 1000);
this.snowflakes.forEach(s => s.update(this.wind_direction));
}
display(asForeground?: boolean){
if (asForeground){
this.foregroundSnowflakes.forEach(s => s.display());
} else {
p.background(this.bgColor);
this.ground.display();
this.backgroundSnowflakes.forEach(s => s.display());
}
}
}
class Snowflake{
pos: p5.Vector
radius: number
alpha: number
hidden: boolean
rotateDir: number
rotation: number = 0
peakCount: number
constructor(x, y, r) {
this.pos = p.createVector(x, y);
this.radius = r;
this.hidden = false;
this.alpha = 0;
this.rotateDir = p.random([-1, 1]) * p.random(0.01, 0.03);
this.peakCount = p.random([4, 5, 6]);
}
update(wind_direction: number){
let dir = p.createVector(
p.map(this.radius, snowflake_min_r, snowflake_max_r, 0, 1) * wind_direction,
p.map(this.radius, snowflake_min_r, snowflake_max_r, 0.5, 1) * 2
);
this.pos.add(dir);
this.rotation += this.rotateDir;
if (this.pos.y > p.height + this.radius){
this.pos.y = -this.radius;
}
if (this.pos.x > p.width + this.radius){
this.pos.x = -this.radius;
} else if (this.pos.x < -this.radius){
this.pos.x = p.width + this.radius;
}
if (this.hidden && this.alpha > 0){
this.alpha -= 0.015;
} else if (this.alpha < 1){
this.alpha += 0.015;
}
}
display(){
p.push();
p.strokeWeight(1);
p.stroke(255, this.alpha * 255);
p.fill(255, this.alpha * 255);
p.translate(this.pos);
p.rotate(this.rotation % p.TWO_PI);
for (let rad = 0; rad < p.PI; rad += p.PI / this.peakCount){
let x1 = p.cos(rad) * this.radius;
let y1 = p.sin(rad) * this.radius;
let x2 = p.cos(rad + p.PI) * this.radius;
let y2 = p.sin(rad + p.PI) * this.radius;
p.line(x1, y1, x2, y2);
}
p.pop();
}
}
class Ground{
points: p5.Vector[]
constructor() {
this.createPoints();
}
createPoints(){
this.points = [];
for (let x = 0; x < p.width; x++){
let vector = p.createVector(
x,
p.noise(x / 300) * 150
);
this.points.push(vector);
}
}
update(){
}
display(){
p.push();
p.fill(220, 220, 255);
p.stroke(50, 50, 150);
p.strokeWeight(2);
p.beginShape();
for (let point of this.points){
p.vertex(point.x, point.y + p.height / 2);
}
p.vertex(p.width, p.height);
p.vertex(0, p.height);
p.endShape(p.CLOSE);
p.pop();
}
}