Mix Youtube videos like a true DJ!
https://dj.tflcl.xyz
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.
251 lines
5.7 KiB
251 lines
5.7 KiB
// Another possible inspiration: https://www.khanacademy.org/computer-programming/twinkle-twinkle/6280832014565376 |
|
let sketch = function(p) { |
|
let svgExport = false; // To export the result to SVG |
|
|
|
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; |
|
|
|
if (svgExport) { |
|
p.createCanvas(1920, 1080, p.SVG) // To export the result to SVG |
|
p.noLoop(); // To export the result to SVG |
|
} else { |
|
p.createCanvas(currentWidth, currentHeight); |
|
} |
|
|
|
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; |
|
|
|
if (svgExport) { |
|
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;
|
|
|