Skip to content

Feature: pass dark/light color codes for bw option #3

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

Merged
merged 8 commits into from
Nov 7, 2017
34 changes: 32 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@ const invert = require('invert-color');

- **`color`** : `String|Array|Object`
Color in HEX string, RGB array or RGB object to be inverted.
- **`bw`** : `Boolean`
Optional. A boolean value indicating whether the output should be amplified to black (`#000000`) or white (`#ffffff`), according to the luminance of the original color.
- **`bw`** : `Boolean|Object`
Optional. A boolean value indicating whether the output should be amplified to black (`#000000`) or white (`#ffffff`), according to the luminance of the original color.
When it's an object, it should be shaped like `{ black: String?, white: String? }`,
where `black` and `white` are expressed as HEX strings and will be used as target
amplified values. When any of them is missing, the default black/white will be assumed.


```js
Expand All @@ -36,6 +39,9 @@ invert('#282b35') // —> #d7d4ca
// amplify to black or white
invert('#282b35', true) // —> #ffffff

// amplify to custom black or white color
invert('#282b35', { black: '#3a3a3a', white: '#fafafa' }) // —> #fafafa

// input color as RGB array or object
invert([69, 191, 189]) // —> #ba4042
invert({ r: 249, g: 119, b: 121 }) // —> #068886
Expand All @@ -59,6 +65,30 @@ invert.asRgbObject('#fff') // —> { r: 0, g: 0, b: 0 }

This is useful in case, you need to create contrast (i.e. background vs foreground, for better readability). The animation at the top is a demonstration.

## Contributing

Clone original project (or fork and clone that):

```sh
git clone https://github.com/onury/invert-color.git
```

Install dependencies:

```sh
npm install
```

There's nothing to build. Run tests:

```sh
npm test
```

Add (failing) tests into [test/unit.spec.js](test/unit.spec.js) file.
Add implementation.
Pass tests.
Refactor and repeat.

## License

Expand Down
19 changes: 13 additions & 6 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,33 @@ function getLuminance(c) {
return 0.2126 * a[0] + 0.7152 * a[1] + 0.0722 * a[2];
}

function invertToBW(color, asArr) {
function invertToBW(color, bw, asArr) {
const defaultColors = {
black: '#000000',
white: '#ffffff',
};
const bwColors = (bw === true)
? defaultColors
: Object.assign({}, defaultColors, bw);
return getLuminance(color) > BW_TRESHOLD
? (asArr ? [0, 0, 0] : '#000000')
: (asArr ? [255, 255, 255] : '#ffffff');
? (asArr ? hexToRGB(bwColors.black) : bwColors.black)
: (asArr ? hexToRGB(bwColors.white) : bwColors.white);
}

function invert(color, bw) {
color = toRGB(color);
if (bw) return invertToBW(color);
if (bw) return invertToBW(color, bw);
return '#' + color.map(c => padz((255 - c).toString(16))).join('');
}

invert.asRgbArray = (color, bw) => {
color = toRGB(color);
return bw ? invertToBW(color, true) : color.map(c => 255 - c);
return bw ? invertToBW(color, bw, true) : color.map(c => 255 - c);
};

invert.asRgbObject = (color, bw) => {
color = toRGB(color);
return toObj(bw ? invertToBW(color, true) : color.map(c => 255 - c));
return toObj(bw ? invertToBW(color, bw, true) : color.map(c => 255 - c));
};


Expand Down
57 changes: 57 additions & 0 deletions test/unit.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,16 @@ describe('test: invert-color', () => {
const A_WHITE = [255, 255, 255];
const O_BLACK = { r: 0, g: 0, b: 0 };
const O_WHITE = { r: 255, g: 255, b: 255 };
const CUSTOM_BLACK = '#303030';
const CUSTOM_WHITE = '#fafafa';
const A_CUSTOM_BLACK = [48, 48, 48];
const O_CUSTOM_BLACK = { r: 48, g: 48, b: 48 };
const A_CUSTOM_WHITE = [250, 250, 250];
const O_CUSTOM_WHITE = { r: 250, g: 250, b: 250 };
const CUSTOM_BW_COLORS = {
black: CUSTOM_BLACK,
white: CUSTOM_WHITE,
};

it('should invert & match photoshop inverted colors', () => {
// ORIGINAL PHOTOSHOP
Expand Down Expand Up @@ -102,6 +112,27 @@ describe('test: invert-color', () => {
expect(invert('#fff', true)).toEqual('#000000');
});

it('should invert to custom black and white colors', () => {
expect(invert('#631746', CUSTOM_BW_COLORS)).toEqual(CUSTOM_WHITE);
expect(invert('#655c42', CUSTOM_BW_COLORS)).toEqual(CUSTOM_WHITE);
expect(invert('#166528', CUSTOM_BW_COLORS)).toEqual(CUSTOM_WHITE);
expect(invert('#4c2946', CUSTOM_BW_COLORS)).toEqual(CUSTOM_WHITE);
expect(invert('#002d26', CUSTOM_BW_COLORS)).toEqual(CUSTOM_WHITE);
expect(invert('#e71398', CUSTOM_BW_COLORS)).toEqual(CUSTOM_BLACK);
expect(invert('#3ab3af', CUSTOM_BW_COLORS)).toEqual(CUSTOM_BLACK);
expect(invert('#76ff98', CUSTOM_BW_COLORS)).toEqual(CUSTOM_BLACK);
expect(invert('#bbb962', CUSTOM_BW_COLORS)).toEqual(CUSTOM_BLACK);
expect(invert('#52838b', CUSTOM_BW_COLORS)).toEqual(CUSTOM_BLACK);
expect(invert('#000', CUSTOM_BW_COLORS)).toEqual(CUSTOM_WHITE);
expect(invert('#fff', CUSTOM_BW_COLORS)).toEqual(CUSTOM_BLACK);
});

it('should support true/false/object for black and white parameter', () => {
expect(invert('#201395', true)).toEqual('#ffffff');
expect(invert('#201395', false)).toEqual('#dfec6a');
expect(invert('#201395', CUSTOM_BW_COLORS)).toEqual(CUSTOM_WHITE);
});

it('should invert to/from array/object to B/W', () => {
// this test also checks for object mutation

Expand All @@ -128,6 +159,32 @@ describe('test: invert-color', () => {
expect(invert.asRgbObject(O_WHITE, true)).toEqual(O_BLACK);
});

it('should invert to/from array/object to custom B/W', () => {
// this test also checks for object mutation

// hex as array
expect(invert.asRgbArray('#631746', CUSTOM_BW_COLORS)).toEqual(A_CUSTOM_WHITE);
expect(invert.asRgbArray('#655c42', CUSTOM_BW_COLORS)).toEqual(A_CUSTOM_WHITE);
expect(invert.asRgbArray('#e71398', CUSTOM_BW_COLORS)).toEqual(A_CUSTOM_BLACK);

// hex as object
expect(invert.asRgbObject('#4c2946', CUSTOM_BW_COLORS)).toEqual(O_CUSTOM_WHITE);
expect(invert.asRgbObject('#002d26', CUSTOM_BW_COLORS)).toEqual(O_CUSTOM_WHITE);
expect(invert.asRgbObject('#76ff98', CUSTOM_BW_COLORS)).toEqual(O_CUSTOM_BLACK);

// array as array
expect(invert.asRgbArray(A_WHITE, CUSTOM_BW_COLORS)).toEqual(A_CUSTOM_BLACK);
expect(invert.asRgbArray(A_BLACK, CUSTOM_BW_COLORS)).toEqual(A_CUSTOM_WHITE);

// object as array
expect(invert.asRgbArray(O_BLACK, CUSTOM_BW_COLORS)).toEqual(A_CUSTOM_WHITE);
expect(invert.asRgbArray(O_WHITE, CUSTOM_BW_COLORS)).toEqual(A_CUSTOM_BLACK);

// object as object
expect(invert.asRgbObject(O_BLACK, CUSTOM_BW_COLORS)).toEqual(O_CUSTOM_WHITE);
expect(invert.asRgbObject(O_WHITE, CUSTOM_BW_COLORS)).toEqual(O_CUSTOM_BLACK);
});

it('should modulo exceeding RGB comps', () => {
expect(invert([300, 300, 300])).toEqual('#2d2d2d');
expect(invert({ r: -46, g: -46, b: -46 })).toEqual('#2d2d2d');
Expand Down