Display full text string without overlap

Hi guys.

My string of text overlaps itself instead of filling the x1, y1, x,2 and y,2 area. What is going on?

size(700, 1000);

String [] words2 = loadStrings("byer2.txt");

for ( int k = 0; k < words2.length; k++) {
  fill(255);
  text(words2[k], 100, 100, 500, 200);
}

String txt file:

Albertslund Assens Bjert Brønshøj Dianalund Esbjerg Flensburg Fredensborg Fredericia Frederiksberg Gilleleje Greve Haderslev Hellerup Herlev Herning Hillerød Hobro 
Horsens Hvidovre København Køge Kolding Lemvig Lyngby Nørre Alslev Odense Randers Rønne Roskilde Silkeborg Skagen Sorø Svendborg Søborg Sønderborg Sønderho Taastrup Thisted Tønder Valby Vanløse Aalborg Aarhus
1 Like

You have an array which has multiple lines

The lines are shown in the same area in a rect, all of them in the same rect, so they overlap

Solution: add up all Strings to one String result in the for loop using result=result + words2[k] + “\n“;

And don‘t use text inside the for loop but only after it: text (result…

2 Likes

Hey! :hugs:

Good suggestion from @Chrisir. But there are often times where one may need to display contents separately without appending them with \n. An example could be where the file contents are choices for a question and you may want your user to click on the choices displayed.

So in cases like this one, here is a simple method to calculate the number of lines it will take to display the text on canvas. Needless to say, this depends on the textSize() and textFont() set.

void setup () {
  size(700, 1000);

  String [] words2 = loadStrings("byer2.txt");

  float xPos = 100, yPos = 100;
  float w = 500, h = 200;
  float eachH = textAscent() + textDescent(); // height for each line

  fill(255);
  for ( int k = 0; k < words2.length; k++) {
    text(words2[k], xPos, yPos, w, h);
    yPos += linesRequired(words2[k], 500)*eachH;
  }
}

int linesRequired(String input, float toDisplayOnW) {
  float allCharW = 0;
  for (char c : input.toCharArray())
    allCharW += textWidth(c);
  return int((ceil(allCharW/toDisplayOnW) + 1));
}

Hope you find it useful. :blush:

3 Likes

Thanks a lot, it works perfectly

Hi Chris!

How would I go about giving each city a random color from an array of 3 colors?

In my former approach it’s not directly possible

To have each city / word of a new color you need to split at ‘ ‘ (a space sign) - then check the length of the resulting array and make a color arry c1 of the same length - and then for loop over the resulting array and use fill(c1[i]); and use text(… and check for necessary line breaks

Pit falls included

1 Like

How would the syntax look for splitting the String?

This is wrong :confused:

String [] words2 = loadStrings("byer2.txt");
  String [] individual = split(words2, " ");

use join first

  String [] words2 = loadStrings("byer2.txt");
  String [] individual = split(join(words2, " "), " ");

simple example





color[] possibleColors =  {
  color(255, 0, 0), 
  color(255, 0, 255), 
  color(255, 255, 0)
};

String [] words2 = {"Upsala", "Stockholm", "Kopenhagen", "Langeland", "Malmö"};

String [] individual; 

color[] wordColors;

void setup() {

  size(600, 600);

  individual = split(join(words2, " "), " ");

  wordColors = new color[individual.length];

  for (int i = 0; i<individual.length; i++) {

    wordColors[i] = possibleColors [int(random(possibleColors.length))];
  }//for

  background(0);
}//

void draw() {
  background(0); 
  for (int i = 0; i<individual.length; i++) {
    fill(wordColors[i]);
    text(individual[i], 77*i+22, 33);
  }//for
}//func
2 Likes

This is awesome thank you! How would you go about adding line breaks so the text won’t continue outside the canvas?


// set of allowed colors 
final color[] POSSIBLE_COLORS =  {
  color(255, 0, 0), 
  color(255, 0, 255), 
  color(255, 255, 0)
};

String [] words2 = {"Upsala", "Stockholm", "Kopenhagen", "Langeland", "Malmö"};

String [] individual; 

color[] wordColors;

void setup() { // array 

  size(710, 600);

  // make a longer list of words 
  for (int i = 0; i<10; i++) { 
    words2 = concat(words2, words2);
  }

  // step 1: join and make individual words (array "individual")
  individual = split(join(words2, " "), " ");

  // step 2: generate color list "wordColors" of the same length as array individual
  wordColors = new color[individual.length];

  // step 3: fill color list "wordColors" 
  for (int i = 0; i<individual.length; i++) {
    wordColors[i] = POSSIBLE_COLORS [int(random(POSSIBLE_COLORS.length))];
  }//for

  background(0);
}//func 

void draw() {
  background(0);
  showText( individual );
}//func 

void showText(String[] localArray) {

  int x = 12;  
  int y = 33;

  for (int i = 0; i<localArray.length; i++) {
    // Do we need a line break? 
    if (x+textWidth(localArray[i])>width-13) {
      // line break 
      x =  12; // reset x 
      y += 29;  // next line
    }//if

    fill(wordColors[i]);
    text(localArray[i], x, y);
    x+=textWidth(localArray[i])+5; // increase x
  }//for
}//
//
2 Likes

Hi again.

I’ve written this into a class object now.

how would I go about having each individual city increase and decrease in opacity/transparency? :slight_smile: to my understanding the program only reads the text loop once, so would you write a function for the animation and place that into the text()?

this is where I am at so far

class OrdBillede2 {
  
  float opacity;

  color [] muligeFarver = {
    color(100, 214, 232), 
    color(22, 81, 32), 
    color(31, 66, 106), 
  };


  String [] words2 = loadStrings("byer2.txt");
  String [] individual;
  color [] byFarver;


  int o;
  PFont font1;
  float textStr2 = 15;


  OrdBillede2() {

    font1 = loadFont ("Akkurat-Bold-18.vlw");
    textFont(font1);
    //for (int i = 0; i <10; i++) {
    //  words2 = concat(words2, words2);
    //}

    individual = split(join(words2, " "), " ");

    byFarver = new color[individual.length];

    for (int i = 0; i<individual.length; i++) {
      byFarver[i] = muligeFarver [int(random(muligeFarver.length))];
    } // loop
    for (int i = 0; i<individual.length; i++) {
      random(opacity);}
  } // OrdBillede2()


  void display() {
    
  opacity = random(0,255);
    
    showText (individual);
  } // void display
  void showText(String [] localArray) {

    int x = 80;
    int y = 176;

    for ( int i = 0; i <localArray.length; i++) {
      if (x+textWidth (localArray[i])>width-5) {
        x = 80;
        y += 30;
      }
      textFont(font1);
      textSize(textStr2);
      fill(byFarver[i], opacity);
      //rotateY(radians(60));
      text(localArray[i], x, y);
      x+=textWidth (localArray[i])+22;
    }
    
    opacity = opacity +10;
    
  } //  void showText
} // ordBillede2
1 Like

It seems like, in general, you want to flow a set of substrings together into one or more paragraphs while embedding advanced formatting (changes in color, opacity, etc.) around words or phrases.

You might be interested in this previous related discussion:

Wow! This shows a deep misunderstanding of what’s going…

just play with the code a bit.

As you can see in the function showText we use one array for the word localArray and one for the color byFarver.

Read about arrays in the reference

the function showText uses text()

Now to have a variety you could have an array byOpacity like byFarver that hold those values. Define byOpacity where byFarver is defined and use it where byFarver is used

Chrisir