Search code examples
javascriptnode.jsterminalcolorscommand-line-interface

How to change color of different things in the same output - JS and Node.js


I am creating a JS RPG CLI game and I have a question about styled output. Once executed, the script outputs a framed Welcome. I need that frame to be colored and the text within needs to be white.

I need this: https://i.sstatic.net/XuYYK.png

I did it with the simple console.log():

    console.log(`
    +-----------------------------+
    |          Welcome !          |
    +-----------------------------+
    `)

To change color I am using simple color references of text:

console.log('\x1b[36m%s\x1b[0m', `
    +-----------------------------+
    |          Welcome !          |
    +-----------------------------+
    `)`

My output is: https://i.sstatic.net/NHtaU.png This changes the color of everything, including the Welcome text and I need that white.

So, how to do that ?


Solution

  • In order to do that you need to change the color of the "Welcome !". But you approach is not very scalable, if you thing you will need to use this "header" many times, you can use this code:

    const colors = {
        cyan: '\x1b[36m',
        reset: '\x1b[0m',
        black: "\x1b[30m",
        red: "\x1b[31m",
        green: "\x1b[32m",
        yellow: "\x1b[33m",
        blue: "\x1b[34m",
        magenta: "\x1b[35m",
        cyan: "\x1b[36m",
        white: "\x1b[37m",
        gray: "\x1b[90m",
    }
    
    const logHeader = (text, color, textColor = colors.reset) => {
        // At least four spaces on each side of the string
        const length = Math.max(29, text.length + 4 * 2)
    
    
        const pipe = `${ color }|${ colors.reset }`
        const emptySpace = length - text.length
    
        const  leftSpaceLength= Math.floor(emptySpace / 2)
        const rightSpaceLength = emptySpace - leftSpaceLength
        const  leftSpace = Array.from({ length:  leftSpaceLength }).fill(' ').join('')
        const rightSpace = Array.from({ length: rightSpaceLength }).fill(' ').join('')
    
        const divider = `${ color }+${ Array.from({ length }).fill('-').join('') }+${ colors.reset }`
    
        const textLine = pipe + leftSpace + textColor + text + colors.reset + rightSpace + pipe
    
        console.log([ divider, textLine, divider ].map(e => '    ' + e).join('\n'))
    }
    
    // this is equivalent to what you had before (of course with the welcome uncolored
    logHeader('Welcome !', colors.cyan)
    
    // but you can also change its color
    logHeader('Welcome !', colors.cyan, colors.red)
    
    // or easily change the text for later uses
    logHeader('Good bye !', colors.green, colors.yellow)