BEE_TO text manipulation

I know it is a bad pun but I couldn’t help noticing it (bee in beeto).

I really liked the examples we dealt with in class, and for my assignment I decided to try to mix some of the different functions in these examples in addition to others to have a unique product.

So I made use of the geomerative with circle class file, the bounce logic, the drawing of a hexagonal polygon, and the logic of drawing a grid.

I decided that my theme would be that of bees and that the idea of having things vibrating in place fits it well. I looked up the color palette of a beehive, and I made the text particles bounce off the borders if they hit them. This was how it looked at first.

Then I decided to increase the speed so it fits the theme more, increased the size proportionally, added the hexagon grid classes, and adjusted the friction, initial speed, and the numericals involved with bringing the hexagons back home.

This is how the final things looks like where the background randomly changes color just as it would be in real life.

https://youtu.be/17Bj16mcsKQ

The main code drawing on everything:

import geomerative.*;
RFont font;
RPoint[] pnts;
Hexagon[] hexas;
int amountPerPoint;
int index;
HexGrid g;
color[] mainpallet = {  #985b10, #6b4701};
int rad, nwide, nhigh, shade;

void setup() {
  size(1000, 640);
  
  RG.init(this);

  font = new RFont("Raleway-Regular.ttf", 280, RFont.CENTER);
  pnts = getPoints("Bee_to");
  amountPerPoint = 4;
  
  rad=20;
  nhigh = (height/((rad*3)/2));
  nwide = int(width/(sqrt(3)*rad))+1;
  
  g = new HexGrid(nwide, nhigh, rad);
  g.display();
  
  hexas = new Hexagon[pnts.length*amountPerPoint];
  
  index = 0;
  
  for (int i = 0; i < pnts.length*amountPerPoint; i += amountPerPoint) {
    for (int j = 0; j < amountPerPoint; j++) {
      int k = i + j;
      hexas[k] = new Hexagon(width/2 + pnts[index].x + random(-2, 2), height/1.65 + pnts[index].y + random(-2, 2), random(8, 18));
    }
    index++;
  }
  
  
   
}

void draw() {
   background(107,71,1);
   
   shade = int(random(0,1));
   g.display();
   
   for (int i =0; i < hexas.length; i++) {
     hexas[i].seekHome();
     hexas[i].update();
     hexas[i].display(6);
     hexas[i].checkEdges();
   }
   
   for(int i=0; i < 5 ; i++)
  {
    Hbackground selected = g.getHex(int(random(nwide)), int(random(nhigh)));
    selected.setFillColour(mainpallet[int(random(2))]);
  }
}

void mousePressed() {
  for (int i = 0; i < hexas.length; i++){
    hexas[i].xSpeed = random(-30, 30);
    hexas[i].ySpeed = random(-30, 30);
    hexas[i].seek = false;
  }
  //delay(200);
}

void mouseReleased(){
  for (int i = 0; i < hexas.length; i++) {
    hexas[i].seek = true;
  }
  //delay(200);
}

RPoint[] getPoints(String str) {
  RCommand.setSegmentLength (20);
  RCommand.setSegmentator(RCommand.UNIFORMLENGTH);
  RGroup grp;

  grp = font.toGroup(str);
  grp = grp.toPolygonGroup();
  return grp.getPoints();
}

Individual hexagons in background:

//this code was inspired from this website http://louisc.co.uk/?p=2554

class Hbackground {
 float centx;
 float centy;
 float radius;
 float angle = TWO_PI / 6;
 boolean fill = false;
 color c;
 
 Hbackground( float x, float y, float r ){
 centx = x;
 centy = y;
 radius = r;
 }
 
//The draw function will define the fill values and calculate the coordinates
 void display() {
   if(fill)
     fill(c);
   else
    noFill();
   
  
   beginShape();
     for (float a = PI/6; a < TWO_PI; a += angle) {
       float sx = centx + cos(a) * radius;
       float sy = centy + sin(a) * radius;
       vertex(sx, sy);
     }
     
     stroke(137,104,0);
     strokeWeight(4);
   endShape(CLOSE);
 }
 
 void setFillColour(color col)
 {
 fill = true;
 c = col;
 }
}

Grid of hexagons in background:

//this code was inspired from this website http://louisc.co.uk/?p=2554

class HexGrid {
  Hbackground[][] grid; //Our 2D storage array of Hexagon Objects
  int cols, rows;
  float radius;
 
  //Class Constructor required the grid size and cell radius
  HexGrid(int nocol, int norow, int rad)
  {
    //Define our grid parameters
    cols = nocol;
    rows = norow;
    radius=float(rad);
 
    //2D Matrix of Hexagon Objects
    grid=new Hbackground[cols][rows];
 
    //Lets assign the inital x,y coordinates outside the loop
    int x = int(sqrt(3)*radius);
    int y = int(radius);
 
    //These two nested for loops will cycle all the columns in each row
    //and calculate the coordinates for the hexagon cells, generating the
    //class object and storing it in the 2D array.
    for( int i=0; i < rows ; i++ ){
      for( int j=0; j < cols; j++)
      {
        grid[j][i] = new Hbackground(x, y, radius);
        x+=radius*sqrt(3); //Calculate the x offset for the next column
      }
      y+=(radius*3)/2; //Calculate the y offset for the next row
      if((i+1)%2==0)
        x=int(sqrt(3)*radius);
      else
        x=int(radius*sqrt(3)/2);
    }
  }
 
  //This function will redraw the entire table by calling the draw on each
  //hexagonal cell object
  void display()
  {
    for( int i=0; i < rows ; i++ ){
      for( int j=0; j < cols; j++)
      {
        grid[j][i].display();
      }
    }
  }
 
  //This function will return the hexagonal cell object given its column and row
  Hbackground getHex(int col, int row)
  {
    return grid[col][row];
  }
 
}

Individual hexagons making the text:

class Hexagon {
  float x, y, homeX, homeY;
  float xSpeed, ySpeed;
  float hWidth;
  boolean seek;
  char letter;
  float dirX, dirY;

  Hexagon(float _x, float _y, float _width ) {
    homeX = x = _x;
    homeY = y = _y;
    xSpeed = ySpeed = 0;
    hWidth = _width;
    seek = true;
  }

  void update() {
    x += xSpeed;
    y += ySpeed;
    xSpeed *= .95;
    ySpeed *= .95;
  }

  void display(int npoints) {
    float angle = TWO_PI / npoints;
    beginShape();
      fill(246,224,0);
      stroke(249,201,1);
      for (float a = PI/6; a < TWO_PI; a += angle) {
        float sx = x + cos(a) * hWidth;
        float sy = y + sin(a) * hWidth;
        vertex(sx, sy);
      }
      strokeWeight(2);
    endShape(CLOSE);
  }

  void seekHome() {
    if (seek) {
      dirX = homeX-x;
      dirY = homeY-y;
      dirX*=.009;
      dirY*=.009;
      xSpeed+=dirX;
      ySpeed+=dirY;
    }
  }

  void checkEdges() {
    if (y>height - hWidth) {
      ySpeed *= -1;
    }
    if (y< hWidth) {
      ySpeed *= -1;
    }
    if (x>width - hWidth) {
      xSpeed *= -1;
    }
    if (x< hWidth) {
      xSpeed *= -1;
    }
  }
}

 

Week 4 Assignment: Generative Text Output

For this week’s assignment, I was not able to really come up with my very own original creative idea, so I had to search online for some  examples online that had to do with some Generative Text Output. Firstly, when I was fumbling through countless Youtube videos with examples, I stumbled on this video where it showed how by repeating a bunch of short sentences and making them appear at different places on the screen really quick could create this kind of blurry image on the screen, just like how when our TV screen would act weird and these white and black bars would flicker on and off.

After I created this blurry image on the screen, I wanted to make a Typewriter effect for my text where my text would appear one by one, but I wasn’t sure how to incorporate that effect to the entire text (maybe because I had to create an array to make this effect for each character of my text?). So, after this wasn’t working, I wanted to make another effect and I thought I could use the mousePressed function to make it freeze or stop creating this blurry image when the mouse is pressed and at the same time create another text, but that did not work as well. So, I settled for making it change color each time the mouse was pressed.

String text1="Hello, my name is Ryan.";
String text2="Hi, I've stopped.";
PFont font;
int counter;
float i, x, y;

void setup() {
  size(800, 600, P2D);
  frameRate(5);
  smooth();
  font=createFont("Georgia", 30);
  textFont(font, 20);
  fill(0);
  counter=0;
}

void draw() {    
  background(255);
  translate(mouseX, mouseY);
  //typewriteText()
  for (i=0; i < 1000; i++) {
    float x = random(width);
    float y = random(height);
    text(text1, x, y);

    if ( mousePressed) {
      noLoop();
      fill(random(255), random(255), random(255));
      for (int i = 0; i < random(1000); i++) {
        textFont(font, random(50));
        x = random(width);
        y = random(height);
        text(text2, x, y);
      }
    } else {
      loop();
      background(255);
      for (i=0; i < 1000; i++) {
        x = random(width);
        y = random(height);
        text(text1, x, y);
      }
    }
  }
}

 

Displaying Text

For this assignment, I chose to display the text in the Processing window.

My initial idea was to create a string of letters that would appear in the window and move in some interesting way. After watching some YouTube tutorials and browsing the Processing forum, my first attempt to create the letter-objects that would appear in a typewriter effect, move around some arbitrary curve and then “find home” miserably failed (I am still not too sure why, but my best-educated guess is because I had a hard time with passing polar coordinates and translating them to regular coordinates).

From the second try, my goal was to create a string of letters that would be placed around the circle and would move around it if the mouse is pressed. To add some fun to it, I decided to place another string inside the circle, and make it change the size in a noise-like pattern, also when the mouse is pressed. This appeared to be more realistic and feasible with my skills, so I just went for implementing this with my code.

The most challenging part appeared to be the math: finding the arclength, placing each letter and making sure the spacing is right, and doing the whole polar coordinates thing.

Here’s the code:

String myText = "hello, I am...";
String anotherText = "Movement!";
PFont font;
float radius = 100;
float x, arclength, angle, move, t;

void setup(){
  size (340, 680);
  font = createFont("Calm", 64);
  textFont(font);
  textAlign(CENTER);
  smooth();
}

void draw(){
  
  background(0);
  
  x = 10;
  arclength = 0;
  
  circles();
  
  // Place the bigger circle
  translate(width/2, height/2);
  noStroke();
  ellipse(0, 0, radius*2, radius*2);
  
  push();
    fill(0);
    textSize(50+t);
    text(anotherText, 0, x);
  pop();
  
  for(int i=0; i<myText.length(); i++){
    
     // Place the next letter
    arclength += textWidth(myText.charAt(i))/2;
    angle = 5*PI/4 + arclength/radius + move;
    
    push();
      translate(radius*cos(angle), radius*sin(angle));
      rotate(angle+PI/2);
      text(myText.charAt(i), 0, 0);
    pop();
    
    // Place the next letter
    arclength += textWidth(myText.charAt(i))/2;
  
  // Move the string if the mouse is pressed
    if (mousePressed){
      move += 0.0082;
      t += random(-0.5,0.5);
    }
  }

}

// Make a background of color-changing circles
void circles(){
  for (int i = 0; i < 50; i++) {
    push();
      fill(random(200,250), random(200,250), random(200,250));
      ellipse(random(width), random(height), radius/10, radius/10);
    pop();  
  }
}

And the demo:

Week 4: Generative Text

 

This was a disaster to figure out, but it was worth it at the end. (I had a very long victory dance).

My initial idea is that i wanted something on an animated text, with a ball moving around. I drew a sketch on procreate to illustrate:

 

My first of many hurdles was getting a font of mine to work. I kept getting errors, (and sometimes processing would display the text different than i expected).  Next, I created two of the text, and placed them away from each other to mirror the illustration I had in mind. After trying and trying to figure out how to get the ball to slide like I did in my illustration, I decided to try something else. I used the example shown (The Bubble One) in class to create circles in each point,  and wanted to print them out one by one so that the text could be drawn. After spending a full day on this (no really, a full day), I found my mistake -I had accidentally called noLoop();.

After that, it was pretty smooth. I figured out my speed, how I wanted it to look, as well as how to toggle the colour to make it fade from black to red back and forth.

import geomerative.*;
import java.util.concurrent.TimeUnit;
RFont font; 
RPoint[] pnts;
float xValue = 0;
float yValue = 0;
int a = 175;
int i = 0;
int previousTime = 0;
float timePassed = 0.1;
int r = 255;
boolean b = true;

void setup(){
  frameRate(120);
  background(255);
  size (500, 500);
  RG.init(this);
  // set the font, the size, and left, center, or right adjusted
  font = new RFont("LeckerliOne-Regular.ttf", 150, RFont.CENTER);
  
  // get the points along a String
  pnts = getPoints("Media");
  System.out.println(pnts);
    
  noFill();
  //noLoop();
  stroke(0,100);
  
}
void update () {
  //stroke( 0, 0, 0, a);
  noStroke();
  fill( r, 0, 0);
  circle(xValue, yValue, 6);
}

void draw() {
  int time = -1;
  pushMatrix();
  translate(width/2, height/1.5);
  if ( millis() > previousTime + timePassed){
     previousTime= millis();
     //println("it works");
    if ( i <pnts.length ){
        update();
        if ( r >= 0 && b == true){
          r -= 1; 
          b = true; 
        }
        else if (r == 225 && b == false){
          r -= 1; 
          b = true; 
        }
        else {
          r +=1;
          b = false; 
        }
        //float diam = random(5,15);
        xValue =  pnts[i].x;
        yValue = pnts[i].y;
        i++;
        //System.out.println("This is Xvalue:" + xValue);
        //System.out.println("This is yvalue:" + yValue);
      }
     }
  popMatrix();
}



// function that returns an array of RPoints based on a string
RPoint[] getPoints(String str) {
  // change this number to change the resolution of points outlining the circle
  RCommand.setSegmentLength(1);
  RCommand.setSegmentator(RCommand.UNIFORMLENGTH);
  RGroup grp;
  grp = font.toGroup(str);
  grp = grp.toPolygonGroup();
  return grp.getPoints();
}

void mousePressed(){
  xValue-=1;
  update();
  
}

 

 

Transforming text – Geomerative

General Information

As I was working on this, I realized that I haven’t understood the Geomerative library as much as I thought I did, as I struggled a lot while using it.
Therefore, I wanted to make this week’s assignment, an opportunity for me to get a better grasp of most things that have to do with Geomerative and implement something quite basic.

I got the idea to make a program that displays words from a string one at a time, with a transition transforming each word into the one following it. (When we reach the final word of the string, it starts again from the first word.)
It turns out that this has been done a lot before, and to be honest, since I was still trying to learn about the Geomerative library, I ended up needing a lot of help and inspiration from the pre-existing codes I found online.
(PS: I didn’t copy any code. I used what I found to understand some of the main concepts of the program, but I made sure to code everything myself.)

The process

The first thing I did was use the geomerative_basic example, that Professor has provided us with, as my base. (It’s on GitHub if anyone was wondering.)
This program displays one string using ellipses.
In order to make it more suitable for what I wanted to create, I made a bunch of changes:

      • I turned everything into arrays (or array of arrays) so that it can be used on multiple strings instead of one.
      • Instead of using RGroup, I used RShape. This is because I needed access to each point individually so I needed to use getPoint() instead of getPoints(), which doesn’t work on RGroup.
      • Instead of drawing ellipses, I drew points. I made the number of points quite big so that it appears as a line which makes the transition effect look a bit cooler.
      • I added another array of arrays of RPoint called “changing_pnts” such that for every word, there are multiple elements:  changing_pnts[…], each containing the positions of all the points making up that word but at a different stage of the transition.
      • I added a function that populates changing_pnts. It has a role in changing each word into the next one and the last word back into the first one.

This is the code in the tab containing the function:

float temp1,temp2;

void populate_changing_pnts()
{
  //for each word
  for (int i=0; i<myStringArr.length; i++) 
  {
      //for the number of positions taken during the transition
      for (int j=0; j<num; j++) 
      {
          //for the number of points in this word (word of index i)
          for (int k=0; k<pnts[i].length; k++) 
          {
              //if we're at the last word, make the transition back to the first word
              if (i == myStringArr.length -1){
                temp1 = lerp( pnts[i][k].x, pnts[0][k].x, j*(1.0/num));
                temp2 = lerp( pnts[i][k].y, pnts[0][k].y, j*(1.0/num));
                changing_pnts[index][k] = new RPoint(temp1, temp2);
              }
              //if we're not at the last word, make the transition to the next word
              else {
                temp1 = lerp( pnts[i][k].x, pnts[i+1][k].x, j*(1.0/num));
                temp2 = lerp( pnts[i][k].y, pnts[i+1][k].y, j*(1.0/num));
                changing_pnts[index][k] = new RPoint(temp1, temp2);
              }  
          }
          index += 1; /*this is here because when the counter j goes back to 0, we want index to keep 
                      incrementing to reach the size of changing_pnts*/
      }
  }
  index = 0; //setting back index to 0
}

 

And this is the code in the main tab:

import geomerative.*;

RFont font;
int diameter = 15;
int pointNum = 2500; //this how many points we want the words to be made up of

String myString = "this wasn't as easy as it seemed in my head"; 
String[] myStringArr; //this is a string of strings that will contain all words from myString 
RPoint[][] pnts; //an array of arrays of points. For each word i, pnts[i] contains all points that form that word

RShape[] words; //an array of groups
float xOffset[]; //an array of xOffsets

int num = 60; //This is the number of positions that each point will go through while it's transitioning
              //This means it will move through 60 positions to get from its start to its destination

RPoint[][] changing_pnts; //an array of arrays of points.
                          //its size will be num * the size of the array of arrays pnts.
                          /*because for each word, there exist many elements changing_pnts[] 
                          each containing the positions of the points at a different stage of the transition*/

int index = 0; //this variable will be the one used to iterate through changing_pnts without a for loop


void setup() {
  size(640, 640);
  stroke(0);
  strokeWeight(4);
  
  RG.init(this);
  font = new RFont("Franklin Goth Ext Condensed.ttf", 200, RFont.CENTER);
  
  myStringArr = split(myString, ' ');
  
  //initializing all of the arrays according to the size of myStringArr
  pnts = new RPoint[myStringArr.length][pointNum];
  words = new RShape[myStringArr.length];
  xOffset = new float[myStringArr.length];
  changing_pnts = new RPoint[(myStringArr.length)*num][pointNum]; //size of this is = nums * size of pnts

  
  // load all strings from the myStringArr into geomerative
  for(int i=0; i<myStringArr.length; i++){
    words[i] = font.toShape(myStringArr[i]);
    //create the same number of points for each word
    for (int j=0; j<pointNum; j++){
      pnts[i][j]= words[i].getPoint(j*(1.0/pointNum));
    }

     //to set each word in the middle of the screen
     //get the size of the string from myStringArr susbtracted from the width of the screen
     //this is the amount left over
    xOffset[i] = width - words[i].getBottomRight().x - words[i].getBottomLeft().x;
    // divide that by two to center it
    xOffset[i] /= 2;
  }
  
  //this function fills changing_pnts with all the required points
  populate_changing_pnts(); 
}

void draw() {
  background(255);
  for (int j = 0; j< pointNum; j++) {
    float x = changing_pnts[index][j].x + xOffset[0];
    float y = changing_pnts[index][j].y + height/2;
    point(x, y);
  }
  index+= 1;
  if (index == (myStringArr.length)*num){
    index=0;
  }
  
}

final outcome

angry w no rights- Meera

 

PFont f;
// int for the gradient (r,g,b).
int r = 0;
int g = 0;
int b= 0;
String feels;
int x;
float t = 400;
void setup(){
  size(800,800);
 //i went to the tools craeted a font and saved it and just wrote the name in loadFont.
  f =loadFont("Herculanum-60.vlw");
  textFont(f);
feels = "angry w no right";
x = width;

}

 
 void draw(){
  
   //Gradient background
   for (int i = 0; i<width; i++){
     stroke(i,i,i);
     line(0,i,width,i);
   }
  // text i chose to write, had to fill the text to be able to see it; couldnt find it intially.
 fill(0);
// what makes my sentence move back and forth is the wave and the random is making it go up and down 
float wave = sin (radians(frameCount));
 
 text(feels,90+wave*200,height/2+random(-100,100));

 }

 

Epileptic spiral

int y;
int size; 
int hundred;
float end;
void setup() {

  size(640, 400);
  background(255);

};
void draw() {

  noFill();
  stroke(0);
  
  //ellipse(width/2-25,height/2,50,50);
hundred = 100; 
  for (int i=0; i<width; i+=100) {
    strokeWeight(20);
    
    arc(320, 200, hundred+i, hundred+i, radians(180), radians(360) );
    arc(320-25, 200, hundred*1.5+i, hundred*1.5+i, radians(0), radians(180) );
     //interesting effect here
     filter(INVERT);
     
    ;
  };
  
  
};
void keyPressed() {
  fill(#FFE200);
  textSize(random(20,200));
  text(key,random(300),random(100,400));
  print(key);
};


Cardio Time

For this week’s assignment I decided to use that was being collected by the running app that I am using to track my running progress. The app records the distance per run, walking pace, running pace and the average pace.

For this assignment I took the average pace per run [given in minutes/km] and point plotted it against the days.

The data was between 0 and 9 so I have to get that data in the range such that I could plot it on the screen. For this I used the following formula
data*(maxDrawableHeight)/9.

This gave me the height of the points from the axis but since the drawing points are given from top left corner going down I inverted this by subtracting this from the drawable height.

 

Table data;
float[] numericData;
float [] plotData;
int numCols;
int axisOffset = 100;
void setup() {
  size(1000, 500);
  loadData();
  dataTransformation();
  drawAxes();
  drawGrid();
  printLabels();
  plotPoints();
  noLoop();
}

void draw() {
}

void drawAxes() {
  axisOffset = 50;
  pushStyle();
  strokeWeight(2);
  //y axis
  line(axisOffset, 0, axisOffset, height-axisOffset);
  //x-axis
  line(0+axisOffset, height-axisOffset, width, height-axisOffset);
  popStyle();
}

void loadData() {
  data = loadTable("data.csv");
  TableRow row = data.getRow(0);
  numCols = row.getColumnCount();
  numericData = new float[numCols];
  for (int i=0; i<numCols; i++) {
    numericData[i] = Float.parseFloat(row.getString(i));
  }
  //println();
}

void printData() {
  for (int i=0; i<numericData.length; i++)
  {
    print(numericData[i] + " | ");
  }
  println();
}

void drawGrid()
{
  // data will be in the range of 0 < 9*(height-axisOffset)
  pushStyle();
  stroke(0,0,0,40);
  // for drawing Horizontal grid lines
  float xLineGap = (height-axisOffset)/9;
  for (float y=height-axisOffset; y>=0; y=y-xLineGap){
    line(axisOffset,y,width,y);
  }
  //println(numCols);
  float yLineGap = (width-axisOffset)/numCols;
  for (float x=axisOffset+yLineGap;x<=width; x+=yLineGap)
  {
    line(x,0,x,height-axisOffset);
  }
  popStyle();
}

void dataTransformation(){
  // data will be in the range of 0 < 9*(height-axisOffset)
  //transform the data
  plotData = new float[numCols];
  for(int i=0;i<numCols;i++)
  {
    plotData[i] = numericData[i]*(height-axisOffset)/9;
  }
  //println(plotData);
}

void plotPoints(){
  float yLineGap = (width-axisOffset)/numCols;
  for(int i=0;i<numCols;i++){
    strokeWeight(6);
    float yCoord = height-(plotData[i]+axisOffset+yLineGap);
    //println(plotData[i]);
    point(axisOffset+yLineGap+(yLineGap)*i,yCoord);
  }
}

void printLabels(){
  //title
  fill(0,0,0);
  textSize(20);
  textAlign(CENTER);
  String title = "Graph Of Average Pace [minutes/km] Against Run Days";
  text(title,width/2, height-(axisOffset/5));
  
  
  //x-axis labels
  float yLineGap = (width-axisOffset)/numCols;
  for(int i=0;i<numCols;i++)
  {
    text(i+1,axisOffset+yLineGap+(yLineGap)*i, height-(axisOffset*3/5));
  }
  
  //y-axis labels
  float xLineGap = (height-axisOffset)/9;
  int text = 0;
  for(float y=height-axisOffset; y>=0; y=y-xLineGap)
  {
    text(text,axisOffset-10,y);
    text++;
    //println(text);
  }
    
  for (float y=height-axisOffset; y>=0; y=y-xLineGap){
    line(axisOffset,y,width,y);
  }
}

 

Week 4: Generative text

For this weeks exercise, I liked the ‘Word made of Circles’ example that we looked at in class so I tried out what it could look like with a rectangle instead of ellipses, and to enhance that ‘edgy’ look, I imported a new font with letter composed of little squares. For the colors, I gave the little rectangles that compose the letters a white outline and a yellow, slightly transparent fill that matches the yellow of the background. This creates somewhat of a gradient from the yellow inside of the letters to the white edge that only becomes  visible when hovering over the letters.

This screenshot shows the color gradient from yellow to white inside the letters.

Take a look at the processing code below adapted from the class example.

import geomerative.*;
RFont font;
String phrase = "susanne";
float xOffset = 0;

RPoint[] pnts;

void setup() {
  size(800, 800);
  RG.init(this);
  font = new RFont("PressStart2P-Regular.ttf", 100, RFont.LEFT);

  // load the phrase into geomerative
  // the first line sets how much distance should there by between each point 
  RCommand.setSegmentLength(1);
  //RCommand.setSegmentator(RCommand.UNIFORMLENGTH);
  RCommand.setSegmentator(RCommand.UNIFORMLENGTH );
  RGroup grp;
  grp = font.toGroup(phrase);
  grp = grp.toPolygonGroup();
  pnts = grp.getPoints();

  // to set the word in the middle of the screen
  // get the size of the phrase subtracted from the width of the screen
  // this is the amount left over
  xOffset = width - grp.getBottomRight().x - grp.getBottomLeft().x;
  // divide that by two to center it
  xOffset = xOffset/2;

  fill(251, 252, 163, 5);
  stroke(255, 255, 255, 40);
}

void draw() {
  background(226, 227, 172);

  for (int i=0; i< pnts.length; i++) {
    float moveIt = (noise(frameCount*.01+i*.01)-.5)*10;
    float x = pnts[i].x + moveIt + xOffset;
    float y = pnts[i].y + moveIt + height/2;

    // dividing makes it invert it's action
    float diam = 2500/dist(x, y, mouseX, mouseY);
    diam = constrain(diam, 7, 70);

    rect(x, y, diam, diam);
  }
}