Raya Tabassum: Generative Text Assignment

Concept:

This kinetic typography transforms static text into an interactive visual display. By treating each point of the font’s letters as a vehicle, the sketch brings the text “Dream” to life, allowing it to respond dynamically to the viewer’s mouse movements. Vehicles “arrive” at their designated spots to form the letters of the word and “flee” when the mouse comes close, creating an engaging effect that feels both chaotic and ordered. The addition of the gradient background adds depth and visual interest, making the typography a part of an aesthetically pleasing composition of a sunset.

Use your mouse to go through the word to interact with it:

Font Points Extraction and Vehicle Initialization:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//Extract points from the font
let points = font.textToPoints(textString, 75, 320, fontSize, {
sampleFactor: 0.1
});
//Initialize vehicles for each point
for (let i = 0; i < points.length; i++) {
let pt = points[i];
let vehicle = new Vehicle(pt.x, pt.y);
vehicles.push(vehicle);
}
//Extract points from the font let points = font.textToPoints(textString, 75, 320, fontSize, { sampleFactor: 0.1 }); //Initialize vehicles for each point for (let i = 0; i < points.length; i++) { let pt = points[i]; let vehicle = new Vehicle(pt.x, pt.y); vehicles.push(vehicle); }
//Extract points from the font
let points = font.textToPoints(textString, 75, 320, fontSize, {
  sampleFactor: 0.1
});

//Initialize vehicles for each point
for (let i = 0; i < points.length; i++) {
  let pt = points[i];
  let vehicle = new Vehicle(pt.x, pt.y);
  vehicles.push(vehicle);
}

Extracting points from text and converting them into “vehicles” was a bit complex due to the need to handle font rendering and point manipulation. The textToPoints() function is used to get the vector points for each letter, which are then used to create vehicle objects that simulate motion.

Also for the Vehicle class, implementing behaviors such as “arrive” and “flee” required understanding of steering behaviors and force accumulation in a physics-based simulation. Balancing these forces to achieve smooth and natural movement was challenging, especially when trying to simulate both attraction to a target point and repulsion from the mouse cursor.

Full code:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
//Preload the font
let font;
let vehicles = []; //Array to hold the 'vehicle' objects
function preload() {
//Load the font from the assets
font = loadFont('Hogfish DEMO.otf');
}
function setup() {
createCanvas(700, 500); //Set up the canvas
//Create a background gradient
setGradient(0, 0, width, height, color('#EBC249'), color('#A52D56'), Y_AXIS);
//Define the text properties
let textString = 'Dream';
let fontSize = 180;
//Convert the text to a series of points
let points = font.textToPoints(textString, 75, 330, fontSize, {
sampleFactor: 0.1 //Determines the density of the points
});
//Create a vehicle object for each point
for (let i = 0; i < points.length; i++) {
let pt = points[i];
let vehicle = new Vehicle(pt.x, pt.y);
vehicles.push(vehicle);
}
}
function draw() {
//Refresh the gradient background each frame
setGradient(0, 0, width, height, color('#EBC249'), color('#A52D56'), Y_AXIS);
//Update and display each vehicle
for (let i = 0; i < vehicles.length; i++) {
let v = vehicles[i];
v.behaviors();
v.update();
v.show();
}
}
//Constants for gradient direction
const Y_AXIS = 1;
const X_AXIS = 2;
//Function to create a gradient background
function setGradient(x, y, w, h, c1, c2, axis) {
noFill();
//Create a vertical gradient
if (axis === Y_AXIS) {
for (let i = y; i <= y + h; i++) {
let inter = map(i, y, y + h, 0, 1);
let c = lerpColor(c1, c2, inter);
stroke(c);
line(x, i, x + w, i);
}
}
//Create a horizontal gradient
else if (axis === X_AXIS) {
for (let i = x; i <= x + w; i++) {
let inter = map(i, x, x + w, 0, 1);
let c = lerpColor(c1, c2, inter);
stroke(c);
line(i, y, i, y + h);
}
}
}
//The Vehicle class
class Vehicle {
constructor(x, y) {
this.pos = createVector(random(width), random(height)); // Start position
this.target = createVector(x, y); //Target position
this.vel = p5.Vector.random2D(); //Initial velocity
this.acc = createVector(); //Acceleration
this.r = 8; //Radius
this.maxspeed = 10; //Maximum speed
this.maxforce = 1; //Maximum steering force
}
//Combine behaviors
behaviors() {
let arrive = this.arrive(this.target);
let mouse = createVector(mouseX, mouseY);
let flee = this.flee(mouse);
arrive.mult(1);
flee.mult(5);
this.applyForce(arrive);
this.applyForce(flee);
}
//Apply a force to the vehicle
applyForce(f) {
this.acc.add(f);
}
//Update the vehicle's position
update() {
this.pos.add(this.vel);
this.vel.add(this.acc);
this.acc.mult(0); //Reset acceleration each frame
}
//Display the vehicle
show() {
stroke(255);
strokeWeight(8);
point(this.pos.x, this.pos.y);
}
//Steer the vehicle towards a target
arrive(target) {
let desired = p5.Vector.sub(target, this.pos); //A vector pointing from the position to the target
let d = desired.mag();
let speed = this.maxspeed;
if (d < 100) {
//Adjust speed based on distance to the target
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;
}
//Make the vehicle flee from the mouse
flee(target) {
let desired = p5.Vector.sub(target, this.pos);
let d = desired.mag();
if (d < 50) {
desired.setMag(this.maxspeed);
desired.mult(-1); //Go in the opposite direction
let steer = p5.Vector.sub(desired, this.vel);
steer.limit(this.maxforce);
return steer;
} else {
return createVector(0, 0); //No force if the mouse is far away
}
}
}
//Preload the font let font; let vehicles = []; //Array to hold the 'vehicle' objects function preload() { //Load the font from the assets font = loadFont('Hogfish DEMO.otf'); } function setup() { createCanvas(700, 500); //Set up the canvas //Create a background gradient setGradient(0, 0, width, height, color('#EBC249'), color('#A52D56'), Y_AXIS); //Define the text properties let textString = 'Dream'; let fontSize = 180; //Convert the text to a series of points let points = font.textToPoints(textString, 75, 330, fontSize, { sampleFactor: 0.1 //Determines the density of the points }); //Create a vehicle object for each point for (let i = 0; i < points.length; i++) { let pt = points[i]; let vehicle = new Vehicle(pt.x, pt.y); vehicles.push(vehicle); } } function draw() { //Refresh the gradient background each frame setGradient(0, 0, width, height, color('#EBC249'), color('#A52D56'), Y_AXIS); //Update and display each vehicle for (let i = 0; i < vehicles.length; i++) { let v = vehicles[i]; v.behaviors(); v.update(); v.show(); } } //Constants for gradient direction const Y_AXIS = 1; const X_AXIS = 2; //Function to create a gradient background function setGradient(x, y, w, h, c1, c2, axis) { noFill(); //Create a vertical gradient if (axis === Y_AXIS) { for (let i = y; i <= y + h; i++) { let inter = map(i, y, y + h, 0, 1); let c = lerpColor(c1, c2, inter); stroke(c); line(x, i, x + w, i); } } //Create a horizontal gradient else if (axis === X_AXIS) { for (let i = x; i <= x + w; i++) { let inter = map(i, x, x + w, 0, 1); let c = lerpColor(c1, c2, inter); stroke(c); line(i, y, i, y + h); } } } //The Vehicle class class Vehicle { constructor(x, y) { this.pos = createVector(random(width), random(height)); // Start position this.target = createVector(x, y); //Target position this.vel = p5.Vector.random2D(); //Initial velocity this.acc = createVector(); //Acceleration this.r = 8; //Radius this.maxspeed = 10; //Maximum speed this.maxforce = 1; //Maximum steering force } //Combine behaviors behaviors() { let arrive = this.arrive(this.target); let mouse = createVector(mouseX, mouseY); let flee = this.flee(mouse); arrive.mult(1); flee.mult(5); this.applyForce(arrive); this.applyForce(flee); } //Apply a force to the vehicle applyForce(f) { this.acc.add(f); } //Update the vehicle's position update() { this.pos.add(this.vel); this.vel.add(this.acc); this.acc.mult(0); //Reset acceleration each frame } //Display the vehicle show() { stroke(255); strokeWeight(8); point(this.pos.x, this.pos.y); } //Steer the vehicle towards a target arrive(target) { let desired = p5.Vector.sub(target, this.pos); //A vector pointing from the position to the target let d = desired.mag(); let speed = this.maxspeed; if (d < 100) { //Adjust speed based on distance to the target 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; } //Make the vehicle flee from the mouse flee(target) { let desired = p5.Vector.sub(target, this.pos); let d = desired.mag(); if (d < 50) { desired.setMag(this.maxspeed); desired.mult(-1); //Go in the opposite direction let steer = p5.Vector.sub(desired, this.vel); steer.limit(this.maxforce); return steer; } else { return createVector(0, 0); //No force if the mouse is far away } } }
//Preload the font
let font;
let vehicles = []; //Array to hold the 'vehicle' objects

function preload() {
  //Load the font from the assets
  font = loadFont('Hogfish DEMO.otf'); 
}

function setup() {
  createCanvas(700, 500); //Set up the canvas
  //Create a background gradient
  setGradient(0, 0, width, height, color('#EBC249'), color('#A52D56'), Y_AXIS);

  //Define the text properties
  let textString = 'Dream';
  let fontSize = 180;
  //Convert the text to a series of points
  let points = font.textToPoints(textString, 75, 330, fontSize, {
    sampleFactor: 0.1 //Determines the density of the points
  });

  //Create a vehicle object for each point
  for (let i = 0; i < points.length; i++) {
    let pt = points[i];
    let vehicle = new Vehicle(pt.x, pt.y);
    vehicles.push(vehicle);
  }
}

function draw() {
  //Refresh the gradient background each frame
  setGradient(0, 0, width, height, color('#EBC249'), color('#A52D56'), Y_AXIS);

  //Update and display each vehicle
  for (let i = 0; i < vehicles.length; i++) {
    let v = vehicles[i];
    v.behaviors();
    v.update();
    v.show();
  }
}

//Constants for gradient direction
const Y_AXIS = 1;
const X_AXIS = 2;

//Function to create a gradient background
function setGradient(x, y, w, h, c1, c2, axis) {
  noFill();

  //Create a vertical gradient
  if (axis === Y_AXIS) {
    for (let i = y; i <= y + h; i++) {
      let inter = map(i, y, y + h, 0, 1);
      let c = lerpColor(c1, c2, inter);
      stroke(c);
      line(x, i, x + w, i);
    }
  } 
  //Create a horizontal gradient
  else if (axis === X_AXIS) {
    for (let i = x; i <= x + w; i++) {
      let inter = map(i, x, x + w, 0, 1);
      let c = lerpColor(c1, c2, inter);
      stroke(c);
      line(i, y, i, y + h);
    }
  }
}

//The Vehicle class
class Vehicle {
  constructor(x, y) {
    this.pos = createVector(random(width), random(height)); // Start position
    this.target = createVector(x, y); //Target position
    this.vel = p5.Vector.random2D(); //Initial velocity
    this.acc = createVector(); //Acceleration
    this.r = 8; //Radius
    this.maxspeed = 10; //Maximum speed
    this.maxforce = 1; //Maximum steering force
  }

  //Combine behaviors
  behaviors() {
    let arrive = this.arrive(this.target);
    let mouse = createVector(mouseX, mouseY);
    let flee = this.flee(mouse);

    arrive.mult(1);
    flee.mult(5);

    this.applyForce(arrive);
    this.applyForce(flee);
  }

  //Apply a force to the vehicle
  applyForce(f) {
    this.acc.add(f);
  }

  //Update the vehicle's position
  update() {
    this.pos.add(this.vel);
    this.vel.add(this.acc);
    this.acc.mult(0); //Reset acceleration each frame
  }

  //Display the vehicle
  show() {
    stroke(255);
    strokeWeight(8);
    point(this.pos.x, this.pos.y);
  }

  //Steer the vehicle towards a target
  arrive(target) {
    let desired = p5.Vector.sub(target, this.pos); //A vector pointing from the position to the target
    let d = desired.mag();
    let speed = this.maxspeed;
    if (d < 100) {
      //Adjust speed based on distance to the target
      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;
  }

  //Make the vehicle flee from the mouse
  flee(target) {
    let desired = p5.Vector.sub(target, this.pos);
    let d = desired.mag();
    if (d < 50) {
      desired.setMag(this.maxspeed);
      desired.mult(-1); //Go in the opposite direction
      let steer = p5.Vector.sub(desired, this.vel);
      steer.limit(this.maxforce);
      return steer;
    } else {
      return createVector(0, 0); //No force if the mouse is far away
    }
  }
}

 

Leave a Reply