JavaScript library for all kinds of color manipulations

Overview

Chroma.js

Chroma.js is a tiny small-ish zero-dependency JavaScript library (13.5kB) for all kinds of color conversions and color scales.

Build Status

Usage

Initiate and manipulate colors:

chroma('#D4F880').darken().hex();  // #9BC04B

Working with color scales is easy, too:

scale = chroma.scale(['white', 'red']);
scale(0.5).hex(); // #FF7F7F

Lab/Lch interpolation looks better than RGB

chroma.scale(['white', 'red']).mode('lab');

Custom domains! Quantiles! Color Brewer!!

chroma.scale('RdYlBu').domain(myValues, 7, 'quantiles');

And why not use logarithmic color scales once in your life?

chroma.scale(['lightyellow', 'navy']).domain([1, 100000], 7, 'log');

Like it?

Why not dive into the interactive documentation (there's a static version, too). You can download chroma.min.js or use the hosted version on cdnjs.com.

You can use it in node.js, too!

npm install chroma-js

Or you can use it in SASS using chromatic-sass!

Build instructions

First clone the repository and install the dev dependencies:

git clone [email protected]:gka/chroma.js.git
cd chroma.js
npm install

Then compile the coffee-script source files to the build files:

npm run build

Don't forget to tests your changes! You will probably also want to add new test to the /test folder in case you added a feature.

npm test

And to update the documentation just run

npm run docs

To preview the docs locally you can use

npm run docs-preview

Similar Libraries / Prior Art

Author

Chroma.js is written by Gregor Aisch.

License

Released under BSD license. Versions prior to 0.4 were released under GPL.

Further reading

FAQ

There have been no commits in X weeks. Is chroma.js dead?

No! It's just that the author of this library has other things to do than devoting every week of his life to making cosmetic changes to a piece of software that is working just fine as it is, just so that people like you don't feel like it's abandoned and left alone in this world to die. Bugs will be fixed. Some new things will come at some point. Patience.

Comments
  • Add linear RGB interpolation

    Add linear RGB interpolation

    Your RGB interpolation is in the logarithmic sRGB space, which doesn’t match human vision, please check out this video

    You should add a linear RGB interpolation as demonstrated in this pen.

    The video should convince you that linear RGB should be the default interpolation mode

    opened by flying-sheep 12
  • chroma.deltaE is not really Delta E

    chroma.deltaE is not really Delta E

    Hi, First, thanks for the great lib!

    The structure of the wiki page on Delta E is not very clear but it still states that Delta E was defined by the CIE. There are various versions of the metric (76, 94, 2000), each coming with additional corrections.

    The implementation of Delta E in chroma.js is that of CMC l:c which was defined by the "Colour Measurement Committee of the Society of Dyers and Colourists", not the CIE. So, even though it is defined as a subsection of the Delta E section on wikipedia, does not seem to be a Delta E metric (and the non commutability of the arguments is a tell of that).

    @Offirmo proposed an implementation of Delta E 94 in #127. I implemented Delta E 2000 there (see the deltaE_lab function), albeit in R, but it should not be very hard to convert to js. It is checked against the data in the paper by Sharma et al 2005 and is correct.

    I would suggest using one of those as chroma.deltaE and redefining the current deltaE as chroma.CMClc.

    Thanks in advance!

    opened by jiho 10
  • perceptual color difference

    perceptual color difference

    Hello and thanks for your great lib !

    I'm generating scales of colors to be displayed on a light grey background.

    Since I don't want the generated colors to be hard to differentiate from the background, I'm filtering them by their "closeness" to the background color.

    The only way I found so far was to use the "contrast(a, b)" function, but it doesn't work that well perceptually. For example, for a same minimum contrast, the yellow color it a lot closer to the light grey than the blue color.

    Researching color difference, I saw here http://stackoverflow.com/questions/9018016/how-to-compare-two-colors some suggestions about using delta-E.

    Does it exist in chroma ? If not, wouldn't it be a nice addition ?

    opened by Offirmo 10
  • Proposal: make Chroma.js immutable

    Proposal: make Chroma.js immutable

    This is something I’ve been thinking on for a long time but could actually implement it by myself.

    Given how immutable data structures are gaining traction it would be awesome to have chroma.js offer purely immutable alternatives.

    What do you think about it?

    opened by yuchi 8
  • Inconsistency between `mix` and `average`

    Inconsistency between `mix` and `average`

    I understood averaging as a more general version of mixing, for more than two colors, but:

    clrs=[chroma.random(),chroma.random()]
    
    // in those two modes, mix and average give the same result
    chroma.mix(clrs[0], clrs[1], 0.5, 'rgb').hex()
    chroma.average(clrs, 'rgb').hex()
    
    chroma.mix(clrs[0], clrs[1], 0.5, 'lab').hex()
    chroma.average(clrs, 'lab').hex()
    
    // in the following they don't
    chroma.mix(clrs[0], clrs[1], 0.5, 'hcl').hex()
    chroma.average(clrs, 'hcl').hex()
    
    chroma.mix(clrs[0], clrs[1], 0.5, 'hsv').hex()
    chroma.average(clrs, 'hsv').hex()
    
    chroma.mix(clrs[0], clrs[1], 0.5, 'hsl').hex()
    chroma.average(clrs, 'hsl').hex()
    
    chroma.mix(clrs[0], clrs[1], 0.5, 'hsi').hex()
    chroma.average(clrs, 'hsi').hex()
    
    chroma.mix(clrs[0], clrs[1], 0.5, 'lrgb').hex()
    chroma.average(clrs, 'lrgb').hex()
    
    opened by jiho 7
  • Channels API

    Channels API

    Is there a way to set/retrieve channel value, as it is done in harthur/color? Or are there any plans on that? E. g.

    var Color = requie('chroma');
    var c = new Color('gray');
    c.red(); //128
    
    opened by dy 7
  • Feature Request: Option for Repeating Chroma Scale

    Feature Request: Option for Repeating Chroma Scale

    New option for chroma scale for repeating gradient. Something like SVG gradient spreadMethod

    Right now:

    let grad = chroma
        .scale(['black', 'red', 'white']);
    
    grad(-.5).css(); // rgb(0,0,0)
    grad(1.5).css(); // rgb(255,255,255)
    grad(2).css();   // rgb(255,255,255)
    

    Usage Example 1:

    let grad = chroma
        .scale(['black', 'red', 'white'])
        .spread('reflect');
    
    grad(-.5).css(); // rgb(255,0,0)
    grad(1.5).css(); // rgb(255,0,0)
    grad(2).css();   // rgb(0,0,0)
    

    Usage Example 2:

    let grad = chroma
        .scale(['black', 'red', 'white'])
        .spread('repeat');
    
    grad(-.5).css(); // rgb(255,0,0)
    grad(1.5).css(); // rgb(255,0,0)
    grad(2).css();   // rgb(255,255,255)
    

    Usage Example 3:

    let grad = chroma
        .scale(['black', 'red', 'white'])
        .spread('pad');
    
    grad(-.5).css(); // rgb(0,0,0)
    grad(1.5).css(); // rgb(255,255,255)
    grad(2).css();   // rgb(255,255,255)
    

    Sorry for my broken english.

    opened by mazznoer 6
  • Feature Request: Auto Legend

    Feature Request: Auto Legend

    I have done a lot of d3 inside and out. chroma is nice for when I just need to color some html elements. Still would like to have a legend. Would be nice if I could just call

    chroma.legendify(scale, element), and it produces a flexible legend in that element

    opened by SumNeuron 6
  • Code splitting

    Code splitting

    13.4 kB gzipped is by no means "tiny", like the README suggests: https://bundlephobia.com/[email protected]. If only using certain features, one should be able to load them individually.

    Rather than just concatenating source files together, we need to use proper imports/exports and translate each .coffee file into a corresponding .js file into a lib folder.

    opened by Ambyjkl 6
  • Support case-insensitive colorbrewer lookups

    Support case-insensitive colorbrewer lookups

    Allows colorbrewer scales to be found by lowercase name.

    The original case is fine for developers but when you start exposing them to end-users it can get annoying. Whether you use blues or Blues the intent is clear. This permits both options.

    Thanks for the great library!

    opened by rymohr 6
  • Mixing alpha colors yields some funky results.

    Mixing alpha colors yields some funky results.

    Mixing black with a transparent color:

    chroma.mix('hsla(0,0%,0%,1)', 'hsla(0,100%,50%,0)').css('hsl')
    // Returns "hsla(0,100%,25%,0.5)"
    // Expected "hsla(0,0%,0%,0.5)"
    

    Mixing a color with a semitransparent color

    chroma.mix('hsla(0,100%,50%,1)', 'hsla(180,50%,50%,0.5)').css('hsl');
    // Returns "hsla(0,25.1%,50%,0.75)"
    // Expected "hsla(90,75%,50%,0.5)"
    
    opened by larsenwork 5
  • CMYK conversion

    CMYK conversion

    chroma.cmyk(1, 0, 0, 0) gives #00ffff which is not realistic (pure cyan ink is way different!). By comparison Photoshop converts to #009fe3 (obviously, including its advanced conversion engine, specific colour profiles etc). Would it be possible to have a more realistic conversion by default?

    opened by fallenartist 0
  • Bump qs from 6.5.2 to 6.5.3

    Bump qs from 6.5.2 to 6.5.3

    Bumps qs from 6.5.2 to 6.5.3.

    Changelog

    Sourced from qs's changelog.

    6.5.3

    • [Fix] parse: ignore __proto__ keys (#428)
    • [Fix] utils.merge: avoid a crash with a null target and a truthy non-array source
    • [Fix] correctly parse nested arrays
    • [Fix] stringify: fix a crash with strictNullHandling and a custom filter/serializeDate (#279)
    • [Fix] utils: merge: fix crash when source is a truthy primitive & no options are provided
    • [Fix] when parseArrays is false, properly handle keys ending in []
    • [Fix] fix for an impossible situation: when the formatter is called with a non-string value
    • [Fix] utils.merge: avoid a crash with a null target and an array source
    • [Refactor] utils: reduce observable [[Get]]s
    • [Refactor] use cached Array.isArray
    • [Refactor] stringify: Avoid arr = arr.concat(...), push to the existing instance (#269)
    • [Refactor] parse: only need to reassign the var once
    • [Robustness] stringify: avoid relying on a global undefined (#427)
    • [readme] remove travis badge; add github actions/codecov badges; update URLs
    • [Docs] Clean up license text so it’s properly detected as BSD-3-Clause
    • [Docs] Clarify the need for "arrayLimit" option
    • [meta] fix README.md (#399)
    • [meta] add FUNDING.yml
    • [actions] backport actions from main
    • [Tests] always use String(x) over x.toString()
    • [Tests] remove nonexistent tape option
    • [Dev Deps] backport from main
    Commits
    • 298bfa5 v6.5.3
    • ed0f5dc [Fix] parse: ignore __proto__ keys (#428)
    • 691e739 [Robustness] stringify: avoid relying on a global undefined (#427)
    • 1072d57 [readme] remove travis badge; add github actions/codecov badges; update URLs
    • 12ac1c4 [meta] fix README.md (#399)
    • 0338716 [actions] backport actions from main
    • 5639c20 Clean up license text so it’s properly detected as BSD-3-Clause
    • 51b8a0b add FUNDING.yml
    • 45f6759 [Fix] fix for an impossible situation: when the formatter is called with a no...
    • f814a7f [Dev Deps] backport from main
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Add support for WCAG 3 contrast check with APCA

    Add support for WCAG 3 contrast check with APCA

    Currently, chroma.contrast() caters only to WCAG 2 standard. But it sometimes behaves unexpectedly.

    image

    Would you consider adding APCA (Advanced Perceptual Contrast Algorithm) contrast check as parameter to this or as a new function?

    opened by mkalamarz 1
  • Initializing color in gl space without alpha gives unexpected results

    Initializing color in gl space without alpha gives unexpected results

    Observations:

    • No alpha value for gl seems to be fine: chroma(0.5, 0.5, 0.8, "gl") = #8080cc (expected)
    • Until you use this object: chroma(0.5, 0.5, 0.8, "gl").brighten(1) = 1 (unexpected)
    • Adding an alpha value helps: chroma(0.5, 0.5, 0.8, 1, "gl").brighten(1) = #b1afff (expected)
    opened by pohlt 0
  • Bump terser from 5.10.0 to 5.14.2

    Bump terser from 5.10.0 to 5.14.2

    Bumps terser from 5.10.0 to 5.14.2.

    Changelog

    Sourced from terser's changelog.

    v5.14.2

    • Security fix for RegExps that should not be evaluated (regexp DDOS)
    • Source maps improvements (#1211)
    • Performance improvements in long property access evaluation (#1213)

    v5.14.1

    • keep_numbers option added to TypeScript defs (#1208)
    • Fixed parsing of nested template strings (#1204)

    v5.14.0

    • Switched to @​jridgewell/source-map for sourcemap generation (#1190, #1181)
    • Fixed source maps with non-terminated segments (#1106)
    • Enabled typescript types to be imported from the package (#1194)
    • Extra DOM props have been added (#1191)
    • Delete the AST while generating code, as a means to save RAM

    v5.13.1

    • Removed self-assignments (varname=varname) (closes #1081)
    • Separated inlining code (for inlining things into references, or removing IIFEs)
    • Allow multiple identifiers with the same name in var destructuring (eg var { a, a } = x) (#1176)

    v5.13.0

    • All calls to eval() were removed (#1171, #1184)
    • source-map was updated to 0.8.0-beta.0 (#1164)
    • NavigatorUAData was added to domprops to avoid property mangling (#1166)

    v5.12.1

    • Fixed an issue with function definitions inside blocks (#1155)
    • Fixed parens of new in some situations (closes #1159)

    v5.12.0

    • TERSER_DEBUG_DIR environment variable
    • @​copyright comments are now preserved with the comments="some" option (#1153)

    v5.11.0

    • Unicode code point escapes (\u{abcde}) are not emitted inside RegExp literals anymore (#1147)
    • acorn is now a regular dependency
    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
Releases(v2.4.0)
Owner
Gregor Aisch
CTO @Datawrapper & proud @nytgraphics alumni. most of my repos live at @vis4 now
Gregor Aisch
:rainbow: Javascript color conversion and manipulation library

color JavaScript library for immutable color conversion and manipulation with support for CSS color strings. var color = Color('#7743CE').alpha(0.5).l

Qix 4.5k Jan 3, 2023
JavaScript Library for creating random pleasing colors and color schemes

#PleaseJS www.checkman.io/please Please.js is a polite companion that wants to help you make your projects beautiful. It uses HSV color space to creat

Jordan Checkman 2.3k Dec 22, 2022
A dependency-free image color extraction library

Color mage A dependency-free image color extraction library. The extraction consists of using K-Means algorithm. It has a few utility functions as wel

Gilmar Quinelato 4 Mar 11, 2022
Fast, small color manipulation and conversion for JavaScript

TinyColor JavaScript color tooling TinyColor is a small, fast library for color manipulation and conversion in JavaScript. It allows many forms of inp

Brian Grinstead 4.5k Jan 1, 2023
Coloris - A lightweight and elegant JavaScript color picker. Written in vanilla ES6, no dependencies. Accessible.

Coloris A lightweight and elegant JavaScript color picker written in vanilla ES6. Convert any text input field into a color field. View demo Features

Momo Bassit 126 Dec 27, 2022
A simple color picker application written in pure JavaScript, for modern browsers.

Color Picker A simple color picker application written in pure JavaScript, for modern browsers. Has support for touch events. Touchy… touchy… Demo and

Taufik Nurrohman 207 Dec 14, 2022
Color2k - a color parsing and manipulation lib served in roughly 2kB

color2k a color parsing and manipulation lib served in roughly 2kB or less (2.8kB to be more precise) color2k is a color parsing and manipulation libr

Rico Kahler 506 Dec 31, 2022
A CLI utility to calculate/verify accessible magic numbers for a color palette.

A11y Contrast A CLI utility to calculate/verify accessible magic numbers for a color palette. Read my blog post for some more information. Installatio

Darek Kay 23 Nov 13, 2022
Create your own complete Web color system fast and easy!

Simpler Color Create your own complete Web color system fast and easy, from as little as one base color! Color is at the heart of every UI design syst

Arnel Enero 278 Dec 20, 2022
A tool for creating and maintaining cohesive, consistent, and accessible color palettes

Primer Prism Primer Prism is a tool for creating and maintaining cohesive, consistent, and accessible color palettes. ?? primer.style/prism ?? Read th

Primer 517 Jan 3, 2023
A array with color name -> decimal rgbs.

colors-named-decimal A array with color name -> decimal rgbs. Based on https://www.w3.org/TR/css-color-4/#colors-named Installation This package is ES

小弟调调™ 4 Jul 20, 2022
A TypeScript package to calculate WCAG 2.0/3.0 and APCA color contrasts

a11y-color-contrast A simple utility package for working with WCAG 2.2/3.0 color contrasts a11y: Built for checking how readable colors are together S

Sondre Aasemoen 10 Oct 10, 2022
A simple Discord bot that will listen for HEX, RGB(a), and HSL(a) colors in a message, and provide a small image of that color.

Pigment For the teams of designers and developers out there - Pigment will listen for messages containing a HEX, RGB(a), or HSL(a) color, and provide

Conrad Crawford 17 Dec 8, 2022
Foot Locker is an online store specialized in selling shoes of all kinds, where you can find all the shoes you want

Foot Locker Links ?? Heroku link Adobe XD link Description Foot Locker is an online store specialized in selling shoes of all kinds, where you can fin

G11 1 Apr 16, 2022
👑 A tiny yet powerful tool for high-performance color manipulations and conversions

Colord is a tiny yet powerful tool for high-performance color manipulations and conversions. Features ?? Small: Just 1.7 KB gzipped (3x+ lighter than

Vlad Shilov 1.2k Jan 3, 2023
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
⚡️ Fast parsing, formatting and timezone manipulations for dates

node-cctz CCTZ is a C++ library for translating between absolute and civil times using the rules of a time zone. Install You will need C++11 compatibl

Vsevolod Strukchinsky 59 Oct 3, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022
Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

null 14 Jan 3, 2023
Colormath.js - a color conversion and color manipulation library written in typescript for Node.js, Deno and Browser

Colormath.js - a color conversion and color manipulation library written in typescript for Node.js, Deno and Browser

TheSudarsanDev 8 Feb 8, 2022