// Another possible inspiration: https://www.khanacademy.org/computer-programming/twinkle-twinkle/6280832014565376 let sketch = function(p) { let bgCol = hexToRgb('#222233'); let starCol = [hexToRgb('#ffcdff'), hexToRgb('#804442'), hexToRgb('#ffff7d')] let starDensity = 0.0005; //0.0005 is safe. Above 0.01 is absurd let currentWidth; let currentHeight; let nbStars; let stars; let bg; let mover; let shootingStarDirection; let time = 0; let sketchLoop = 0; p.setup = function(){ p.frameRate(24); currentWidth = p.windowWidth; currentHeight = p.windowHeight; // p.createCanvas(currentWidth, currentHeight); p.createCanvas(1920, 1080, p.SVG) // To export the result to SVG p.noLoop(); // To export the result to SVG bgInit(); mover = new Mover(); } p.draw = function(){ // p.background(bgCol); p.clear(); p.image(bg, 0, 0); if (time%72 == 0) { //72 is 3s at 24fps if (p.random(1) < 0.3) { mover.init(); let accX = p.random(12, 18) * p.random([-1, 1]); let accY = p.random(-4, 4); mover.vel.set(accX, accY); } } if (mover.lifespan < 255) { mover.update(); mover.show(); } time += 1; p.save(); // To export the result to SVG } //End of draw() class Stars { //Inspired by https://www.youtube.com/watch?v=NJjEGoqTn1Y constructor(nb) { this.nb = nb; this.x = []; this.y = []; this.color = []; this.size = []; } make() { for (let i = 0; i < this.nb; i++) { this.x[i] = p.random(0,p.width); this.y[i] = p.random(0,p.height); this.color[i] = p.random(starCol); this.color[i].setAlpha(p.random(100,230)); this.size[i] = 1 + p.random(2); } } draw() { for (let i = 0; i < this.nb; i++) { bg.strokeWeight(this.size[i]); bg.stroke(this.color[i]); bg.point(this.x[i], this.y[i]); } } } class Mover { // Simulating Forces // The Nature of Code // The Coding Train / Daniel Shiffman // https://youtu.be/Uibl0UE4VH8 // https://thecodingtrain.com/learning/nature-of-code/2.1-simulating-forces.html // https://editor.p5js.org/codingtrain/sketches/kYWcOmch constructor() { // this.pos = p.createVector( // p.random(p.round(0.2 * p.width)), // p.random(0, p.round(p.height/2)) // ); this.pos = p.createVector(0, 0); this.vel = p.createVector(0, 0); this.acc = p.createVector(0, 0); // this.r = 16; this.color = 'white'; // this.color.setAlpha(p.random(100,230)); this.size; this.lifespan = 255; this.burnrate; } init() { this.lifespan = 0; this.burnrate = p.random(2, 8); // this.size = p.random(4,7) this.acc.set(0, 0); this.vel.set(0, 0); this.pos.x = p.random(p.round(0.05 * p.width), p.round(0.95 * p.width)); this.pos.y = p.random(0, p.round(p.height*0.45)); let gravity = p.createVector(0, 0.02); this.applyForce(gravity); } applyForce(force) { this.acc.set(force); } edges() { if (this.pos.y >= p.height-this.r) { this.pos.y = p.height-this.r; this.vel.y *= -1; } if (this.pos.x >= p.width-this.r) { this.pos.x = p.width-this.r; this.vel.x *= -1; } else if (this.pos.x <= this.r) { this.pos.x = this.r; this.vel.x *= -1; } } update() { this.lifespan += this.burnrate; this.lifespan = p.constrain(this.lifespan, 0, 255); if (this.lifespan < 255) { this.pos.add(this.vel); this.vel.mult(0.98); this.vel.add(this.acc); } } show() { p.strokeWeight(this.size); // p.stroke(this.color); p.stroke(255, p.constrain(305-this.lifespan, 0, 255), 0, 255-0.7*this.lifespan); p.point(this.pos); } } p.windowResized = function() { let newWidth = p.windowWidth; let newHeight = p.windowHeight; //Redraw only if new size if bigger than previously // if (newWidth > currentWidth || newHeight > currentHeight) { if (true) { currentWidth = newWidth; currentHeight = newHeight; p.resizeCanvas(currentWidth, currentHeight); bgInit(); } } function bgInit() { nbStars = calcNumberOfStars(); bg = p.createGraphics(p.width, p.height); // bg.background(bgCol); // setGradient(0, 0, p.width, p.height, bgCol, starCol[1]); // bg.background(0, 0, 0, 0); stars = new Stars(nbStars); stars.make(); stars.draw(); } function calcNumberOfStars() { //Helps to get a consistent number of starts regardless the window size if (starDensity > 0.01) { console.log('starDensity is too high! going back to the maximum (0.01) in order to prevent too much CPU load when starting the patch'); starDensity = 0.01; } let nb = p.round(starDensity * currentWidth * currentHeight) // console.log('nbStars: ' + nb); return nb; } function hexToRgb(hex) { hex = hex.replace('#', ''); var bigint = parseInt(hex, 16); var r = (bigint >> 16) & 255; var g = (bigint >> 8) & 255; var b = bigint & 255; return p.color(r, g, b); } function setGradient(x, y, w, h, c1, c2) { bg.noFill(); // Top to bottom gradient for (let i = y; i <= y + h; i++) { let inter = p.pow(p.map(i, y, y + h, 0, 1),6); let c = bg.lerpColor(c1, c2, inter); bg.stroke(c); bg.line(x, i, x + w, i); } } }; let processingSketch = new p5(sketch, 'bg'); let processingIsOn = true;