Animated text / Spacing problem

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