thebespokepixel/trucolor-cli

View on GitHub
src/lib/colour.js

Summary

Maintainability
A
0 mins
Test Coverage
/* ─────────╮
 │ trucolor │ Internal color handling, here for optimisation
 ╰──────────┴────────────────────────────────────────────────────────────────── */
import _ from 'lodash'
import terminalFeatures from 'term-ng'
import {TemplateTag, replaceSubstitutionTransformer} from 'common-tags'
import {simple, palette} from 'trucolor'

export const clr = _.merge(simple({format: 'sgr'}), palette({format: 'sgr'}, {
    purple: 'purple',
    purpleSwatch: 'purple desaturate 70',
    orange: 'hsb:45,100,100',
    orangeSwatch: 'hsb:45,100,100 desaturate 70',
    red: 'red lighten 10',
    green: 'green lighten 10',
    blue: 'blue lighten 20',
    hotpink: 'hotpink',
    chocolate: 'chocolate',
    dark: 'red desaturate 100 darken 20',
    msat: 'red desaturate 60',
    mlight: 'rgb(255,255,255) darken 25',
    bright: 'rgb(255,255,255)',
    one: 'red desaturate 50 spin 60',
    two: 'green spin 30',
    ul: 'underline',
    invert: 'invert',
    exBackground: 'background dark red',
    exBold: 'bold yellow',
    exFaint: 'faint yellow',
    exItalic: 'italic #33FF33',
    exInvert: 'invert #7B00B1',
    exUnderline: 'underline #fff',
    exBlink: 'blink orange',
}))

export const colorReplacer = new TemplateTag(
    replaceSubstitutionTransformer(
        /([a-zA-Z]+?)[:/|](.+)/,
        (match, colorName, content) => `${clr[colorName]}${content}${clr[colorName].out}`,
    ),
)

export function spectrum(width, char) {
    if (terminalFeatures.color.has16m) {
        return _.map(Array.from({length: width}), (value, col) => {
            const scos = Math.cos((col / width) * (Math.PI / 2))
            const ssin = Math.sin((col / width) * (Math.PI))
            const red = (scos > 0) ? Math.floor(scos * 255) : 0
            const green = (ssin > 0) ? Math.floor(ssin * 255) : 0
            const blue = (scos > 0) ? Math.floor((1 - scos) * 255) : 0
            return `\u001B[38;2;${red};${green};${blue}m${char}`
        }).join('')
    }

    return `${char.repeat(width)}\n${clr.red.in}  Your terminal currently doesn't support 24 bit color.`
}