Skip to content

Commit

Permalink
Optimize lab plugin size, fix docs and types for delta method
Browse files Browse the repository at this point in the history
  • Loading branch information
omgovich authored and Vlad Shilov committed Sep 23, 2021
1 parent 87da7d0 commit 3cb326d
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 43 deletions.
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -712,18 +712,17 @@ colord("#e60000").isReadable("#ffff47", { level: "AAA", size: "large" }); // tru
</details>

<details>
<summary><b><code>.delta(color2 = "#FFF", options?)</code></b> (<b>lab</b> plugin)</summary>
<summary><b><code>.delta(color2 = "#FFF")</code></b> (<b>lab</b> plugin)</summary>

Calculates the perceived color difference between two colors.
The difference calculated according to [Delta E2000](https://en.wikipedia.org/wiki/Color_difference#CIEDE2000).

Returns the normalized value in range from [0, 1], where 0 is the same color and 1 are completely different.
The return value is `0` if the colors are equal, `1` if they are entirely different.

```js
colord("#3296fa").delta("#197dc8") // 0.099
colord("#faf0c8").delta("#fff") // 0.148
colord("#afafaf").delta("#b4b4b4") // 0.014
colord("#000").delta("#fff") // 1.0
colord("#3296fa").delta("#197dc8"); // 0.099
colord("#faf0c8").delta("#ffffff"); // 0.148
colord("#afafaf").delta("#b4b4b4"); // 0.014
colord("#000000").delta("#ffffff"); // 1
```

</details>
Expand Down Expand Up @@ -842,11 +841,11 @@ colord("hwb(210 0% 60% / 50%)").toHex(); // "#00336680"
</details>

<details>
<summary><b><code>lab</code> (CIE LAB color space)</b> <i>1.5 KB</i></summary>
<summary><b><code>lab</code> (CIE LAB color space)</b> <i>1.4 KB</i></summary>

Adds support of [CIE LAB](https://en.wikipedia.org/wiki/CIELAB_color_space) color model. The conversion logic is ported from [CSS Color Module Level 4 Specification](https://www.w3.org/TR/css-color-4/#color-conversion-code).

Also plugin provides `.delta` method for perceived color difference calculations.
Also plugin provides `.delta` method for [perceived color difference calculations](https://en.wikipedia.org/wiki/Color_difference#CIEDE2000).

```js
import { colord, extend } from "colord";
Expand All @@ -857,8 +856,8 @@ extend([labPlugin]);
colord({ l: 53.24, a: 80.09, b: 67.2 }).toHex(); // "#ff0000"
colord("#ffffff").toLab(); // { l: 100, a: 0, b: 0, alpha: 1 }

colord("#afafaf").delta("#b4b4b4") // 0.014
colord("#000").delta("#fff") // 1.0
colord("#afafaf").delta("#b4b4b4"); // 0.014
colord("#000000").delta("#ffffff"); // 1
```

</details>
Expand Down
10 changes: 0 additions & 10 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,3 @@ export const ANGLE_UNITS: Record<string, number> = {
turn: 360,
rad: 360 / (Math.PI * 2),
};

/**
* Radians to degrees multiplier.
*/
export const rad2deg = 180 / Math.PI;

/**
* Degrees to radiants multiplier.
*/
export const deg2rad = Math.PI / 180;
32 changes: 13 additions & 19 deletions src/get/getPerceivedDifference.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { rad2deg, deg2rad } from "../constants";
import { LabaColor } from "../types";

/**
Expand All @@ -14,26 +13,22 @@ import { LabaColor } from "../types";
*
* | Delta E | Perception |
* |---------|----------------------------------------|
* | <= 1.0 | Not perceptible by human eyes |
* | 1 - 2 | Perceptible through close observation |
* | 2 - 10 | Perceptible at a glance |
* | <= 1.0 | Not perceptible by human eyes |
* | 1 - 2 | Perceptible through close observation |
* | 2 - 10 | Perceptible at a glance |
* | 11 - 49 | Colors are more similar than opposite |
* | 100 | Colors are exact opposite |
* | 100 | Colors are exact opposite |
*
* [Source](http://www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE2000.html)
* [Read about Delta E](https://zschuessler.github.io/DeltaE/learn/#toc-delta-e-2000)
*/
export function getDeltaE00(color1: LabaColor, color2: LabaColor): number {
/**
* kl - grafic arts = 1; textiles = 2;
* kl - unity factor;
* kh - weighting factor;
*/
const [kl, kc, kh] = [1, 1, 1];

const { l: l1, a: a1, b: b1 } = color1;
const { l: l2, a: a2, b: b2 } = color2;

const rad2deg = 180 / Math.PI;
const deg2rad = Math.PI / 180;

// dc -> delta c;
// ml -> median l;
const c1 = (a1 ** 2 + b1 ** 2) ** 0.5;
Expand All @@ -55,13 +50,8 @@ export function getDeltaE00(color1: LabaColor, color2: LabaColor): number {
let h1 = a11 === 0 && b1 === 0 ? 0 : Math.atan2(b1, a11) * rad2deg;
let h2 = a22 === 0 && b2 === 0 ? 0 : Math.atan2(b2, a22) * rad2deg;

if (h1 < 0) {
h1 += 360;
}

if (h2 < 0) {
h2 += 360;
}
if (h1 < 0) h1 += 360;
if (h2 < 0) h2 += 360;

let dh = h2 - h1;
const dhAbs = Math.abs(h2 - h1);
Expand Down Expand Up @@ -99,6 +89,10 @@ export function getDeltaE00(color1: LabaColor, color2: LabaColor): number {
const Rc = 2 * (c7 / (c7 + 25 ** 7)) ** 0.5;
const Rt = -Rc * Math.sin(deg2rad * 2 * dTheta);

const kl = 1; // 1 for graphic arts, 2 for textiles
const kc = 1; // unity factor
const kh = 1; // weighting factor

return (
((dL / kl / sL) ** 2 +
(dC / kc / sC) ** 2 +
Expand Down
7 changes: 4 additions & 3 deletions src/plugins/lab.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@ declare module "../colord" {
interface Colord {
/**
* Converts a color to CIELAB color space and returns an object.
* The object always includes `alpha` value [01].
* The object always includes `alpha` value [0, 1].
*/
toLab(): LabaColor;

/**
* Calculates the perceived color difference for two colors according to
* [Delta E2000](https://en.wikipedia.org/wiki/Color_difference#CIEDE2000).
* Returns a value in [0, 1] range.
*/
delta(color: AnyColor | Colord): number;
delta(color?: AnyColor | Colord): number;
}
}

Expand All @@ -29,7 +30,7 @@ const labPlugin: Plugin = (ColordClass, parsers): void => {
return roundLaba(rgbaToLaba(this.rgba));
};

ColordClass.prototype.delta = function (color) {
ColordClass.prototype.delta = function (color = "#FFF") {
const compared = color instanceof ColordClass ? color : new ColordClass(color);
const delta = getDeltaE00(this.toLab(), compared.toLab()) / 100;
return clamp(round(delta, 3));
Expand Down

0 comments on commit 3cb326d

Please sign in to comment.