Animated text / Spacing problem

Hi Everyone,

I am trying to create an animated text, starting with a random size and color on the page.
Each letter move according a sine fonction.

Unfortunately, i get lost in my thoughts and don’t understand anymore why i don’t have the result that i am expected.

The text start with right random sizes but wrong spacing and when i am starting to make the letters move, i am losing the random effect and spacing still a problem.

Can someone help me please?

Thank you,

Rémy

PFont f;
String message = "WEIRD";
Letter[] letters;

void setup(){
  size (400,200);
  f = createFont ("Arial",40,true);
  textFont(f);
  
  letters = new Letter[message.length()];
  int x = 100;
  
  for (int i = 0; i < letters.length; i++){
    letters[i] = new Letter (x, height/2,message.charAt(i));
    x += textWidth (message.charAt(i));   
  }
}

void draw(){
  background(0);
  
  for (int i = 0; i < letters.length; i++){
    letters[i].display();
    letters[i].grow();
  }
}

class Letter{
  float x,y;
  char letters;
  
  float s;
  float c;
  float g;
  
  Letter( float _x, float _y, char _letters){
    x = _x;
    y = _y;
    letters = _letters;
    s = random(20,80);
    c = random(50,200);
    g = 0;   
  }

  void display(){
    fill(c);
    textAlign(LEFT);
    textSize(s);
    text(letters,x,y);
  }
  
  void grow(){
    s = map (sin(g),-1,1,5,100);
    g += 0.05;
  }
}
1 Like
PFont f;
String message = "WEIRD";
Letter[] letters;

void setup() {
  size (400, 200);
  f = createFont ("Arial", 40, true);
  textFont(f);
  letters = new Letter[message.length()];
  int x = 100;
  for (int i = 0; i < letters.length; i++) {
    letters[i] = new Letter (x, height/2, message.charAt(i));
    x += textWidth (message.charAt(i));
  }
}

void draw() {
  background(0);
  for (int i = 0; i < letters.length; i++) {
    letters[i].grow();
    letters[i].display();
  }
}

class Letter {
  float x, y;
  char letters;

  float s;
  float c;
  float g;

  Letter( float _x, float _y, char _letters) {
    x = _x;
    y = _y;
    letters = _letters;
    s = random(20, 80);
    c = random(50, 200);
    g = random(TWO_PI);
  }

  void display() {
    fill(c);
    textAlign(LEFT);
    textSize(s);
    text(letters, x, y);
  }

  void grow() {
    g += 0.05;
    g %= TWO_PI;
    s = map( sin(g), -1, 1, 12, 100 );
  }
}

I have fixed the random sizes issue. Before, each letter’s size, s, may have started at random, but was immediately changed to be based on g… which wasn’t random!

I have no idea how you want the letters spaced, so I am unable to help with that. Should the letters never overlap? Should they be spaced out more equally? You weren’t clear. Perhaps a mock-up image or two would help us?

1 Like

Hi @TfGuy44

Thank you for your answer. I didn’t saw that i had g=0; in my settings :sweat:

Regarding the spacing between the letters, i want to have a typographical justification on the left corner (see red dots line on mock-up). When the letters change their sizes, the spacing is conserved regarding their width. Does it makes sens to you?

Let me know.

Best,

Rémy

You are storing absolute coordinates (x, y) in your Letter class - but there is no way for each letter to know its cumulative offset without giving it a way to check the list of all the letters to the left of it. Its absolute position shouldn’t be its job.

Instead, you want a cursor variable or class. Each time a letter is printed, it knows its own width (because the textSize is set) – at that moment, it needs to tell the cursor how wide it is, and the cursor will advance by that much. Then print the next letter, etc.

// https://discourse.processing.org/t/animated-text-spacing-problem/4559/4
// 2018-10-25

PFont f;
String message = "WEIRD";
Cursor cursor;
Letter[] letters;

void setup() {
  size (400, 200);
  // font
  f = createFont ("Arial", 40, true);
  textFont(f);
  textAlign(LEFT);
  // message
  letters = new Letter[message.length()];
  for (int i = 0; i < letters.length; i++) {
    letters[i] = new Letter (message.charAt(i));
  }
  //cursor -- really just an x variable that updates
  // by the width of each letter typed.
  cursor = new Cursor();
}

void draw() {
  background(0);
  translate(100, height/2.0);
  for (int i = 0; i < letters.length; i++) {
    // change letter size
    letters[i].grow();
    // type each letter at cursor location
    // -- this advances the cursor by the current letter-width
    cursor.type(letters[i]);
  }
  cursor.x = 0;  // reset cursor
}

class Cursor {
  float x = 0;
  void type(Letter letter) {
    letter.display(x, 0);
    x += letter.width();
  }
}

class Letter {
  float fillColor;
  char letter;
  float scale;
  float scaleStep;

  Letter(char _letter) {
    letter = _letter;
    scale = random(TWO_PI);
    scaleStep = 0.05;
    fillColor = random(50, 200);
  }

  void display(float x, float y) {
    pushStyle();
    fill(fillColor);
    textSize(this.size());
    text(letter, x, y);
    popStyle();
  }

  float grow() {
    return scale += scaleStep;
  }

  float size() {
    return map(sin(scale), -1, 1, 12, 100);
  }

  float width() {
    pushStyle();
    textSize(this.size());
    float letterWidth = textWidth(letter);
    popStyle();
    return letterWidth;
  }
}

PulsingLetterCursor--screenshot

3 Likes

Hi @jeremydouglass

Sorry for my late answer, i didn’t see yours.
This is exactly what i was looking for. Your cursor solution is a smart approach.

Thank you for the helping hand :wave:

Best,

Rémy

1 Like