Concept
Initially , I tried figuring out whether data visualization or generative text would be a cooler project to work on . I tried data visualization for precipitation for every city but I couldn’t find large clean datasets and had difficulty in setting the world map to scale as the background of my canvas .
Meanwhile , in the generative text side , I experimented with different fonts and different ways to display and adjust text . I came across the texttoPoints() method that creates an array of points from a text when using a specified font . I looked for cool implementations online and came across this video by Ed Cavett –
I thought this was amazing and decide to do something using this code and logic to create interactive generative text .
-
- First of all, I wanted to have dynamic text such that whatever the user would input in a text box would be displayed on the screen. Although I thought this would be easy, it was challenging for me to implement it as I had to understand the class lineMaker() created by Ed Cavett fully and had to change some aspects of it to ensure that text was generated dynamically.
- I wanted to add the words that were typed in the background too – this involved changing the position of the words in the background depending upon the textlength and using loops to fill the whole screen with the correct spacing . I also experimented with color and alpha values to see what suited the best .
- I wanted some moving letters based on what the user had typed . For each letter typed by the user, I created a letter object that would move in a circle of changing radius to give the effect that the circle was closing in to the center of the canvas . The letters would disappear as the text was changed .
- After reading about signifiers in this week’s reading , I had to make sure that the user knew how to change the text at the center of the canvas . So , I added a message next to the text box so that when the user presses enter, the message at the center is updated .
- I also wanted to add a ‘fire ‘ effect instead of a lightning effect to the letters at the center so I changed the color values for highlighting the text and the color of the ‘darts’ too .
Sketch
PLEASE ENTER TEXT IN THE TEXTBOX AND PRESS ENTER !! HAVE FUN !!
Challenges while implementing
-
- I had a lot of errors while implementing the code. The backspace functionality to remove any letters already on canvas was tricky to implement . It would duplicate the letters . I found a way to clear the array and regenerate it every frame to remove this error . Althouugh this is not the most efficient way to do it (which would be to push and pop elements at the end of the array)
- The aligning of words typed to the background of canvas was another aspect . It took some time to get the alignment right. Initially , I had tried to use the array generated by textToPoints() function for drawing the words as points but the program would lag/crash due to the large number of points so I decided to stick with using text .
- The code to generate the darts and form the word in the center that is based on Ed Cavett’s code was fairly complicated for me and it took a lot of time understanding it . Thankfully , I did not have to change much and it was only important to broadly understand what each segment does so that I could change the properties as intended .
Code that I am proud of
This project took a lot of time and I am really proud of the fact that I was able to make a dynamic version of Ed Cavett’s text art . In addition , I implemented the background and the spiral letters as well as the Letter class . I am most proud of the code for letter class as follows :
class Letter { constructor(char) { this.char = char; this.x = random(width); this.y = random(height); this.angle = atan2(this.y - height / 2, this.x - width / 2); // Angle from center this.radius = 300; } update() { let angularSpeed = 0.05; // Increase or decrease radius based on current value if (this.radius >= 400) { this.radiusDecreasing = true; //boolean to determine whether circle should increase or decrease } else if (this.radius <= 200) { this.radiusDecreasing = false; //flase if radius is below 200 } // Increment or decrement radius if (this.radiusDecreasing) { this.radius -= 1; } else { this.radius += 1; } // Update angle this.angle += angularSpeed; this.x = width / 2 + cos(this.angle) * this.radius; this.y = height / 2 + sin(this.angle) * this.radius; } display() { textSize(fontSize); fill(255,150,0); text(this.char, this.x, this.y); } }
I also spent a lot of time implementing the alignment for the words in the background , this is the piece of code that does that :
// Word Decor let charArray = input.value().split(''); word = input.value(); //implementing word decor // Calculate text width let text_Width = myFont.textBounds(word, 0, 0, fontSize).w; // Calculate horizontal position for centering let centerX = (width - text_Width)/2; // Draw points push(); stroke(255); for (let i = 0; i < points.length; i++) { point(points[i].x, points[i].y); } pop(); }*/ for(let j=0;j<num_cols;j++){ for(let i=0;i<num_lines;i++){ fill(200,200,200,20); text(word,centerX,50+ i*fontSize); } translate(-text_Width,0); } //reset canvas translate(text_Width*num_cols ,0); for(let j=0;j<num_cols;j++){ for(let i=0;i<num_lines;i++){ fill(200,200,200,20); text(word,centerX,50+ i*fontSize); } translate(text_Width,0); } //resets canvas to OG position translate(-text_Width*num_cols,0);
Here, the translate functions have been used to fill the whole canvas . I have made sure that I translate back to the original position once the drawing is done . Although looking back , I think using pop() in the right way would make it easier , this is the way I decided to implement it .
Reflection/Scope for improvement
I am very happy with what I achieved at the end . The project took a lot of time but I learnt a lot – especially while trying to understand the lineMaker() class . However there are certain additional implementations that I had thought of which I would love to look into in the future but I couldn’t implement now because of errors that would take time to debug :
-
- Increase the number of letters in the circle – you will notice there is an unused variable called lettermultiplier in the beginning that is set to 5 as well as a commented out for loop in). This was for adding extra letters to the circle, however the for loop doesn’t work as expected for some reason and the letters attain complete randomness in motion instead of moving smoothly ( it probably has to do something with instantiating each letter object but I couldn’t pinpoint the source of the error) .
- Use different font (I have used Roboto which is fairly common , maybe a fancier font could look better)
- Experiment with different uses of texttoPoints() function . This function can be used in a variety of interesting ways . Although I have used it only for one such way , there seems to be endless possibilities with this function.