Coder Social home page Coder Social logo

chromatism's Introduction

Chromatism 🌈

A simple set of utility functions for colours.

NPM

Awesome resources for colour stuff.

Table of Contents

Contributing

First off, thanks so much for helping out! Colour modes + functions contributing info will be added soon.

Note: The type definitions file (/index.d.ts) must be updated as part of your pull request. (If you're not familiar with typescript, I can update it for ya.) It contains definitions for colour modes AND colour functions. (Special thanks to @bdoss on GitHub for adding the inital TS definitions!)

Installation

$ npm install --save chromatism

CommonJS

var chromatism = require('chromatism');

ES Modules

import * as chromatism from 'chromatism';

ES Module also exports all functions individually, allowing for tree-shaking and smaller bundles

import { brightness } from 'chromatism';

Browser without bundling

<script type="text/javascript" src="path-to-files/dist/chromatism.js"></script>

Functions

All functions can take any colour type. You can even mix colour types if a function takes more than one. A list of colour types are available here. Return values are also not bound by the function. Any functions that return colours, return a colour object, which contains getters for each colour type. If you take the return value of one of these functions and get returnValue.hex for example, you will get the hexadecimal equivalent value.

In previous versions (Pre. v2.x), you could chain functions. This functionality has been removed to save space on the bundle.

⚠️ Note: The following examples return different types of values, (hex, rgb, hsl, etc) but you can use any of the available colour modes as seen in the colour modes table at the bottom of this README.

💱 Colour Transformations

The following functions return a Colour Object, which contains getters to get a return value of any colour mode. See [Colour Mode](#Colour Modes) table for a list of all the available colour modes.

Convert colour types

var newColour = chromatism.convert( colour ).hex;

Value can be any colour in any of the supported colour modes. (See chart at bottom of README) This is an identity operation, as it just returns an object containing all of the available colour modes of the result.

All colour modes supported can be converted to any other. This does however mean that some conversions will have intermediate values, which can cause small inconsistencies, especially when changing colour spaces. The path for each conversion is optimised as much as possible to avoid loss of colour information.


Generate a complementary colour

var newColour = chromatism.complementary( colour ).rgb;

There is also a uniform version of this function. When using the uniform version, the output colours will have the same apparent lightness as the source colour, which normally means they'll look nicer together. (There is a performance trade-off however.)

var newColour = chromatism.uniformComplementary( colour ).rgb;

Complementary


Generate an array of triad colours

var newColour = chromatism.triad( colour ).hsl;

There is also a uniform version of this function. When using the uniform version, the output colours will have the same apparent lightness as the source colour, which normally means they'll look nicer together. (There is a performance trade-off however.)

var newColour = chromatism.uniformTriad( colour ).rgb;

Triad


Generate an array of tetrad colours

var newColour = chromatism.tetrad( colour ).cmyk;

There is also a uniform version of this function. When using the uniform version, the output colours will have the same apparent lightness as the source colour, which normally means they'll look nicer together. (There is a performance trade-off however.)

var newColour = chromatism.uniformTetrad( colour ).rgb;

Tetrad


Find the mid point between two colours

var newColour = chromatism.mid( colourOne, colourTwo ).cssrgb;

Mid


Invert a colour

var newColour = chromatism.invert( colour ).hex;

Invert


Invert a grey colour

var newColour = chromatism.invertLightness( colour ).hsl;

Invert Lightness


Blend two colours (Multiply)

var newColour = chromatism.multiply( colourOne, colourTwo ).hsv;

Blend


Generate an array of adjacent hue-shifted colours (rainbow effect)

var newColour = chromatism.adjacent( degrees, sections, colour ).cmyk;

Rainbow

Shift should be in degrees. It can be either positive and negative.


Generate an array of the fade between two colours

var newColour = chromatism.fade( amount, colourFrom, colourTo ).hsl;

Fade


Generate a new shade of a colour

var newColour = chromatism.shade( percent, colour ).csshsl;

Shade

Percent should be a number between -100 and 100.


Generate a new saturation of a colour

var newColour = chromatism.saturation( percent, colour ).hex;

Saturation

Percent should be a number between -100 and 100.


Change colour's brightness

var newColour = chromatism.brightness( percent, colour ).hsl;

Brightness

This essentially acts as a sum of saturation and shade, and thus does not adjust luminosity. Brightness works for 99% of most scenarios though.

Percent should be a number between -100 and 100.


Shift the hue of a colour

var newColour = chromatism.hue( degrees, colour ).hex;

Hue

Hue shift is measured in degrees, using the HSL colour model.


Shift the contrast of a colour

var newColour = chromatism.contrast( contrastCoeff, colour ).hsl;

Contrast

Contrast coefficient is supplied in decimal form! You'll normally use a value between 0 and 4.

Imagine increasing the contrast (shift > 1) as making lighter colours lighter, and darker colours darker. Decreasing (shift < 1) makes all colours more similar.


Greyscale version of the colour

var newColour = chromatism.greyscale( colour ).cmyk;

Greyscale


Sepia version of the colour

var newColour = chromatism.sepia( colour ).hsv;

Sepia


Determine accessible colour for foreground text

var newColour = chromatism.contrastRatio( colour ).rgb;

Contrast Ratio

Use this function to determine the colour of text needed create a high contrast between text and a solid background of the supplied colour. Made according to the W3C Standard on Web Accessibility


Chromatic Adaptation (White point)

var newColour = chromatism.adapt( colour, illuminant, [source illuminant] ).XYZ;

Illuminant Adaptation

Shifts the Illuminant (white-point) on the supplied colour. Supply an illuminant label as a capital-letter string in the illuminant attribute. (e.g. "D65", "F2") A full list is available at the bottom of this README. Most standard white-points are supported. (Most colours in Chromatism are assumed to be illuminated by D65, so you can leave off the source illuminant property normally, it defaults to CIE 2° D65.)


🔢 Colour Metering Functions

These functions do not return a colour, but instead return some aspect or measure of the colour(s).

Colour Difference

var diff = chromatism.difference( colourOne, colourTwo, [luminance weight], [chroma weight] );

Returns a measure of how different the two supplied colours are. Luminance and Chroma weight are equal to l and c in the CMC l:c Delta-E equation. By default they are both set to 1. (Thus testing imperceptibility)

Colour Temperature

var diff = chromatism.temperature( colour );

Returns the correlated colour temperature of the supplied colour in Kelvin. (A higher number indicates a blue-er colour; a lower number indicates a red-er colour.) This should only be used when working with colours that could actually be emitted by a black-body radiator (think glowing stuff, such as tungsten in incandescent lightbulbs), as colour temperature is only an approximation of the colour to a narrow strip of the XYZ gamut. (Note the thin line in the middle of this chart.)

Colour temperature is calculated via McCamy's CCT fomula. (DOI: 10.1002/col.5080170211) Which may mean that colours temperatures beyond 6500K (CIE Illuminant D65) are not entirely accurate

Supported Values

Reference Values Description
Illuminants "A", "B", "C", "D50", "D55", "D65", "D75", "E", "F2", "F7", "F11" Standard CIE illuminants in XYZ format

Scales + Colour Spaces

Mode Scale Colour Space
.hex #000000 - #FFFFFF sRGB
.rgb (r, g, b) 0 - 255 sRGB
.cssrgb (r, g, b) 0 - 255 sRGB
.hsl (h) 0 - 359, (s, l) 0 - 100 sRGB
.csshsl (h) 0 - 359, (s, l) 0 - 100 sRGB
.hsv (h) 0 - 359, (s, v) 0 - 100 sRGB
.cmyk (c, m, y, k) 0 - 1 CMYK
.yiq (y, i, q) 0 - 1 YUV
.XYZ (Y) 0 - 100, (X, Z) derived XYZ
.xyY (Y) 0 - 100, (x, y) 0 - 1 XYZ
.lms (⍴, γ, β) 0 - 1 XYZ
.cielab (L*a*b*) (L) 0 - 100, (a, b) -128 - 128 CIELAB
.cieluv (L*u*v*) (L) 0 - 100, (u, v) -128 - 128 CIELUV
.cielch (L*C*h*) (L) 0 - 100, (C, h) -128 - 128 CIELCh
.hsluv (hu) 0 - 359, (s, l) 0 - 10 CIELCh

Colour Modes

Mode Example Syntax
.hex "#FFC837"
.rgb { r:255, g: 200, b: 55 }
.cssrgb "rgb(255,200,55)"
.hsl { h: 44, s: 100, l: 61 }
.csshsl "hsl(44,100,61)"
.hsv {h: 44, s: 78, v: 100}
.cmyk {c: 0.5, m: 1, y: 0.2, k: 0.45}
.yiq { y: 0.132, i: 0.0222, q: 0.195 }
.XYZ { X: 41.24, Y: 21.26, Z: 1.93 }
.xyY { x: 0.64, y: 0.33, Y: 21.26 }
.lms { rho: 42.266, gamma: 5.561, beta: 2.135 }
.cielab (L*a*b*) { L: 53.23, a: 80.11, b: 67.22 }
.cieluv (L*u*v*) { L: 53.23, u: 175.05, v: 37.75 }
.cielch (L*C*h*) { L: 53.23, C: 179.08, h: 12.17 }
.hsluv { hu: 12.17, s: 99.99, l: 53.23 }

⚠️ A note about CIELUV + CIELCH: Conversion to CIELUV (and by extension, CIELCH) requires defining the illuminant, which can skew results slightly. By default, Chromatism assumes all colours are illuminated by CIE D65, which means that you may get differing chrominance values (±~10) if you are comparing against a CIELUV/CIELCH colour illuminated by anything other than D65.

All functions return an object containing all modes of the result. (In getters, so don't worry, Chromatism doesn't calculate all the versions of the result when you use a function!)

For example, if you need a string containing the hex code for the colour result, simply use .hex:

var newColour = chromatism.invert("#5300FF").hex

chromatism's People

Contributors

andreipfeiffer avatar bdoss-shaw avatar graypegg avatar kale-io avatar mspalmer91 avatar tehshrike avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chromatism's Issues

Update readme with the refactor branch API changes

Should include both the upcoming changes to adapt (#19) and the fact that chaining is no longer supported.

I think that's the only API changes?

It would be good to note that ES modules/treeshaking is supported, for the browser-serving folks like me who are toolbox-module-averse.

Not as important, but we should also consider adding some really small example lines for each function for people to see and copy/paste. We can use jsmd to make sure that the examples stay accurate.

Broken images on documentation

Hi, for some reason all the pictures in the documentations are just broken, therefore the docs are almost useless 😭
Is it just the CSN server temporarily down or is it permanently not available anymore? 🤕

Screen Shot 2022-01-11 at 3 03 31 PM

Is there a demo site maybe as an alternative?

Refactoring to tiny functions

Goal: expose a bunch of tiny operation functions that people can bundle into their webapps without unnecessary byte-size-guilt

Work is happening in the refactor branch.

  • disconnect all the operation functions from each other so that each file can be accessed directly (#9)
  • make a basic test for each operation based on the current behavior (#13)
  • split all helpers out into their own modules (#14)
  • change CJS to ESM (#18, #20)
  • eliminate or make more efficient the search for a conversion path in convert-to-type.js (#25)

Longer shots that can wait for another version:

  • disconnect the conversion functions from each other and change operations to all return a single format, like XYZ
  • expose XYZ-to-whatever conversion functions that people can pull in individually as they need

Broken images README

Hi there!

Is there any interest in fixing those broken images located throughout the README?
annotation 2019-03-06 205852
I could help.

Incorrect hue scale

In the Scales + Colour Spaces section, it is stated that hue is in the range 0-365, while it should be 0-359.

Typings is incorrect

Hi,

The module is typed as exporting all function while it's a default import.

So import { brightness } from 'chromatism' or import * as chromatism from 'chromatism' does not throw typing error but does not work (chromatism_1.brightness is not a function).
But import chromatism from 'chromatism' does not pass type checking : error TS1192: Module '"~/node_modules/chromatism/index"' has no default export.

The following index.d.tsshould fix this :

declare namespace Chromatism {
     // All the code of the old `index.d.ts`
}

export default Chromatism;

Etienne.

Eliminate HSV->RGB or HSL->RGB conversion

HSV and HSL are very similar, and those conversions take a lot of code, so it's better not to keep both versions around.

Context: #24

When I tried removing either of the conversions, the output values changed enough that the tests wouldn't pass.

This implies that the conversions might be lossier than they should be, or one of them is less accurate than it should be.

hsl-->rgb,error is a little big

chromatism.convert( { h: 300, s: 100, l: 50 } ).rgb
//-->{r:253.47, g:0, b:254.49}-->Math.round()-->253,0,254
i want it can be {r:255, g:0, b:255}, after Math.round()

Weird result when doing Lab -> hsv with specific values

Hi,

Great library, I'm using this for color calculations in my home automation lighting setup. :)

Notably, I'm using Lab colorspace for tweaking the "color temperature" of my lights based on time of day (yeah, probably not the best way, but anyway). My lights expect hsv, so I'm doing the conversion between these using chromatism.

I noticed that at a particular time every evening, my lights would briefly flash bright white as the color temperature slowly adjusts towards an orange color. I started digging into this, and got this far as to have a consistent repro of the bug:

$ node
> require('chromatism').convert({"L":50,"a":10.3777,"b":56.74016}).hsv
{ h: 214.9506072233,
  s: -226243866.03568426,
  v: 0.00001916702582205332 }
> require('chromatism').convert({"L":50,"a":10.3777,"b":56.7401}).hsv
{ h: 42.32831591829547,
  s: 99.99979165015888,
  v: 61.46835916922344 }

Notice how the first example gives totally crazy values, but tweaking any of the input params just slightly in any direction gives me a "sane" color again. My guess would be a division by zero occurring somewhere in chromatism. Converting to RGB (instead of HSV) works fine with these input parameters.

want use @3.02

'package.json' version is 3.0.0, i want use @3.0.2, but how to install it?

Minification is cool

Hey there,

If you could run your dist file through a minifier like uglify or something, it would be great for those sensitive about performance. There are a few 20+ line sections of blank lines and space that could be saved. Right now your dist file is almost twice as big as tinycolor's. 'Twas just a tip if you're trying to bring more users to depend on your library.

Thanks for the great work

invert is broken when r/g/b is 0

invert('#000000').hex should give #FFFFFF but gives #000000, similarly
invert('#EE00EE').hex should give #11FF11 but gives #110011

ES Modules

Would you consider switching the code from CommonJS to ES Modules and exposing an entry point via pkg.module? That would allow my bundler to pull in just the exposed functions that I actually use when I want to use this library in the browser.

You would still expose a UMD or CJS entry point via main, this would just be a help to users targeting the browser.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.