Concept & Inspiration
Aaron Sherwood’s portfolio website had me impressed since the past 2 years, and it had been on my to-do list of things to learn just because of how addictive its animations were. Therefore, I decided to pursue this assignment in p5js to produce something similar and learn something new.
The website I took inspiration from is linked here
Embedded Canvas
The assignment outcome is attached as an embedded sketch as follows:
Code
The methodology to convert the text to points:
function setup() {
createCanvas(600, 400);
textSize(64);
textFont(font);
for (let i = 0; i < texts.length; i++) {
let points = font.textToPoints(texts[i], 50 + i * 150, height / 2,50, {sampleFactor: 0.75, simplifyThreshold: 0 });
for (let j = 0; j < points.length; j++) {
let p = new Particle(points[j].x, points[j].y);
particles.push(p);
}
}
}
function setup() {
createCanvas(600, 400);
textSize(64);
textFont(font);
for (let i = 0; i < texts.length; i++) {
let points = font.textToPoints(texts[i], 50 + i * 150, height / 2,50, {sampleFactor: 0.75, simplifyThreshold: 0 });
for (let j = 0; j < points.length; j++) {
let p = new Particle(points[j].x, points[j].y);
particles.push(p);
}
}
}
function setup() { createCanvas(600, 400); textSize(64); textFont(font); for (let i = 0; i < texts.length; i++) { let points = font.textToPoints(texts[i], 50 + i * 150, height / 2,50, {sampleFactor: 0.75, simplifyThreshold: 0 }); for (let j = 0; j < points.length; j++) { let p = new Particle(points[j].x, points[j].y); particles.push(p); } } }
Object Oriented Nature of the Particles!
class Particle {
constructor(x, y) {
this.pos = createVector(x, y);
this.vel = createVector(random(-1, 1), random(-1, 1));
this.acc = createVector(0, 0);
this.target = createVector(x, y);
this.size = 2;
this.maxSpeed = 2;
this.maxForce = 0.1;
this.attractRadius = 50;
this.attractForce = 0.1;
this.color = color(255, 255, 255);
}
behaviors() {
let arrive = this.arrive(this.target);
this.applyForce(arrive);
this.repel();
}
repel() {
let mouse = createVector(mouseX, mouseY);
let distance = p5.Vector.dist(this.pos, mouse);
if (distance < this.attractRadius) {
let repelForce = p5.Vector.sub(this.pos, mouse).normalize().mult(this.attractForce);
this.applyForce(repelForce);
}
}
attract() {
let mouse = createVector(mouseX, mouseY);
let distance = p5.Vector.dist(this.pos, mouse);
if (distance < this.attractRadius) {
let attractForce = p5.Vector.sub(mouse, this.pos).normalize().mult(this.attractForce);
this.applyForce(attractForce);
}
}
applyForce(f) {
this.acc.add(f);
}
arrive(target) {
let desired = p5.Vector.sub(target, this.pos);
let d = desired.mag();
let speed = this.maxSpeed;
if (d < 100) {
speed = map(d, 0, 100, 0, this.maxSpeed);
}
desired.setMag(speed);
let steer = p5.Vector.sub(desired, this.vel);
steer.limit(this.maxForce);
return steer;
}
update() {
this.pos.add(this.vel);
this.vel.add(this.acc);
this.acc.mult(0);
}
show() {
// Set the fill color based on the velocity of the particle
let vel = this.vel.mag();
if (vel < 0.5) {
this.color = color(255, 0, 0); // red
} else if (vel < 1) {
this.color = color(255, 255, 0); // yellow
} else {
this.color = color(255, 255, 255); // white
}
fill(this.color);
noStroke();
ellipse(this.pos.x, this.pos.y, this.size, this.size);
}
}
class Particle {
constructor(x, y) {
this.pos = createVector(x, y);
this.vel = createVector(random(-1, 1), random(-1, 1));
this.acc = createVector(0, 0);
this.target = createVector(x, y);
this.size = 2;
this.maxSpeed = 2;
this.maxForce = 0.1;
this.attractRadius = 50;
this.attractForce = 0.1;
this.color = color(255, 255, 255);
}
behaviors() {
let arrive = this.arrive(this.target);
this.applyForce(arrive);
this.repel();
}
repel() {
let mouse = createVector(mouseX, mouseY);
let distance = p5.Vector.dist(this.pos, mouse);
if (distance < this.attractRadius) {
let repelForce = p5.Vector.sub(this.pos, mouse).normalize().mult(this.attractForce);
this.applyForce(repelForce);
}
}
attract() {
let mouse = createVector(mouseX, mouseY);
let distance = p5.Vector.dist(this.pos, mouse);
if (distance < this.attractRadius) {
let attractForce = p5.Vector.sub(mouse, this.pos).normalize().mult(this.attractForce);
this.applyForce(attractForce);
}
}
applyForce(f) {
this.acc.add(f);
}
arrive(target) {
let desired = p5.Vector.sub(target, this.pos);
let d = desired.mag();
let speed = this.maxSpeed;
if (d < 100) {
speed = map(d, 0, 100, 0, this.maxSpeed);
}
desired.setMag(speed);
let steer = p5.Vector.sub(desired, this.vel);
steer.limit(this.maxForce);
return steer;
}
update() {
this.pos.add(this.vel);
this.vel.add(this.acc);
this.acc.mult(0);
}
show() {
// Set the fill color based on the velocity of the particle
let vel = this.vel.mag();
if (vel < 0.5) {
this.color = color(255, 0, 0); // red
} else if (vel < 1) {
this.color = color(255, 255, 0); // yellow
} else {
this.color = color(255, 255, 255); // white
}
fill(this.color);
noStroke();
ellipse(this.pos.x, this.pos.y, this.size, this.size);
}
}
class Particle { constructor(x, y) { this.pos = createVector(x, y); this.vel = createVector(random(-1, 1), random(-1, 1)); this.acc = createVector(0, 0); this.target = createVector(x, y); this.size = 2; this.maxSpeed = 2; this.maxForce = 0.1; this.attractRadius = 50; this.attractForce = 0.1; this.color = color(255, 255, 255); } behaviors() { let arrive = this.arrive(this.target); this.applyForce(arrive); this.repel(); } repel() { let mouse = createVector(mouseX, mouseY); let distance = p5.Vector.dist(this.pos, mouse); if (distance < this.attractRadius) { let repelForce = p5.Vector.sub(this.pos, mouse).normalize().mult(this.attractForce); this.applyForce(repelForce); } } attract() { let mouse = createVector(mouseX, mouseY); let distance = p5.Vector.dist(this.pos, mouse); if (distance < this.attractRadius) { let attractForce = p5.Vector.sub(mouse, this.pos).normalize().mult(this.attractForce); this.applyForce(attractForce); } } applyForce(f) { this.acc.add(f); } arrive(target) { let desired = p5.Vector.sub(target, this.pos); let d = desired.mag(); let speed = this.maxSpeed; if (d < 100) { speed = map(d, 0, 100, 0, this.maxSpeed); } desired.setMag(speed); let steer = p5.Vector.sub(desired, this.vel); steer.limit(this.maxForce); return steer; } update() { this.pos.add(this.vel); this.vel.add(this.acc); this.acc.mult(0); } show() { // Set the fill color based on the velocity of the particle let vel = this.vel.mag(); if (vel < 0.5) { this.color = color(255, 0, 0); // red } else if (vel < 1) { this.color = color(255, 255, 0); // yellow } else { this.color = color(255, 255, 255); // white } fill(this.color); noStroke(); ellipse(this.pos.x, this.pos.y, this.size, this.size); } }
Problems
The primary issue I faced was to discover the font.textToPoints() function and its complex usage. The other difficult bits was to repel or attract the points and adjust the speed and colors of it!