Assignment 4: Generative Text Output

Concept

The concept I aimed to replicate the captivating streams of 1s and 0s that are frequently shown in movies or GIFs, which represent the fundamentals of digital computing and communication. I wanted to achieve something similar to seeing a complex dance of binary digits, therefore I represented these streams with random characters.

Inspiration 

Sketch


Code

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
function draw() {
background(0);
// Display and animate characters
for (let x = 0; x < cols; x++) {
for (let y = 0; y < rows; y++) {
let yOffset = (millis() * speed + x * 50 + y * 50) % (height + 200) - 100;
if (grid[x][y].bright) {
// Set bright neon blue color for highlighted characters
fill(0, 255, 255);
} else {
// Set light neon blue color for other characters
fill(0, 150, 255);
}
text(grid[x][y].char, x * charSize, y * charSize + yOffset);
}
}
}
function draw() { background(0); // Display and animate characters for (let x = 0; x < cols; x++) { for (let y = 0; y < rows; y++) { let yOffset = (millis() * speed + x * 50 + y * 50) % (height + 200) - 100; if (grid[x][y].bright) { // Set bright neon blue color for highlighted characters fill(0, 255, 255); } else { // Set light neon blue color for other characters fill(0, 150, 255); } text(grid[x][y].char, x * charSize, y * charSize + yOffset); } } }
function draw() {
  background(0); 
  
  // Display and animate characters
  for (let x = 0; x < cols; x++) {
    for (let y = 0; y < rows; y++) {
      let yOffset = (millis() * speed + x * 50 + y * 50) % (height + 200) - 100;
      
      if (grid[x][y].bright) {
        // Set bright neon blue color for highlighted characters
        fill(0, 255, 255); 
      } else {
        // Set light neon blue color for other characters
        fill(0, 150, 255); 
      }
      
      text(grid[x][y].char, x * charSize, y * charSize + yOffset);
    }
  }
}

In the draw() method, I have a nested loop that iterates over each cell of the 2D grid array. The location of the characters are calculated and its appearance based on its coordinates and a time-based offset (yOffset). This offset is computed given the cell coordinates, a predetermined speed value, and the current value of millis(), which indicates the milliseconds since the sketch began operating.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if (grid[x][y].bright) {
// Set bright neon blue color for highlighted characters
fill(0, 255, 255);
} else {
// Set light neon blue color for other characters
fill(0, 150, 255);
}
if (grid[x][y].bright) { // Set bright neon blue color for highlighted characters fill(0, 255, 255); } else { // Set light neon blue color for other characters fill(0, 150, 255); }
if (grid[x][y].bright) {
        // Set bright neon blue color for highlighted characters
        fill(0, 255, 255); 
      } else {
        // Set light neon blue color for other characters
        fill(0, 150, 255); 
      }

Each character’s color is chosen according to the entry that corresponds to it in the grid array. fill() method applies a bright neon blue color to a cell if its bright attribute is set to true. Otherwise, ordinary characters are shown in a lighter neon blue hue.

Full Code

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 2D array to display the characters
let grid;
// the font size of the characters
let charSize = 20;
// columns and rows for the 2D array (grid)
let cols, rows;
// speed of the characters falling
let speed = 0.2;
function setup() {
print(windowWidth,windowHeight)
createCanvas(windowWidth, windowHeight);
//creating the 2D array
cols = floor(width / charSize);
rows = floor(height / charSize);
grid = create2DArray(cols, rows);
// initializing the characters font size
textSize(charSize);
// Initialize grid with random characters
for (let x = 0; x < cols; x++) {
for (let y = 0; y < rows; y++) {
grid[x][y] = {
// calling the characters randomly
char: randomChar(),
// Randomly determine if the character should be brighter or not
bright: random(1) > 0.8
};
}
}
}
function draw() {
background(0);
// Display and animate characters
for (let x = 0; x < cols; x++) {
for (let y = 0; y < rows; y++) {
let yOffset = (millis() * speed + x * 50 + y * 50) % (height + 200) - 100;
if (grid[x][y].bright) {
// Set bright neon blue color for highlighted characters
fill(0, 255, 255);
} else {
// Set light neon blue color for other characters
fill(0, 150, 255);
}
text(grid[x][y].char, x * charSize, y * charSize + yOffset);
}
}
}
function windowResized() {
resizeCanvas(windowWidth, windowHeight);
cols = floor(width / charSize);
rows = floor(height / charSize);
grid = create2DArray(cols, rows);
// Reinitialize grid with random characters
for (let x = 0; x < cols; x++) {
for (let y = 0; y < rows; y++) {
grid[x][y] = {
char: randomChar(),
// Randomly determine if the character should be brighter or not
bright: random(1) > 0.8
};
}
}
}
// function to create the 2D array grid
function create2DArray(cols, rows) {
let arr = new Array(cols);
for (let i = 0; i < arr.length; i++) {
arr[i] = new Array(rows);
}
return arr;
}
// function to generate a random character
function randomChar() {
return String.fromCharCode(floor(random(65, 91)));
}
// 2D array to display the characters let grid; // the font size of the characters let charSize = 20; // columns and rows for the 2D array (grid) let cols, rows; // speed of the characters falling let speed = 0.2; function setup() { print(windowWidth,windowHeight) createCanvas(windowWidth, windowHeight); //creating the 2D array cols = floor(width / charSize); rows = floor(height / charSize); grid = create2DArray(cols, rows); // initializing the characters font size textSize(charSize); // Initialize grid with random characters for (let x = 0; x < cols; x++) { for (let y = 0; y < rows; y++) { grid[x][y] = { // calling the characters randomly char: randomChar(), // Randomly determine if the character should be brighter or not bright: random(1) > 0.8 }; } } } function draw() { background(0); // Display and animate characters for (let x = 0; x < cols; x++) { for (let y = 0; y < rows; y++) { let yOffset = (millis() * speed + x * 50 + y * 50) % (height + 200) - 100; if (grid[x][y].bright) { // Set bright neon blue color for highlighted characters fill(0, 255, 255); } else { // Set light neon blue color for other characters fill(0, 150, 255); } text(grid[x][y].char, x * charSize, y * charSize + yOffset); } } } function windowResized() { resizeCanvas(windowWidth, windowHeight); cols = floor(width / charSize); rows = floor(height / charSize); grid = create2DArray(cols, rows); // Reinitialize grid with random characters for (let x = 0; x < cols; x++) { for (let y = 0; y < rows; y++) { grid[x][y] = { char: randomChar(), // Randomly determine if the character should be brighter or not bright: random(1) > 0.8 }; } } } // function to create the 2D array grid function create2DArray(cols, rows) { let arr = new Array(cols); for (let i = 0; i < arr.length; i++) { arr[i] = new Array(rows); } return arr; } // function to generate a random character function randomChar() { return String.fromCharCode(floor(random(65, 91))); }
// 2D array to display the characters
let grid;
// the font size of the characters
let charSize = 20;
// columns and rows for the 2D array (grid)
let cols, rows;
// speed of the characters falling
let speed = 0.2;

function setup() {
  print(windowWidth,windowHeight)
  createCanvas(windowWidth, windowHeight);
  
  //creating the 2D array
  cols = floor(width / charSize);
  rows = floor(height / charSize);
  
  grid = create2DArray(cols, rows);
  //  initializing the characters font size 
  textSize(charSize);
  
  // Initialize grid with random characters
  for (let x = 0; x < cols; x++) {
    for (let y = 0; y < rows; y++) {
      grid[x][y] = {
        // calling the characters randomly      
        char: randomChar(),
        // Randomly determine if the character should be brighter or not
        bright: random(1) > 0.8 
      };
    }
  }
}

function draw() {
  background(0); 
  
  // Display and animate characters
  for (let x = 0; x < cols; x++) {
    for (let y = 0; y < rows; y++) {
      let yOffset = (millis() * speed + x * 50 + y * 50) % (height + 200) - 100;
      
      if (grid[x][y].bright) {
        // Set bright neon blue color for highlighted characters
        fill(0, 255, 255); 
      } else {
        // Set light neon blue color for other characters
        fill(0, 150, 255); 
      }
      
      text(grid[x][y].char, x * charSize, y * charSize + yOffset);
    }
  }
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
  cols = floor(width / charSize);
  rows = floor(height / charSize);
  
  grid = create2DArray(cols, rows);
  
  // Reinitialize grid with random characters
  for (let x = 0; x < cols; x++) {
    for (let y = 0; y < rows; y++) {
      grid[x][y] = {
        char: randomChar(),
        // Randomly determine if the character should be brighter or not
        bright: random(1) > 0.8 
      };
    }
  }
}

// function to create the 2D array grid
function create2DArray(cols, rows) {
  let arr = new Array(cols);
  for (let i = 0; i < arr.length; i++) {
    arr[i] = new Array(rows);
  }
  return arr;
}

// function to generate a random character
function randomChar() {
  return String.fromCharCode(floor(random(65, 91)));
}

 

Challenges

The significant challenge was how to keep the characters’ animation in a fluid and synced motion along with the shifting grid placements while maintaining readability and visual consistency.

Another challenge was assigning different brightness levels to different characters. This required careful coordination to make sure the highlighted characters shone out without overshadowing other characters or creating visual clutter.

Improvements

There is one improvement that I would like to implement in the future. I would want to improve the animation algorithm’s efficiency that may result in more fluid and flawless visual transitions, particularly when working with bigger grids or faster animation rates.

Another improvement could be the inclusion of user interactivity. The user could disrupt the falling characters using mouse hover and the characters trying to get back into the original stream.

Leave a Reply