Guide Area

JavaScript – Text to dots that explode on hover (Source code)

js-video

0. Introduction

In this tutorial, I will show you how to convert text to dots and add an explosive behavior on hover. This tutorial is based on a source code of Coding Train’s Challenge #59 where Daniel Shiffman talks about usage of Javascript library p5.js. You can either get the source code from the repository linked above, or watch Daniel’s Youtube tutorial:

What Daniel achieved is to translate text to dots as a border and create an exploding-like behavior when you mouse-over the text. My tutorial will modify Daniel’s code a bit. What I achieved is to have a letter made of dots – not just the border, but full body. Let’s get started.

In this tutorial, text is made by manually defining dots in a .txt document, which is a time consuming matter if you plan to create more than just one letter. You can find a way to automatize this yourself – my time is currently very limited, so I couldn’t do it for you.

1. Text to dots

By now, you should either have downloaded source code from repository, or implement it yourself by watching Daniel’s Youtube tutorial. We will modify his code later on, but first of all, we need to discuss a method of creating dots from text.

– The first step

… is to create a .txt document. I will be creating letter “V”, so I saved the file in the root directory of my project, under name v-dots.txt. In this document, I want you to draw any letter that you like using just dots. So if you go for a letter “V”, your doc should look like this:

........                    ........
 ........                  ........
  ........                ........
   ........              ........
    ........            ........
     ........          ........
      ........        ........
       ........      ........
        ........    ........
         ........  ........
          ................
           ..............
            ............
             ..........
              ........
               ......
                ....

– The second step

The above representation of letter V can be modified a little. Think about the dot elements in it. They all share one property – padding from left, defined by number of spaces or other characters in front of them. The first dot in the first row has 0 dots and spaces in front of it, so the padding is 0. The second dot has 0 spaces and 1 dot in front of it, so the padding is 1. And the last dot in the first row has 15 dots and 20 spaces in front of it, so the padding is 35.

So the second step would be to add a padding (as a number) in front of every dot and after that, removing all the spaces. So the first row:

........                    ........

will become:

0.1.2.3.4.5.6.7.28.29.30.31.32.33.34.35

Note: You don’t need to add a dot at the end of the line. Dot’s will be used to split the line later on and we’re only interested in the paddings, as those will tell us where to create a dot in frontend.

– The third step

…is to do the second step for all the lines. At the end, you should end up with a following txt document:

0.1.2.3.4.5.6.7.28.29.30.31.32.33.34.35
1.2.3.4.5.6.7.8.27.28.29.30.31.32.33.34
2.3.4.5.6.7.8.9.26.27.28.29.30.31.32.33
3.4.5.6.7.8.9.10.25.26.27.28.29.30.31.32
4.5.6.7.8.9.10.11.24.25.26.27.28.29.30.31
5.6.7.8.9.10.11.12.23.24.25.26.27.28.29.30
6.7.8.9.10.11.12.13.22.23.24.25.26.27.28.29
7.8.9.10.11.12.13.14.21.22.23.24.25.26.27.28
8.9.10.11.12.13.14.15.20.21.22.23.24.25.26.27
9.10.11.12.13.14.15.16.19.20.21.22.23.24.25.26
10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25
11.12.13.14.15.16.17.18.19.20.21.22.23.24.25
12.13.14.15.16.17.18.19.20.21.22.23.24.25
13.14.15.16.17.18.19.20.21.22.23.24.25
14.15.16.17.18.19.20.21.22.23.24.25
15.16.17.18.19.20.21.22.23.24.25
16.17.18.19.20.21.22.23.24.25

2. Create a mapper object

Daniel’s source code uses textToPoints() to get an array of particles, each defined by position on the text (x and y values). So in order to swap this array for ours, we need to make a new one which will contain objects with the same attributes.

Above the setup() function, insert this code:

function Point(x,y) {
    this.x = x;
    this.y = y;
}

and in addition to that, create two global variables:

var points = [];
var ow,oh; 
// ow and oh = Width and height of a div container
// which will contain the canvas

3. Modify your .html page

First, add these two dependencies:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">

Then, add a wrapper div for canvas that Javascript will create.

<div class="row">
    <div class="col-5 align-middle" id="sketch-wrapper"></div>
    <div class="col"><div>
</div>

4. Rewrite setup() function

So right now, we need to modify functionality of Daniel’s code. We will be getting information about dots from a file. So let’s start by creating a jQuery GET request and moving the whole functionality of the setup() function to it’s .done() thread. Then, we get rid of the textToPoints() part, as well as background() (and possibly comments). Then, we attach a parent div to the canvas. This is what the setup() looks like after all the changes:

function setup() {
    $.get('v-dots.txt', function(data) {
        
    }).done(function() {
        canvas = createCanvas(ow, 500);
        canvas.parent('sketch-holder');

        for (var i = 0; i < points.length; i++) {
            var pt = points[i];
            var vehicle = new Vehicle(pt.x, pt.y);
            vehicles.push(vehicle);
        }
    });
}

5. Map values from .txt and add them to array

The most important part is to map the values from the file with letter V, to an array of points which the library p5.js will use for creating elements on canvas.

If you notice Daniel’s code, when calling textToPoints(), he manually stated padding from top, padding from left and font size. We do not have this opportunity, so additional calculations will be needed. So let’s start.

We will be splitting the contents of .txt file into two-dimensional array, and traversing through it. While doing that, we will create a Point object for every padding number from the .txt file and add it to the array of points. The following code snippet is a working solution – read the line descriptions below the snippet.

function setup() {
    $.get('v-dots.txt', function(data) {
        ow = $("#sketch-wrapper").width();
        oh = $("#sketch-wrapper").height();
        var datarows = data.split("\n");
        for (var i = 0; i < datarows.length; i++) {
            var datapaddings = datarows[i].split(".");
            for (var j = 0; j < datapaddings.length; j++) {
                var paddingleft = datapaddings[j];
                positionleft = ow/10 + (positionleft*7) + (j*7);
                var positiontop = ow/10 + (i*20);
                var p = new Point(positionleft,positiontop);
                points.push(p);
            }
        }
    }).done(function() {
        canvas = createCanvas(ow, 500);
        canvas.parent('sketch-holder');

        for (var i = 0; i < points.length; i++) {
            var pt = points[i];
            var vehicle = new Vehicle(pt.x, pt.y);
            vehicles.push(vehicle);
        }
    });
}

* Line 3, 4: Get width and height of the div that will contain canvas.
* Line 5-8: Split contents of txt file by lines and dots into two-dimensional array, and traverse through it
* Line 9-13: Calculate position on canvas, create new Point object and add it to array

To understand how formulas for calculation of variables positionleft and positiontop work, I should explain its content to you. Please note, that positiontop formula is a bit different than positionleft – this is because we set align-middle class on our div in HTML and therefore we don’t have to maintain top padding on page.

– ow/10 is one tenth of div’s width as a padding from left, so when articles explode, they don’t disappear in borders of screen;
– positionleft*7 is an actual position of the dot on canvas – if specific number in file has a value of 30, positionleft is 30px; multiplying allows to widen the whole letter on canvas
– j*7 is a helper multiplier that allows to add inner padding between dots (horizontally)

js-diagram

6. Test it

Upload your files to your application server and open it in your browser. You should be able to see following content:

js-video

Conclusion

This is one of many usages of the p5.js library and as I stated before, I did not have much time to play with it. You can customize it based on your needs. Hope it helped you. Source code is available here:

Download source code

Vladimir Marton

DevOps Engineer focused on cloud infrastructure, automation, CI/CD and programming in Javascript, Python, PHP and SQL. Guidearea is my oldest project where I write articles about programming, marketing, SEO and others.