Looping busy indicator

Let’s just stash this here…

Javascript code snippet for node.js to display a looping busy indicator on the console output.

/**
 * Display busy animation
 *
 * @param   {number}    ms    Speed in milliseconds
 * @param   {function}  stop  Stop callback, return `true` to stop animation
 * @return  {void}
 */

function busy ( ms, stop ) {
  const arr = '|/―\\';
  let i = 0;

  // the loop
  const id = setInterval( () => {

    // stop animation?
    if ( stop() ) {
      clearInterval( id );
      console.log( '\rDone \033[32;1m\u2713\033[0m' );
      return;
    }

    // continue
    i = !arr[i] ? 0 : i;
    process.stdout.write( `\r${arr[i]} ` );
    i++;

  }, ms );
}

// current time for example
const start = Date.now();

// do animation at speed 90ms
busy( 90, () => {

  // stop after 5 seconds
  return ( Date.now() - start ) >= 5000;

} );
Actual terminal recording

What it does

First define the characters for the loop:

|/―\\

Can be any ASCII character you like. Note that a backslash \ needs to be escaped.

Then check the stop callback function. If it returns false then keep running, else stop the animation, overwrite the line with ‘Done’ with a green (ANSI 32) checkmark (\u2713) and jump to the next line.

Next iterate the characters, wait ms time before each character and reset the index to 0 at the end of the chars.

And finally write the animation characters to the console. When you use console.log each change is written on a new line, because that appends \n to the output. With process.stdout.write you can use \r to reset the cursor to the beginning of the line and then overwrite the displayed characters. The space at the end is there only for good looks.

Like this article?
Buy me a coffee

Changelog
2023-09-18: Rewrite to include stop mechanism


Related stuff


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *