Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support 8 & 24 bit color #27

Closed
naturalethic opened this issue Oct 11, 2018 · 13 comments
Closed

Support 8 & 24 bit color #27

naturalethic opened this issue Oct 11, 2018 · 13 comments
Labels
enhancement New feature or request
Milestone

Comments

@naturalethic
Copy link

https://en.wikipedia.org/wiki/ANSI_escape_code#Colors

Additionally, generators for colors say,

const mauve = colorette('#b784a7')

Maybe theming too.

@jorgebucaran jorgebucaran added the enhancement New feature or request label Oct 11, 2018
@jorgebucaran
Copy link
Owner

Interesting idea. There are a few ways to do this. I'll experiment a bit.

@naturalethic What is theming?

@jorgebucaran jorgebucaran changed the title Feature request: 8 & 24 bit color support Support 8 & 24 bit color Oct 20, 2018
@jorgebucaran
Copy link
Owner

Generating the ANSI sequences is easy. Downsampling 24-bit color on terminals that don't support 24-bit color, e.g. Terminal.app not so much.

Chalk does this using color-convert and supports-color.

color-convert can convert a 24-bit color to 16-bit, 8-bit, etc., and supports-color allow you to check for specific terminal color support. Color detection might not be 100% reliable according to this, but it seems to work well.

I'm not going to incorporate color-convert or supports-color as a dependency to Colorette at this time, but I can provide the following new named exports ansi16, ansi256, and rgb, which you can use with color-convert to generate additional color functions.

Here is an example to show you how that could potentially look like:

Example

  • index.js

    const { hex } = require("./utils/hex")
    const mauve = hex("#b784a7")
    
    console.log(mauve("Mauve!"))
  • ./utils/hex.js

    const { stdout } = require("supports-color")
    const { hex } = require("color-convert")
    const { rgb, ansi256, ansi16 } = require("colorette")
    
    module.exports = {
      hex: color =>
        stdout
          ? stdout.has16m
            ? rgb(...hex.rgb(color))
            : ansi256(hex.ansi256(color))
          : ansi16(hex.ansi16(color))
    }

Result

  • Terminal.app

  • iTerm.app (v3.2.3)

cc @naturalethic

@naturalethic
Copy link
Author

naturalethic commented Oct 21, 2018

Great stuff! Regarding theming upon some thought there's nothing you'd need to provide. People can just put together any kind of color scheme they like and provide a small library if they want. Terminals themselves can theme the standard 16 colors.

@jorgebucaran
Copy link
Owner

@naturalethic Thanks! Maybe I can improve this a bit more. I'll experiment more.

@jorgebucaran
Copy link
Owner

@naturalethic I played a bit more with it and whittled it down to this.

const color = require("colorette")
const { rgb, ansi256, ansi16  } = require("color-convert").hex
const hex = color.generate({ rgb, ansi256, ansi16 })

const mauve = hex("#b784a7")
console.log(mauve("Mauve"))

Now, compare it to what I posted above. Which one is better?

const { stdout } = require("supports-color")
const hexTo = require("color-convert").hex
const { rgb, ansi256, ansi16 } = require("colorette")

const hex = color =>
    stdout
      ? stdout.has16m
        ? rgb(...hexTo.rgb(color))
        : ansi256(hexTo.ansi256(color))
      : ansi16(hexTo.ansi16(color))

const mauve = hex("#b784a7")
console.log(mauve("Mauve"))

@naturalethic
Copy link
Author

Seems you could just do this:

const color = require("colorette")
const hex = color.generate(require("color-convert").hex)

@naturalethic
Copy link
Author

Or perhaps you could document that the end user must add color-covert to their packages if they want hex, then just provide the hex method on your library, which will give a friendly error if the color-convert package isn't present.

@jorgebucaran
Copy link
Owner

@naturalethic Opps, I did it again. #31

That adds built-in 24-bit color support.

const { hex } = require("colorette")
const mauve = hex("#b784a7")

console.log(mauve("TrueColor"))
\u001b[38;2;183;132;167mTrueColor\u001b[39m
Terminal.app

Reduced to 8-bit in terminals without TrueColor support.

screen shot 2018-10-26 at 1 00 24

iTerm.app (v3)

screen shot 2018-10-26 at 1 00 01

@naturalethic
Copy link
Author

Hey nice I was wondering if you were going to do this.

@jorgebucaran
Copy link
Owner

@naturalethic Me too. Thoughts? :)

@naturalethic
Copy link
Author

I'll definitely be using this on my next console project. Does the performance hold up even in 24 bit?

@jorgebucaran
Copy link
Owner

@naturalethic Does the performance hold up even in 24 bit?

Yes, it does. The color factory functions hex, bgHex, rgb or bgRgb do extra work to produce a new color function, but once you've created it, the resulting function will perform exactly as any of the 16 built-in ones.

Example

Import a built-in color function and a color factory function.

const { red, hex } = require("colorette")

Derive a new color function.

const trueRed = hex("#ff0000")

From this point on you can expect the same performance out from trueRed and red.

@jorgebucaran
Copy link
Owner

I want to focus on the core functionality of this package, and simply not address 8~24 bit color at this time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
2 participants