HNY2025
p5.js
View Source Code
// by shibomb https://shibomb.xyz
// License: CC BY-NC-SA 4.0
const WORDS =
"2025 KEEPGOING NEXTSTEP CRAZY CHALLENGE COMPLETE YOU ME LOVE CONTINUE SUPPORT OBLIGATION ART PROGRAM GAME CREATIVE ACTION HEAVY METAL CAT COMPUTER SIMPLE LUCKY FULL FUTURE MOVE KINDNESS BUILD DONTSTOP";
const RANDOM_WORDS = true;
const INTERVAL_SECONDS = 1.618;
const X_TERM = 4;
const Y_TERM = 16;
const X_INIT = X_TERM * 2;
const Y_INIT = 180;
const SIZE = 138 * 1.618;
const STROKE_WEIGHT = 4; // 4
const USE_GRADATION = true;
class Baloon {
constructor(str, x, y, size, c1, c2) {
this.str = str;
this.pos = createVector(x, y);
this.size = size;
this.c1 = c1;
this.c2 = c2;
this.points = myFont.textToPoints(this.str, 0, 0, this.size, {
sampleFactor: 0.2,
simplifyThreshold: 0.1,
});
this.bbox = myFont.textBounds(this.str, 0, 0, this.size);
this.count = floor(random(0, 10));
}
update() {
this.count++;
if (this.count < 10) this.count += 10;
}
setGradation() {
let gradientStroke = drawingContext.createLinearGradient(
0,
0,
this.bbox.w,
0
);
gradientStroke.addColorStop(0, this.c1);
gradientStroke.addColorStop(0.25, this.c1);
gradientStroke.addColorStop(1, this.c2);
drawingContext.strokeStyle = gradientStroke;
}
display() {
if (this.pos.y > height + SIZE ) return
push();
translate(this.pos.x, this.pos.y);
// stroke(20);
strokeWeight(STROKE_WEIGHT);
strokeCap(PROJECT);
strokeJoin(MITER);
if (USE_GRADATION) {
this.setGradation();
}
noFill()
beginShape();
for (let i = 0; i < this.points.length; i++) {
vertex(
this.points[i].x + (random() -0.5) *this.points[i].y*0.2,
this.points[i].y + (random() -0.5) *this.points[i].x*0.2
);
}
// for (let i = 0; i < min(3, this.points.length); i++) {
// curveVertex(
// this.points[i].x + this.moves[i].x,
// this.points[i].y + this.moves[i].y
// );
// }
endShape(CLOSE);
// fill("Red");
// for (let i = 0; i < this.points.length; i++) {
// circle(
// this.points[i].x + this.moves[i].x,
// this.points[i].y + this.moves[i].y,
// 4);
// }
pop();
}
}
// ---------------------------------------------------------
// main
// ---------------------------------------------------------
let W, H;
let objs = [];
let myFont;
let MESSAGE;
let bgc1, bgc2;
function preload() {
myFont = loadFont("Roboto-Bold.ttf");
// myFont = loadFont("BIZUDPGothic-Bold.ttf");
}
function setup() {
// W = 640
// W = min(windowWidth, windowHeight)
// H = W;
W = windowWidth;
H = windowHeight;
createCanvas(W, H);
textFont(myFont);
init();
setInterval(init, INTERVAL_SECONDS * 1000);
}
function shuffleMessage() {
let words = WORDS.split(" ");
if (RANDOM_WORDS) {
shuffle(words, true);
}
MESSAGE = words.join(" ");
}
function randomColor(min = 30, max = 220, alpha = 255) {
return color(
Math.floor(random(min, max)),
Math.floor(random(min, max)),
Math.floor(random(min, max)),
alpha
);
}
function init() {
let xTerm = X_TERM;
let xInit = X_INIT;
let yTerm = Y_TERM;
let yInit = Y_INIT;
let x = xInit;
let y = yInit;
let h = 0;
let size = SIZE;
shuffleMessage();
let strs = MESSAGE.split("");
objs = [];
let c1 = randomColor();
let c2 = randomColor();
let sizeRadmom = 0;
for (const str of strs) {
bbox = myFont.textBounds(str, 0, 0, size);
if (str == " ") {
c1 = randomColor();
c2 = randomColor();
}
if (x + bbox.w > width - xInit) {
x = xInit;
y += h + yTerm;
h = 0;
if (str == " ") {
continue;
}
}
objs.push(new Baloon(str, x, y, size + sizeRadmom, c1, c2));
x += objs[objs.length - 1].bbox.w + xTerm;
h = max(h, objs[objs.length - 1].bbox.h);
}
//
bgc1 = randomColor(200, 220, 32);
bgc2 = randomColor(200, 220, 32);
// bgc1 = randomColor();
// bgc2 = randomColor();
}
function setGradation() {
let gradientStroke = drawingContext.createLinearGradient(
width * 0.4,
height * 0.1,
width * 0.6,
height * 0.9
);
gradientStroke.addColorStop(0, bgc1);
gradientStroke.addColorStop(1, bgc2);
drawingContext.fillStyle = gradientStroke;
}
function draw() {
background(bgc1, 20);
for (const obj of objs) {
obj.update();
}
setGradation();
rect(0, 0, width, height);
for (const obj of objs) {
obj.display();
}
}