The question is how do we make something like Material Design, Bootstrap progress-bars in a terminal. It seems impossible but it could be done.
In my previous article, we know that the terminal is divided into cells in an x-y plane like a graph with x and y-axis.
It starts with (x, y) (0, 0)
in a positive plane. The terminal by default starts at 0, 0
i.e the cursor is placed at 0, 0
. The cursor current position determines where data will be written to next.
If we place the cursor at (x, y) (9, 5)
, data will start from the (x, y) (9, 5) position. And this can be done with the readline
API readline#cursorTo(stdout, int x: Number, int y: Number)
in Nodejs.
Now, we have this knowledge.
To have a spinning line effect like this:
We know to spin a line, we start with this -
, then anticlockwise, we have \
, then |
and last /
. Then we start again from -
to /
. Now if we can do the above pretty quickly we will have a spinning effect in our terminal.
- \ | /
So all we have to do is to write -
,\
,|
, /
in the same cell rapidly.
To do this in JavaScript, first, we will hold the -
,\
,|
, /
in an array. We will set up an index variable to hold the current index position in the array. Then we will set up a time interval with the setInterval
API.
We will give a time of 100ms, this is to make it execute the function callback very fast to achieve the spinning effect. The function callback will retrieve the current line type from the array using the index we declared previously. Then we write the line type with the process.stdout.write
API. Using this API will make the cursor to advance to the next cell, no we don’t want that. So, we use the readline#cursorTo
API to set the cursor back to the previous cell, so on the next call, the next line type in the array will be written to the same cell.
So with all these executing at speed 100ms, we will see the spinning effect.
Scaffold a Node project, open the index.js
file and add the following code:
Run the file to see the effect:
node .
Let’s go stylish. We can’t have the only effect ['-', '\', '|', '/']
. We can make our Spinner class display different effects, to do that we will create a spinners.json
file.
This will hold different effects:
spinners.json
:
See this as an object that holds different effects. See each effect comes with its time interval. The frames property holds the sequence in which it will be displayed. See the arc
object has frames that when rendered at 100ms will produce an arc effect.
We have the dots objects, these dots objects display the dots effect when displayed rapidly at 80ms frame rate.
Now, we will refactor our Spinner
class to contain our new addition.
As we have spinners.json
, we use the fs#fsReadSync
API to pick up the json file and read the contents to the spinners
variable.
The spin
method now has an argument spinnerName
that holds the name of the effect in the spinners.json
file. With the effect name, we extract from the spinners variable the effect and store the frames
and interval
values in spinnerFrames
and spinnerTimeInterval
respectively.
The spinnerFrames
will now be referenced from to get the next frame style and the spinnerTimeInterval
will be passed to setInterval
to set time interval for the function callback execution.
Now, to run the Spinner
, we create an instance and call the spin
method with the name of the effect we want.
// index.js
...
new Spinner().spin("dots")
Here, the dots
effect will be spinning.
// index.js
...
new Spinner().spin("dots2")
The dots2
effect will be shown.
// index.js
...
new Spinner().spin("line")
This will show our prev line
effect.
// index.js
...
new Spinner().spin("arc")
This will show the arc effect.
You see, how easy it was. We used the setInterval API, process.stdout.write and readline#cursorTo and the style frames to produce the effect.
You can go forth and add the effects of your own. You can also write your implementation better than mine. I would like to see what you will come up with.
If you have any questions regarding this or anything I should add, correct or remove, feel free to comment, email or DM me.
Thanks !!!
☞ JavaScript Programming Tutorial Full Course for Beginners
☞ Learn JavaScript - Become a Zero to Hero
☞ Javascript Project Tutorial: Budget App
☞ E-Commerce JavaScript Tutorial - Shopping Cart from Scratch