omni-color 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +7 -0
- package/README.md +1042 -0
- package/dist/__test__/color-interop.test.d.ts +1 -0
- package/dist/__test__/color-interop.test.js +82 -0
- package/dist/__test__/comparison_culori.test.d.ts +1 -0
- package/dist/__test__/comparison_culori.test.js +169 -0
- package/dist/__test__/interop-chroma.test.d.ts +1 -0
- package/dist/__test__/interop-chroma.test.js +676 -0
- package/dist/__test__/interop-tinycolor.test.d.ts +1 -0
- package/dist/__test__/interop-tinycolor.test.js +499 -0
- package/dist/color/__test__/baseColor.test.d.ts +2 -0
- package/dist/color/__test__/baseColor.test.d.ts.map +1 -0
- package/dist/color/__test__/baseColor.test.js +34 -0
- package/dist/color/__test__/baseColor.test.js.map +1 -0
- package/dist/color/__test__/blank.d.ts +1 -0
- package/dist/color/__test__/blank.js +3 -0
- package/dist/color/__test__/color.test.d.ts +1 -0
- package/dist/color/__test__/color.test.js +1073 -0
- package/dist/color/__test__/colorSpaces.test.d.ts +1 -0
- package/dist/color/__test__/colorSpaces.test.js +69 -0
- package/dist/color/__test__/combinations.test.d.ts +1 -0
- package/dist/color/__test__/combinations.test.js +665 -0
- package/dist/color/__test__/conversions.test.d.ts +1 -0
- package/dist/color/__test__/conversions.test.js +719 -0
- package/dist/color/__test__/deltaE.test.d.ts +1 -0
- package/dist/color/__test__/deltaE.test.js +120 -0
- package/dist/color/__test__/formats.test.d.ts +1 -0
- package/dist/color/__test__/formats.test.js +514 -0
- package/dist/color/__test__/gradients.test.d.ts +1 -0
- package/dist/color/__test__/gradients.test.js +414 -0
- package/dist/color/__test__/harmonies.test.d.ts +1 -0
- package/dist/color/__test__/harmonies.test.js +676 -0
- package/dist/color/__test__/manipulations.test.d.ts +1 -0
- package/dist/color/__test__/manipulations.test.js +264 -0
- package/dist/color/__test__/names.test.d.ts +1 -0
- package/dist/color/__test__/names.test.js +67 -0
- package/dist/color/__test__/parse.test.d.ts +1 -0
- package/dist/color/__test__/parse.test.js +256 -0
- package/dist/color/__test__/random.test.d.ts +1 -0
- package/dist/color/__test__/random.test.js +262 -0
- package/dist/color/__test__/readability.test.d.ts +1 -0
- package/dist/color/__test__/readability.test.js +2596 -0
- package/dist/color/__test__/srgb.test.d.ts +1 -0
- package/dist/color/__test__/srgb.test.js +43 -0
- package/dist/color/__test__/swatch.test.d.ts +1 -0
- package/dist/color/__test__/swatch.test.js +267 -0
- package/dist/color/__test__/temperature.test.d.ts +1 -0
- package/dist/color/__test__/temperature.test.js +223 -0
- package/dist/color/__test__/utils.test.d.ts +1 -0
- package/dist/color/__test__/utils.test.js +409 -0
- package/dist/color/__test__/validations.test.d.ts +1 -0
- package/dist/color/__test__/validations.test.js +239 -0
- package/dist/color/color.constants.d.ts +4 -0
- package/dist/color/color.constants.d.ts.map +1 -0
- package/dist/color/color.constants.js +152 -0
- package/dist/color/color.constants.js.map +1 -0
- package/dist/color/color.consts.d.ts +4 -0
- package/dist/color/color.consts.js +152 -0
- package/dist/color/color.d.ts +788 -0
- package/dist/color/color.d.ts.map +1 -0
- package/dist/color/color.helpers.d.ts +6 -0
- package/dist/color/color.helpers.js +4 -0
- package/dist/color/color.js +919 -0
- package/dist/color/color.js.map +1 -0
- package/dist/color/colorSpaces.d.ts +15 -0
- package/dist/color/colorSpaces.js +127 -0
- package/dist/color/combinations.d.ts +45 -0
- package/dist/color/combinations.js +562 -0
- package/dist/color/conversions.d.ts +16 -0
- package/dist/color/conversions.d.ts.map +1 -0
- package/dist/color/conversions.js +705 -0
- package/dist/color/conversions.js.map +1 -0
- package/dist/color/deltaE.d.ts +59 -0
- package/dist/color/deltaE.js +110 -0
- package/dist/color/formats.d.ts +128 -0
- package/dist/color/formats.d.ts.map +1 -0
- package/dist/color/formats.js +153 -0
- package/dist/color/formats.js.map +1 -0
- package/dist/color/gradients.d.ts +49 -0
- package/dist/color/gradients.js +672 -0
- package/dist/color/harmonies.d.ts +18 -0
- package/dist/color/harmonies.js +128 -0
- package/dist/color/manipulations.d.ts +29 -0
- package/dist/color/manipulations.js +106 -0
- package/dist/color/names.d.ts +38 -0
- package/dist/color/names.js +108 -0
- package/dist/color/parse.d.ts +2 -0
- package/dist/color/parse.js +437 -0
- package/dist/color/random.d.ts +30 -0
- package/dist/color/random.js +65 -0
- package/dist/color/readability.d.ts +53 -0
- package/dist/color/readability.js +284 -0
- package/dist/color/srgb.d.ts +8 -0
- package/dist/color/srgb.js +33 -0
- package/dist/color/swatch.d.ts +49 -0
- package/dist/color/swatch.js +118 -0
- package/dist/color/temperature.d.ts +26 -0
- package/dist/color/temperature.js +141 -0
- package/dist/color/utils.d.ts +49 -0
- package/dist/color/utils.d.ts.map +1 -0
- package/dist/color/utils.js +104 -0
- package/dist/color/utils.js.map +1 -0
- package/dist/color/validations.d.ts +2 -0
- package/dist/color/validations.d.ts.map +1 -0
- package/dist/color/validations.js +178 -0
- package/dist/color/validations.js.map +1 -0
- package/dist/demo/src/AppFooter.d.ts +1 -0
- package/dist/demo/src/AppFooter.js +4 -0
- package/dist/demo/src/AppHeader.d.ts +5 -0
- package/dist/demo/src/AppHeader.js +6 -0
- package/dist/demo/src/components/Card.d.ts +9 -0
- package/dist/demo/src/components/Card.js +9 -0
- package/dist/demo/src/components/Chip.d.ts +21 -0
- package/dist/demo/src/components/Chip.js +23 -0
- package/dist/demo/src/components/ColorBox.d.ts +16 -0
- package/dist/demo/src/components/ColorBox.js +45 -0
- package/dist/demo/src/components/ColorInfoCard.d.ts +7 -0
- package/dist/demo/src/components/ColorInfoCard.js +50 -0
- package/dist/demo/src/components/ExpandableCodeSnippet.d.ts +5 -0
- package/dist/demo/src/components/ExpandableCodeSnippet.js +17 -0
- package/dist/demo/src/components/Icon.d.ts +11 -0
- package/dist/demo/src/components/Icon.js +50 -0
- package/dist/demo/src/components/Icon.types.d.ts +14 -0
- package/dist/demo/src/components/Icon.types.js +15 -0
- package/dist/demo/src/components/SectionContainer.d.ts +10 -0
- package/dist/demo/src/components/SectionContainer.js +12 -0
- package/dist/demo/src/components/VSpace.d.ts +5 -0
- package/dist/demo/src/components/VSpace.js +4 -0
- package/dist/demo/src/components/inputs/Checkbox.d.ts +7 -0
- package/dist/demo/src/components/inputs/Checkbox.js +4 -0
- package/dist/demo/src/components/inputs/InputGroup.d.ts +6 -0
- package/dist/demo/src/components/inputs/InputGroup.js +4 -0
- package/dist/demo/src/components/inputs/NumberInput.d.ts +10 -0
- package/dist/demo/src/components/inputs/NumberInput.js +8 -0
- package/dist/demo/src/components/inputs/Select.d.ts +12 -0
- package/dist/demo/src/components/inputs/Select.js +6 -0
- package/dist/demo/src/components/inputs/Slider.d.ts +10 -0
- package/dist/demo/src/components/inputs/Slider.js +4 -0
- package/dist/demo/src/components/utils.d.ts +17 -0
- package/dist/demo/src/components/utils.js +24 -0
- package/dist/demo/src/demo/ColorDemo.d.ts +1 -0
- package/dist/demo/src/demo/ColorDemo.js +45 -0
- package/dist/demo/src/demo/ColorHarmonyDemo.d.ts +6 -0
- package/dist/demo/src/demo/ColorHarmonyDemo.js +18 -0
- package/dist/demo/src/demo/ColorInfo.d.ts +6 -0
- package/dist/demo/src/demo/ColorInfo.js +14 -0
- package/dist/demo/src/demo/ColorInput.d.ts +7 -0
- package/dist/demo/src/demo/ColorInput.js +58 -0
- package/dist/demo/src/demo/ColorManipulationDemo.d.ts +6 -0
- package/dist/demo/src/demo/ColorManipulationDemo.js +63 -0
- package/dist/demo/src/demo/ColorSwatch.d.ts +13 -0
- package/dist/demo/src/demo/ColorSwatch.js +15 -0
- package/dist/demo/src/demo/ReadabilityDemo.d.ts +6 -0
- package/dist/demo/src/demo/ReadabilityDemo.js +24 -0
- package/dist/demo/src/demo/combinations/AverageColorsOptionInputs.d.ts +7 -0
- package/dist/demo/src/demo/combinations/AverageColorsOptionInputs.js +7 -0
- package/dist/demo/src/demo/combinations/BlendColorsOptionInputs.d.ts +7 -0
- package/dist/demo/src/demo/combinations/BlendColorsOptionInputs.js +13 -0
- package/dist/demo/src/demo/combinations/ColorCombinationDemo.d.ts +6 -0
- package/dist/demo/src/demo/combinations/ColorCombinationDemo.js +78 -0
- package/dist/demo/src/demo/combinations/MixColorsOptionInputs.d.ts +7 -0
- package/dist/demo/src/demo/combinations/MixColorsOptionInputs.js +10 -0
- package/dist/demo/src/demo/combinations/colorCombinationDemo.consts.d.ts +4 -0
- package/dist/demo/src/demo/combinations/colorCombinationDemo.consts.js +12 -0
- package/dist/demo/src/demo/gradients/GradientOptionInputs.d.ts +10 -0
- package/dist/demo/src/demo/gradients/GradientOptionInputs.js +42 -0
- package/dist/demo/src/demo/gradients/GradientThroughCard.d.ts +6 -0
- package/dist/demo/src/demo/gradients/GradientThroughCard.js +50 -0
- package/dist/demo/src/demo/gradients/GradientToCard.d.ts +6 -0
- package/dist/demo/src/demo/gradients/GradientToCard.js +54 -0
- package/dist/demo/src/demo/gradients/GradientsDemo.d.ts +6 -0
- package/dist/demo/src/demo/gradients/GradientsDemo.js +6 -0
- package/dist/demo/src/demo/gradients/gradientOptions.consts.d.ts +3 -0
- package/dist/demo/src/demo/gradients/gradientOptions.consts.js +16 -0
- package/dist/demo/src/demo/palette/ColorPaletteDemo.d.ts +6 -0
- package/dist/demo/src/demo/palette/ColorPaletteDemo.js +26 -0
- package/dist/demo/src/demo/palette/PaletteGenerationOptions.d.ts +8 -0
- package/dist/demo/src/demo/palette/PaletteGenerationOptions.js +53 -0
- package/dist/demo/src/demo/palette/PaletteHarmonyOptions.d.ts +7 -0
- package/dist/demo/src/demo/palette/PaletteHarmonyOptions.js +5 -0
- package/dist/demo/src/main.d.ts +1 -0
- package/dist/demo/src/main.js +14 -0
- package/dist/demo/src/pages/DemoPage.d.ts +1 -0
- package/dist/demo/src/pages/DemoPage.js +28 -0
- package/dist/demo/src/pages/PlaygroundPage.d.ts +1 -0
- package/dist/demo/src/pages/PlaygroundPage.js +24 -0
- package/dist/demo/src/playground/Playground.d.ts +1 -0
- package/dist/demo/src/playground/Playground.js +42 -0
- package/dist/demo/src/playground/playgroundUtils.d.ts +16 -0
- package/dist/demo/src/playground/playgroundUtils.js +202 -0
- package/dist/demo/src/seo/PageHead.d.ts +9 -0
- package/dist/demo/src/seo/PageHead.js +76 -0
- package/dist/demo/src/seo/StructuredData.d.ts +6 -0
- package/dist/demo/src/seo/StructuredData.js +13 -0
- package/dist/demo/src/toast/ToastProvider.d.ts +2 -0
- package/dist/demo/src/toast/ToastProvider.js +62 -0
- package/dist/demo/src/toast/index.d.ts +2 -0
- package/dist/demo/src/toast/index.js +2 -0
- package/dist/demo/src/toast/toastBus.d.ts +13 -0
- package/dist/demo/src/toast/toastBus.js +27 -0
- package/dist/index.d.ts +1233 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5235 -0
- package/dist/index.js.map +1 -0
- package/dist/palette/__test__/palette.test.d.ts +1 -0
- package/dist/palette/__test__/palette.test.js +397 -0
- package/dist/palette/palette.d.ts +41 -0
- package/dist/palette/palette.js +126 -0
- package/dist/src/__test__/interop-chroma.test.d.ts +1 -0
- package/dist/src/__test__/interop-chroma.test.js +673 -0
- package/dist/src/__test__/interop-tinycolor.test.d.ts +1 -0
- package/dist/src/__test__/interop-tinycolor.test.js +499 -0
- package/dist/src/color/__test__/color.test.d.ts +1 -0
- package/dist/src/color/__test__/color.test.js +1071 -0
- package/dist/src/color/__test__/colorSpaces.test.d.ts +1 -0
- package/dist/src/color/__test__/colorSpaces.test.js +69 -0
- package/dist/src/color/__test__/combinations.test.d.ts +1 -0
- package/dist/src/color/__test__/combinations.test.js +665 -0
- package/dist/src/color/__test__/conversions.test.d.ts +1 -0
- package/dist/src/color/__test__/conversions.test.js +719 -0
- package/dist/src/color/__test__/deltaE.test.d.ts +1 -0
- package/dist/src/color/__test__/deltaE.test.js +120 -0
- package/dist/src/color/__test__/formats.test.d.ts +1 -0
- package/dist/src/color/__test__/formats.test.js +470 -0
- package/dist/src/color/__test__/gradients.test.d.ts +1 -0
- package/dist/src/color/__test__/gradients.test.js +414 -0
- package/dist/src/color/__test__/harmonies.test.d.ts +1 -0
- package/dist/src/color/__test__/harmonies.test.js +734 -0
- package/dist/src/color/__test__/manipulations.test.d.ts +1 -0
- package/dist/src/color/__test__/manipulations.test.js +264 -0
- package/dist/src/color/__test__/names.test.d.ts +1 -0
- package/dist/src/color/__test__/names.test.js +67 -0
- package/dist/src/color/__test__/parse.test.d.ts +1 -0
- package/dist/src/color/__test__/parse.test.js +251 -0
- package/dist/src/color/__test__/random.test.d.ts +1 -0
- package/dist/src/color/__test__/random.test.js +262 -0
- package/dist/src/color/__test__/readability.test.d.ts +1 -0
- package/dist/src/color/__test__/readability.test.js +2596 -0
- package/dist/src/color/__test__/swatch.test.d.ts +1 -0
- package/dist/src/color/__test__/swatch.test.js +267 -0
- package/dist/src/color/__test__/temperature.test.d.ts +1 -0
- package/dist/src/color/__test__/temperature.test.js +223 -0
- package/dist/src/color/__test__/utils.test.d.ts +1 -0
- package/dist/src/color/__test__/utils.test.js +409 -0
- package/dist/src/color/__test__/validations.test.d.ts +1 -0
- package/dist/src/color/__test__/validations.test.js +239 -0
- package/dist/src/color/color.consts.d.ts +4 -0
- package/dist/src/color/color.consts.js +152 -0
- package/dist/src/color/color.d.ts +775 -0
- package/dist/src/color/color.js +903 -0
- package/dist/src/color/colorSpaces.d.ts +15 -0
- package/dist/src/color/colorSpaces.js +127 -0
- package/dist/src/color/combinations.d.ts +45 -0
- package/dist/src/color/combinations.js +557 -0
- package/dist/src/color/conversions.d.ts +16 -0
- package/dist/src/color/conversions.js +705 -0
- package/dist/src/color/deltaE.d.ts +59 -0
- package/dist/src/color/deltaE.js +110 -0
- package/dist/src/color/formats.d.ts +126 -0
- package/dist/src/color/formats.js +150 -0
- package/dist/src/color/gradients.d.ts +49 -0
- package/dist/src/color/gradients.js +673 -0
- package/dist/src/color/harmonies.d.ts +18 -0
- package/dist/src/color/harmonies.js +129 -0
- package/dist/src/color/manipulations.d.ts +29 -0
- package/dist/src/color/manipulations.js +107 -0
- package/dist/src/color/names.d.ts +38 -0
- package/dist/src/color/names.js +108 -0
- package/dist/src/color/parse.d.ts +2 -0
- package/dist/src/color/parse.js +438 -0
- package/dist/src/color/random.d.ts +30 -0
- package/dist/src/color/random.js +65 -0
- package/dist/src/color/readability.d.ts +53 -0
- package/dist/src/color/readability.js +284 -0
- package/dist/src/color/swatch.d.ts +49 -0
- package/dist/src/color/swatch.js +117 -0
- package/dist/src/color/temperature.d.ts +26 -0
- package/dist/src/color/temperature.js +142 -0
- package/dist/src/color/utils.d.ts +57 -0
- package/dist/src/color/utils.js +142 -0
- package/dist/src/color/validations.d.ts +2 -0
- package/dist/src/color/validations.js +178 -0
- package/dist/src/index.d.ts +20 -0
- package/dist/src/index.js +2 -0
- package/dist/src/palette/__test__/palette.test.d.ts +1 -0
- package/dist/src/palette/__test__/palette.test.js +397 -0
- package/dist/src/palette/palette.d.ts +41 -0
- package/dist/src/palette/palette.js +127 -0
- package/dist/src/utils.d.ts +20 -0
- package/dist/src/utils.js +42 -0
- package/dist/utils.d.ts +20 -0
- package/dist/utils.js +42 -0
- package/package.json +96 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Color } from '../color';
|
|
2
|
+
import { getDeltaE } from '../deltaE';
|
|
3
|
+
describe('Delta E calculations', () => {
|
|
4
|
+
describe('getDeltaE', () => {
|
|
5
|
+
it('returns 0 for identical colors regardless of method', () => {
|
|
6
|
+
const neutral = new Color('#777777');
|
|
7
|
+
expect(getDeltaE(neutral, neutral, { method: 'CIE76' })).toBe(0);
|
|
8
|
+
expect(getDeltaE(neutral, neutral, { method: 'CIE94' })).toBe(0);
|
|
9
|
+
expect(getDeltaE(neutral, neutral, { method: 'CIEDE2000' })).toBe(0);
|
|
10
|
+
});
|
|
11
|
+
it('matches reference values for CIEDE2000', () => {
|
|
12
|
+
const firstPairA = new Color({ l: 50, a: 2.6772, b: -79.7751 });
|
|
13
|
+
const firstPairB = new Color({ l: 50, a: 0, b: -82.7485 });
|
|
14
|
+
expect(getDeltaE(firstPairA, firstPairB, { method: 'CIEDE2000' })).toBeCloseTo(0.721, 3);
|
|
15
|
+
const secondPairA = new Color({ l: 50, a: 3.1571, b: -77.2803 });
|
|
16
|
+
const secondPairB = new Color({ l: 50, a: 0, b: -82.7485 });
|
|
17
|
+
expect(getDeltaE(secondPairA, secondPairB, { method: 'CIEDE2000' })).toBeCloseTo(1.07197, 4);
|
|
18
|
+
const thirdPairA = new Color({ l: 50, a: 2.8361, b: -74.02 });
|
|
19
|
+
const thirdPairB = new Color({ l: 50, a: 0, b: -82.7485 });
|
|
20
|
+
expect(getDeltaE(thirdPairA, thirdPairB, { method: 'CIEDE2000' })).toBeCloseTo(1.42485, 4);
|
|
21
|
+
});
|
|
22
|
+
it('matches reference values for CIE94 and CIE76', () => {
|
|
23
|
+
const firstPairA = new Color({ l: 50, a: 2.6772, b: -79.7751 });
|
|
24
|
+
const firstPairB = new Color({ l: 50, a: 0, b: -82.7485 });
|
|
25
|
+
expect(getDeltaE(firstPairA, firstPairB, { method: 'CIE94' })).toBeCloseTo(0.7636577088674601, 6);
|
|
26
|
+
expect(getDeltaE(firstPairA, firstPairB, { method: 'CIE76' })).toBeCloseTo(1.619848449701395, 6);
|
|
27
|
+
const secondPairA = new Color({ l: 50, a: 3.1571, b: -77.2803 });
|
|
28
|
+
const secondPairB = new Color({ l: 50, a: 0, b: -82.7485 });
|
|
29
|
+
expect(getDeltaE(secondPairA, secondPairB, { method: 'CIE94' })).toBeCloseTo(1.069608018415056, 6);
|
|
30
|
+
expect(getDeltaE(secondPairA, secondPairB, { method: 'CIE76' })).toBeCloseTo(1.2429935639415082, 6);
|
|
31
|
+
const thirdPairA = new Color({ l: 50, a: 2.8361, b: -74.02 });
|
|
32
|
+
const thirdPairB = new Color({ l: 50, a: 0, b: -82.7485 });
|
|
33
|
+
expect(getDeltaE(thirdPairA, thirdPairB, { method: 'CIE94' })).toBeCloseTo(1.6500919264582965, 6);
|
|
34
|
+
expect(getDeltaE(thirdPairA, thirdPairB, { method: 'CIE76' })).toBeCloseTo(3.4337015012956535, 6);
|
|
35
|
+
});
|
|
36
|
+
it('handles hue wrapping and zero-chroma inputs correctly', () => {
|
|
37
|
+
const nearZeroHue = new Color({ l: 60, c: 20, h: 20 });
|
|
38
|
+
const nearFullHue = new Color({ l: 60, c: 20, h: 340 });
|
|
39
|
+
const grayscaleA = new Color({ l: 55, a: 0, b: 0 });
|
|
40
|
+
const grayscaleB = new Color({ l: 45, a: 0, b: 0 });
|
|
41
|
+
expect(getDeltaE(nearZeroHue, nearFullHue, { method: 'CIEDE2000' })).toBeCloseTo(9.2596, 4);
|
|
42
|
+
expect(getDeltaE(grayscaleA, grayscaleB, { method: 'CIEDE2000' })).toBeCloseTo(10.328990616488563, 6);
|
|
43
|
+
expect(getDeltaE(grayscaleA, grayscaleB, { method: 'CIE94' })).toBeCloseTo(10.329000048382673, 6);
|
|
44
|
+
expect(getDeltaE(grayscaleA, grayscaleB, { method: 'CIE76' })).toBeCloseTo(10.329000048407398, 6);
|
|
45
|
+
});
|
|
46
|
+
it('honors custom weighting factors for CIE94', () => {
|
|
47
|
+
const lighterRed = new Color('#ff6666');
|
|
48
|
+
const darkerRed = new Color('#aa0000');
|
|
49
|
+
const defaultWeighting = getDeltaE(lighterRed, darkerRed, { method: 'CIE94' });
|
|
50
|
+
const textilesWeighting = getDeltaE(lighterRed, darkerRed, {
|
|
51
|
+
method: 'CIE94',
|
|
52
|
+
cie94Options: { kL: 2, kC: 1, kH: 1.5 },
|
|
53
|
+
});
|
|
54
|
+
expect(defaultWeighting).toBeGreaterThan(textilesWeighting);
|
|
55
|
+
expect(defaultWeighting).toBeCloseTo(29.175, 3);
|
|
56
|
+
expect(textilesWeighting).toBeCloseTo(15.172, 3);
|
|
57
|
+
});
|
|
58
|
+
it('honors custom weighting factors for CIEDE2000', () => {
|
|
59
|
+
const lighterRed = new Color('#ff6666');
|
|
60
|
+
const darkerRed = new Color('#aa0000');
|
|
61
|
+
const defaultWeighting = getDeltaE(lighterRed, darkerRed, { method: 'CIEDE2000' });
|
|
62
|
+
const customWeighting = getDeltaE(lighterRed, darkerRed, {
|
|
63
|
+
method: 'CIEDE2000',
|
|
64
|
+
ciede2000Options: { kL: 2, kC: 1, kH: 1.5 },
|
|
65
|
+
});
|
|
66
|
+
const explicitDefaults = getDeltaE(lighterRed, darkerRed, {
|
|
67
|
+
method: 'CIEDE2000',
|
|
68
|
+
ciede2000Options: { kL: 1, kC: 1, kH: 1 },
|
|
69
|
+
});
|
|
70
|
+
expect(defaultWeighting).toBeCloseTo(29.2788, 4);
|
|
71
|
+
expect(customWeighting).toBeCloseTo(15.2694, 4);
|
|
72
|
+
expect(explicitDefaults).toBeCloseTo(defaultWeighting, 12);
|
|
73
|
+
});
|
|
74
|
+
it('supports comparing colors from different input spaces', () => {
|
|
75
|
+
const red = new Color('#ff0000');
|
|
76
|
+
const green = new Color({ h: 120, s: 100, l: 50 });
|
|
77
|
+
const yellow = new Color({ l: 97.607, a: -15.578, b: 93.585 });
|
|
78
|
+
expect(getDeltaE(red, green, { method: 'CIE76' })).toBeCloseTo(170.585, 2);
|
|
79
|
+
expect(getDeltaE(red, yellow, { method: 'CIE94' })).toBeCloseTo(59.1667, 3);
|
|
80
|
+
expect(getDeltaE(red, yellow, { method: 'CIEDE2000' })).toBeCloseTo(63.5875, 4);
|
|
81
|
+
});
|
|
82
|
+
it('throws for invalid methods in getDeltaE', () => {
|
|
83
|
+
const colorA = new Color({ l: 50, a: 2.6772, b: -79.7751 });
|
|
84
|
+
const colorB = new Color({ l: 50, a: 0, b: -82.7485 });
|
|
85
|
+
expect(() => getDeltaE(colorA, colorB, { method: 'INVALID' })).toThrow("Invalid 'method'");
|
|
86
|
+
});
|
|
87
|
+
it('uses CIEDE2000 by default', () => {
|
|
88
|
+
const red = new Color('#ff0000');
|
|
89
|
+
const almostRed = new Color('#ff0100');
|
|
90
|
+
expect(getDeltaE(red, almostRed)).toBeCloseTo(0.034, 3);
|
|
91
|
+
});
|
|
92
|
+
it('accepts alternate methods', () => {
|
|
93
|
+
const blue = new Color('rgb(0, 0, 255)');
|
|
94
|
+
const teal = new Color({ h: 180, s: 100, l: 50 });
|
|
95
|
+
expect(getDeltaE(blue, teal, { method: 'CIE76' })).toBeCloseTo(168.65, 2);
|
|
96
|
+
expect(getDeltaE(blue, teal, { method: 'CIE94' })).toBeCloseTo(74.762, 2);
|
|
97
|
+
});
|
|
98
|
+
it('accepts Colors created from different input shapes', () => {
|
|
99
|
+
const base = new Color('#336699');
|
|
100
|
+
const identical = new Color({ r: 51, g: 102, b: 153 });
|
|
101
|
+
const white = new Color('#ffffff');
|
|
102
|
+
expect(getDeltaE(base, identical)).toBe(0);
|
|
103
|
+
expect(getDeltaE(base, white, { method: 'CIE76' })).toBeCloseTo(66.644, 3);
|
|
104
|
+
});
|
|
105
|
+
it('is symmetric regardless of parameter order', () => {
|
|
106
|
+
const golden = new Color('#daa520');
|
|
107
|
+
const navy = new Color('#001f3f');
|
|
108
|
+
const forward = getDeltaE(golden, navy, { method: 'CIEDE2000' });
|
|
109
|
+
const reverse = getDeltaE(navy, golden, { method: 'CIEDE2000' });
|
|
110
|
+
expect(forward).toBeCloseTo(reverse, 12);
|
|
111
|
+
});
|
|
112
|
+
it('accepts mixed case method', () => {
|
|
113
|
+
const c1 = new Color('red');
|
|
114
|
+
const c2 = new Color('maroon');
|
|
115
|
+
const d1 = getDeltaE(c1, c2, { method: 'CIE94' });
|
|
116
|
+
const d2 = getDeltaE(c1, c2, { method: 'cie94' });
|
|
117
|
+
expect(d1).toBe(d2);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,470 @@
|
|
|
1
|
+
import { Color } from '../color';
|
|
2
|
+
import { cmykToString, colorToString, getColorFormatType, hslaToString, hslToString, hwbToString, labToString, lchToString, oklabToString, oklchToString, rgbaToString, rgbToString, } from '../formats';
|
|
3
|
+
describe('rgbToString', () => {
|
|
4
|
+
it('generates rgb strings', () => {
|
|
5
|
+
const black = new Color('#000000');
|
|
6
|
+
expect(rgbToString(black.toRGB())).toBe('rgb(0 0 0)');
|
|
7
|
+
expect(black.toRGBString()).toBe('rgb(0 0 0)');
|
|
8
|
+
const white = new Color('#ffffff');
|
|
9
|
+
expect(rgbToString(white.toRGB())).toBe('rgb(255 255 255)');
|
|
10
|
+
expect(white.toRGBString()).toBe('rgb(255 255 255)');
|
|
11
|
+
const gray = new Color('#808080');
|
|
12
|
+
expect(rgbToString(gray.toRGB())).toBe('rgb(128 128 128)');
|
|
13
|
+
expect(gray.toRGBString()).toBe('rgb(128 128 128)');
|
|
14
|
+
const red = new Color('#ff0000');
|
|
15
|
+
expect(rgbToString(red.toRGB())).toBe('rgb(255 0 0)');
|
|
16
|
+
expect(red.toRGBString()).toBe('rgb(255 0 0)');
|
|
17
|
+
const green = new Color('#00ff00');
|
|
18
|
+
expect(rgbToString(green.toRGB())).toBe('rgb(0 255 0)');
|
|
19
|
+
expect(green.toRGBString()).toBe('rgb(0 255 0)');
|
|
20
|
+
const blue = new Color('#0000ff');
|
|
21
|
+
expect(rgbToString(blue.toRGB())).toBe('rgb(0 0 255)');
|
|
22
|
+
expect(blue.toRGBString()).toBe('rgb(0 0 255)');
|
|
23
|
+
const yellow = new Color('#ffff00');
|
|
24
|
+
expect(rgbToString(yellow.toRGB())).toBe('rgb(255 255 0)');
|
|
25
|
+
expect(yellow.toRGBString()).toBe('rgb(255 255 0)');
|
|
26
|
+
const cyan = new Color('#00ffff');
|
|
27
|
+
expect(rgbToString(cyan.toRGB())).toBe('rgb(0 255 255)');
|
|
28
|
+
expect(cyan.toRGBString()).toBe('rgb(0 255 255)');
|
|
29
|
+
const magenta = new Color('#ff00ff');
|
|
30
|
+
expect(rgbToString(magenta.toRGB())).toBe('rgb(255 0 255)');
|
|
31
|
+
expect(magenta.toRGBString()).toBe('rgb(255 0 255)');
|
|
32
|
+
const custom = new Color('#abc123');
|
|
33
|
+
expect(rgbToString(custom.toRGB())).toBe('rgb(171 193 35)');
|
|
34
|
+
expect(custom.toRGBString()).toBe('rgb(171 193 35)');
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
describe('rgbaToString', () => {
|
|
38
|
+
it('generates rgba strings', () => {
|
|
39
|
+
const transparentBlack = new Color('#00000000');
|
|
40
|
+
expect(rgbaToString(transparentBlack.toRGBA())).toBe('rgb(0 0 0 / 0)');
|
|
41
|
+
expect(transparentBlack.toRGBAString()).toBe('rgb(0 0 0 / 0)');
|
|
42
|
+
const opaqueWhite = new Color('#ffffffff');
|
|
43
|
+
expect(rgbaToString(opaqueWhite.toRGBA())).toBe('rgb(255 255 255 / 1)');
|
|
44
|
+
expect(opaqueWhite.toRGBAString()).toBe('rgb(255 255 255 / 1)');
|
|
45
|
+
const gray = new Color('#80808080');
|
|
46
|
+
expect(rgbaToString(gray.toRGBA())).toBe('rgb(128 128 128 / 0.502)');
|
|
47
|
+
expect(gray.toRGBAString()).toBe('rgb(128 128 128 / 0.502)');
|
|
48
|
+
const red = new Color('#ff000080');
|
|
49
|
+
expect(rgbaToString(red.toRGBA())).toBe('rgb(255 0 0 / 0.502)');
|
|
50
|
+
expect(red.toRGBAString()).toBe('rgb(255 0 0 / 0.502)');
|
|
51
|
+
const green = new Color('#00ff007f');
|
|
52
|
+
expect(rgbaToString(green.toRGBA())).toBe('rgb(0 255 0 / 0.498)');
|
|
53
|
+
expect(green.toRGBAString()).toBe('rgb(0 255 0 / 0.498)');
|
|
54
|
+
const blue = new Color('#0000ff40');
|
|
55
|
+
expect(rgbaToString(blue.toRGBA())).toBe('rgb(0 0 255 / 0.251)');
|
|
56
|
+
expect(blue.toRGBAString()).toBe('rgb(0 0 255 / 0.251)');
|
|
57
|
+
const yellow = new Color('#ffff00c0');
|
|
58
|
+
expect(rgbaToString(yellow.toRGBA())).toBe('rgb(255 255 0 / 0.753)');
|
|
59
|
+
expect(yellow.toRGBAString()).toBe('rgb(255 255 0 / 0.753)');
|
|
60
|
+
const cyan = new Color('#00ffff20');
|
|
61
|
+
expect(rgbaToString(cyan.toRGBA())).toBe('rgb(0 255 255 / 0.125)');
|
|
62
|
+
expect(cyan.toRGBAString()).toBe('rgb(0 255 255 / 0.125)');
|
|
63
|
+
const magenta = new Color('#ff00ff99');
|
|
64
|
+
expect(rgbaToString(magenta.toRGBA())).toBe('rgb(255 0 255 / 0.6)');
|
|
65
|
+
expect(magenta.toRGBAString()).toBe('rgb(255 0 255 / 0.6)');
|
|
66
|
+
const custom = new Color('#abc123d6');
|
|
67
|
+
expect(rgbaToString(custom.toRGBA())).toBe('rgb(171 193 35 / 0.839)');
|
|
68
|
+
expect(custom.toRGBAString()).toBe('rgb(171 193 35 / 0.839)');
|
|
69
|
+
});
|
|
70
|
+
it('rounds alpha to three decimals', () => {
|
|
71
|
+
expect(rgbaToString({ r: 1, g: 2, b: 3, a: 0.123456 })).toBe('rgb(1 2 3 / 0.123)');
|
|
72
|
+
expect(rgbaToString({ r: 1, g: 2, b: 3, a: 0.98765 })).toBe('rgb(1 2 3 / 0.988)');
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
describe('hslToString', () => {
|
|
76
|
+
it('generates hsl strings', () => {
|
|
77
|
+
const black = new Color('#000000');
|
|
78
|
+
expect(hslToString(black.toHSL())).toBe('hsl(0 0% 0%)');
|
|
79
|
+
expect(black.toHSLString()).toBe('hsl(0 0% 0%)');
|
|
80
|
+
const white = new Color('#ffffff');
|
|
81
|
+
expect(hslToString(white.toHSL())).toBe('hsl(0 0% 100%)');
|
|
82
|
+
expect(white.toHSLString()).toBe('hsl(0 0% 100%)');
|
|
83
|
+
const gray = new Color('#808080');
|
|
84
|
+
expect(hslToString(gray.toHSL())).toBe('hsl(0 0% 50.196%)');
|
|
85
|
+
expect(gray.toHSLString()).toBe('hsl(0 0% 50.196%)');
|
|
86
|
+
const red = new Color('#ff0000');
|
|
87
|
+
expect(hslToString(red.toHSL())).toBe('hsl(0 100% 50%)');
|
|
88
|
+
expect(red.toHSLString()).toBe('hsl(0 100% 50%)');
|
|
89
|
+
const green = new Color('#00ff00');
|
|
90
|
+
expect(hslToString(green.toHSL())).toBe('hsl(120 100% 50%)');
|
|
91
|
+
expect(green.toHSLString()).toBe('hsl(120 100% 50%)');
|
|
92
|
+
const blue = new Color('#0000ff');
|
|
93
|
+
expect(hslToString(blue.toHSL())).toBe('hsl(240 100% 50%)');
|
|
94
|
+
expect(blue.toHSLString()).toBe('hsl(240 100% 50%)');
|
|
95
|
+
const yellow = new Color('#ffff00');
|
|
96
|
+
expect(hslToString(yellow.toHSL())).toBe('hsl(60 100% 50%)');
|
|
97
|
+
expect(yellow.toHSLString()).toBe('hsl(60 100% 50%)');
|
|
98
|
+
const cyan = new Color('#00ffff');
|
|
99
|
+
expect(hslToString(cyan.toHSL())).toBe('hsl(180 100% 50%)');
|
|
100
|
+
expect(cyan.toHSLString()).toBe('hsl(180 100% 50%)');
|
|
101
|
+
const magenta = new Color('#ff00ff');
|
|
102
|
+
expect(hslToString(magenta.toHSL())).toBe('hsl(300 100% 50%)');
|
|
103
|
+
expect(magenta.toHSLString()).toBe('hsl(300 100% 50%)');
|
|
104
|
+
const custom = new Color('#abc123');
|
|
105
|
+
expect(hslToString(custom.toHSL())).toBe('hsl(68.354 69.298% 44.706%)');
|
|
106
|
+
expect(custom.toHSLString()).toBe('hsl(68.354 69.298% 44.706%)');
|
|
107
|
+
});
|
|
108
|
+
it('rounds component values to three decimals', () => {
|
|
109
|
+
expect(hslToString({ h: 123.4567, s: 50.5555, l: 10.1234 })).toBe('hsl(123.457 50.556% 10.123%)');
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
describe('hslaToString', () => {
|
|
113
|
+
it('generates hsla strings', () => {
|
|
114
|
+
const transparentBlack = new Color('#00000000');
|
|
115
|
+
expect(hslaToString(transparentBlack.toHSLA())).toBe('hsl(0 0% 0% / 0)');
|
|
116
|
+
expect(transparentBlack.toHSLAString()).toBe('hsl(0 0% 0% / 0)');
|
|
117
|
+
const opaqueWhite = new Color('#ffffffff');
|
|
118
|
+
expect(hslaToString(opaqueWhite.toHSLA())).toBe('hsl(0 0% 100% / 1)');
|
|
119
|
+
expect(opaqueWhite.toHSLAString()).toBe('hsl(0 0% 100% / 1)');
|
|
120
|
+
const gray = new Color('#80808080');
|
|
121
|
+
expect(hslaToString(gray.toHSLA())).toBe('hsl(0 0% 50.196% / 0.502)');
|
|
122
|
+
expect(gray.toHSLAString()).toBe('hsl(0 0% 50.196% / 0.502)');
|
|
123
|
+
const red = new Color('#ff000080');
|
|
124
|
+
expect(hslaToString(red.toHSLA())).toBe('hsl(0 100% 50% / 0.502)');
|
|
125
|
+
expect(red.toHSLAString()).toBe('hsl(0 100% 50% / 0.502)');
|
|
126
|
+
const green = new Color('#00ff007f');
|
|
127
|
+
expect(hslaToString(green.toHSLA())).toBe('hsl(120 100% 50% / 0.498)');
|
|
128
|
+
expect(green.toHSLAString()).toBe('hsl(120 100% 50% / 0.498)');
|
|
129
|
+
const blue = new Color('#0000ff40');
|
|
130
|
+
expect(hslaToString(blue.toHSLA())).toBe('hsl(240 100% 50% / 0.251)');
|
|
131
|
+
expect(blue.toHSLAString()).toBe('hsl(240 100% 50% / 0.251)');
|
|
132
|
+
const yellow = new Color('#ffff00c0');
|
|
133
|
+
expect(hslaToString(yellow.toHSLA())).toBe('hsl(60 100% 50% / 0.753)');
|
|
134
|
+
expect(yellow.toHSLAString()).toBe('hsl(60 100% 50% / 0.753)');
|
|
135
|
+
const cyan = new Color('#00ffff20');
|
|
136
|
+
expect(hslaToString(cyan.toHSLA())).toBe('hsl(180 100% 50% / 0.125)');
|
|
137
|
+
expect(cyan.toHSLAString()).toBe('hsl(180 100% 50% / 0.125)');
|
|
138
|
+
const magenta = new Color('#ff00ff99');
|
|
139
|
+
expect(hslaToString(magenta.toHSLA())).toBe('hsl(300 100% 50% / 0.6)');
|
|
140
|
+
expect(magenta.toHSLAString()).toBe('hsl(300 100% 50% / 0.6)');
|
|
141
|
+
const custom = new Color('#abc123d6');
|
|
142
|
+
expect(hslaToString(custom.toHSLA())).toBe('hsl(68.354 69.298% 44.706% / 0.839)');
|
|
143
|
+
expect(custom.toHSLAString()).toBe('hsl(68.354 69.298% 44.706% / 0.839)');
|
|
144
|
+
});
|
|
145
|
+
it('rounds hsla components to three decimals', () => {
|
|
146
|
+
expect(hslaToString({ h: 123.4567, s: 50.5555, l: 10.1234, a: 0.98765 })).toBe('hsl(123.457 50.556% 10.123% / 0.988)');
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
describe('colorToString', () => {
|
|
150
|
+
it('generates color() strings in different spaces', () => {
|
|
151
|
+
const opaque = new Color('#336699');
|
|
152
|
+
const translucent = new Color('#336699cc');
|
|
153
|
+
expect(colorToString(opaque.toRGBA())).toBe('color(srgb 0.2 0.4 0.6)');
|
|
154
|
+
expect(colorToString(translucent.toRGBA())).toBe('color(srgb 0.2 0.4 0.6 / 0.8)');
|
|
155
|
+
expect(colorToString(translucent.toRGBA(), { space: 'display-p3' })).toBe('color(display-p3 0.249851 0.39524 0.584034 / 0.8)');
|
|
156
|
+
expect(colorToString(opaque.toRGBA(), { space: 'rec2020' })).toBe('color(rec2020 0.250128 0.336705 0.537794)');
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
describe('hwbToString', () => {
|
|
160
|
+
it('generates hwb strings', () => {
|
|
161
|
+
const black = new Color('#000000');
|
|
162
|
+
expect(hwbToString(black.toHWB())).toBe('hwb(0 0% 100%)');
|
|
163
|
+
expect(black.toHWBString()).toBe('hwb(0 0% 100%)');
|
|
164
|
+
expect(black.toHWBAString()).toBe('hwb(0 0% 100% / 1)');
|
|
165
|
+
const white = new Color('#ffffffff');
|
|
166
|
+
expect(hwbToString(white.toHWB())).toBe('hwb(0 100% 0%)');
|
|
167
|
+
expect(white.toHWBString()).toBe('hwb(0 100% 0%)');
|
|
168
|
+
expect(white.toHWBAString()).toBe('hwb(0 100% 0% / 1)');
|
|
169
|
+
const gray = new Color('#80808080');
|
|
170
|
+
expect(hwbToString(gray.toHWB())).toBe('hwb(0 50% 50%)');
|
|
171
|
+
expect(gray.toHWBString()).toBe('hwb(0 50% 50%)');
|
|
172
|
+
expect(gray.toHWBAString()).toBe('hwb(0 50% 50% / 0.502)');
|
|
173
|
+
const green = new Color('#00ff00');
|
|
174
|
+
expect(hwbToString(green.toHWB())).toBe('hwb(120 0% 0%)');
|
|
175
|
+
expect(green.toHWBString()).toBe('hwb(120 0% 0%)');
|
|
176
|
+
expect(green.toHWBAString()).toBe('hwb(120 0% 0% / 1)');
|
|
177
|
+
const custom = new Color('#abc123d6');
|
|
178
|
+
expect(hwbToString(custom.toHWB())).toBe('hwb(68.354 14% 24%)');
|
|
179
|
+
expect(custom.toHWBString()).toBe('hwb(68.354 14% 24%)');
|
|
180
|
+
expect(custom.toHWBAString()).toBe('hwb(68.354 14% 24% / 0.839)');
|
|
181
|
+
});
|
|
182
|
+
it('rounds hwb components to three decimals', () => {
|
|
183
|
+
expect(hwbToString({ h: 123.4567, w: 12.3456, b: 65.4321 })).toBe('hwb(123.457 12.346% 65.432%)');
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
describe('cmykToString', () => {
|
|
187
|
+
it('generates cmyk strings', () => {
|
|
188
|
+
const black = new Color('#000000');
|
|
189
|
+
expect(cmykToString(black.toCMYK())).toBe('device-cmyk(0% 0% 0% 100%)');
|
|
190
|
+
expect(black.toCMYKString()).toBe('device-cmyk(0% 0% 0% 100%)');
|
|
191
|
+
const white = new Color('#ffffff');
|
|
192
|
+
expect(cmykToString(white.toCMYK())).toBe('device-cmyk(0% 0% 0% 0%)');
|
|
193
|
+
expect(white.toCMYKString()).toBe('device-cmyk(0% 0% 0% 0%)');
|
|
194
|
+
const gray = new Color('#808080');
|
|
195
|
+
expect(cmykToString(gray.toCMYK())).toBe('device-cmyk(0% 0% 0% 50%)');
|
|
196
|
+
expect(gray.toCMYKString()).toBe('device-cmyk(0% 0% 0% 50%)');
|
|
197
|
+
const red = new Color('#ff0000');
|
|
198
|
+
expect(cmykToString(red.toCMYK())).toBe('device-cmyk(0% 100% 100% 0%)');
|
|
199
|
+
expect(red.toCMYKString()).toBe('device-cmyk(0% 100% 100% 0%)');
|
|
200
|
+
const green = new Color('#00ff00');
|
|
201
|
+
expect(cmykToString(green.toCMYK())).toBe('device-cmyk(100% 0% 100% 0%)');
|
|
202
|
+
expect(green.toCMYKString()).toBe('device-cmyk(100% 0% 100% 0%)');
|
|
203
|
+
const blue = new Color('#0000ff');
|
|
204
|
+
expect(cmykToString(blue.toCMYK())).toBe('device-cmyk(100% 100% 0% 0%)');
|
|
205
|
+
expect(blue.toCMYKString()).toBe('device-cmyk(100% 100% 0% 0%)');
|
|
206
|
+
const yellow = new Color('#ffff00');
|
|
207
|
+
expect(cmykToString(yellow.toCMYK())).toBe('device-cmyk(0% 0% 100% 0%)');
|
|
208
|
+
expect(yellow.toCMYKString()).toBe('device-cmyk(0% 0% 100% 0%)');
|
|
209
|
+
const cyan = new Color('#00ffff');
|
|
210
|
+
expect(cmykToString(cyan.toCMYK())).toBe('device-cmyk(100% 0% 0% 0%)');
|
|
211
|
+
expect(cyan.toCMYKString()).toBe('device-cmyk(100% 0% 0% 0%)');
|
|
212
|
+
const magenta = new Color('#ff00ff');
|
|
213
|
+
expect(cmykToString(magenta.toCMYK())).toBe('device-cmyk(0% 100% 0% 0%)');
|
|
214
|
+
expect(magenta.toCMYKString()).toBe('device-cmyk(0% 100% 0% 0%)');
|
|
215
|
+
const custom = new Color('#abc123');
|
|
216
|
+
expect(cmykToString(custom.toCMYK())).toBe('device-cmyk(11% 0% 82% 24%)');
|
|
217
|
+
expect(custom.toCMYKString()).toBe('device-cmyk(11% 0% 82% 24%)');
|
|
218
|
+
});
|
|
219
|
+
it('rounds cmyk components to three decimals', () => {
|
|
220
|
+
expect(cmykToString({ c: 12.3456, m: 0.9876, y: 54.321, k: 10.5555 })).toBe('device-cmyk(12.346% 0.988% 54.321% 10.556%)');
|
|
221
|
+
});
|
|
222
|
+
});
|
|
223
|
+
describe('labToString', () => {
|
|
224
|
+
it('generates lab strings', () => {
|
|
225
|
+
const black = new Color('#000000');
|
|
226
|
+
expect(labToString(black.toLAB())).toBe('lab(0% 0 0)');
|
|
227
|
+
expect(black.toLABString()).toBe('lab(0% 0 0)');
|
|
228
|
+
const white = new Color('#ffffff');
|
|
229
|
+
expect(labToString(white.toLAB())).toBe('lab(100% 0.005 -0.01)');
|
|
230
|
+
expect(white.toLABString()).toBe('lab(100% 0.005 -0.01)');
|
|
231
|
+
const gray = new Color('#808080');
|
|
232
|
+
expect(labToString(gray.toLAB())).toBe('lab(53.585% 0.003 -0.006)');
|
|
233
|
+
expect(gray.toLABString()).toBe('lab(53.585% 0.003 -0.006)');
|
|
234
|
+
const red = new Color('#ff0000');
|
|
235
|
+
expect(labToString(red.toLAB())).toBe('lab(53.233% 80.109 67.22)');
|
|
236
|
+
expect(red.toLABString()).toBe('lab(53.233% 80.109 67.22)');
|
|
237
|
+
const green = new Color('#00ff00');
|
|
238
|
+
expect(labToString(green.toLAB())).toBe('lab(87.737% -86.185 83.181)');
|
|
239
|
+
expect(green.toLABString()).toBe('lab(87.737% -86.185 83.181)');
|
|
240
|
+
const blue = new Color('#0000ff');
|
|
241
|
+
expect(labToString(blue.toLAB())).toBe('lab(32.303% 79.197 -107.864)');
|
|
242
|
+
expect(blue.toLABString()).toBe('lab(32.303% 79.197 -107.864)');
|
|
243
|
+
const custom = new Color('#abc123');
|
|
244
|
+
expect(labToString(custom.toLAB())).toBe('lab(74.138% -26.201 69.136)');
|
|
245
|
+
expect(custom.toLABString()).toBe('lab(74.138% -26.201 69.136)');
|
|
246
|
+
});
|
|
247
|
+
it('rounds lab components to three decimals', () => {
|
|
248
|
+
expect(labToString({ l: 12.3456, a: -7.654321, b: 123.4567 })).toBe('lab(12.346% -7.654 123.457)');
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
describe('lchToString', () => {
|
|
252
|
+
it('generates lch strings', () => {
|
|
253
|
+
const black = new Color('#000000');
|
|
254
|
+
expect(lchToString(black.toLCH())).toBe('lch(0% 0 0)');
|
|
255
|
+
expect(black.toLCHString()).toBe('lch(0% 0 0)');
|
|
256
|
+
const white = new Color('#ffffff');
|
|
257
|
+
expect(lchToString(white.toLCH())).toBe('lch(100% 0.012 296.813)');
|
|
258
|
+
expect(white.toLCHString()).toBe('lch(100% 0.012 296.813)');
|
|
259
|
+
const gray = new Color('#808080');
|
|
260
|
+
expect(lchToString(gray.toLCH())).toBe('lch(53.585% 0.007 296.813)');
|
|
261
|
+
expect(gray.toLCHString()).toBe('lch(53.585% 0.007 296.813)');
|
|
262
|
+
const red = new Color('#ff0000');
|
|
263
|
+
expect(lchToString(red.toLCH())).toBe('lch(53.233% 104.576 40)');
|
|
264
|
+
expect(red.toLCHString()).toBe('lch(53.233% 104.576 40)');
|
|
265
|
+
const green = new Color('#00ff00');
|
|
266
|
+
expect(lchToString(green.toLCH())).toBe('lch(87.737% 119.779 136.016)');
|
|
267
|
+
expect(green.toLCHString()).toBe('lch(87.737% 119.779 136.016)');
|
|
268
|
+
const blue = new Color('#0000ff');
|
|
269
|
+
expect(lchToString(blue.toLCH())).toBe('lch(32.303% 133.816 306.287)');
|
|
270
|
+
expect(blue.toLCHString()).toBe('lch(32.303% 133.816 306.287)');
|
|
271
|
+
const yellow = new Color('#ffff00');
|
|
272
|
+
expect(lchToString(yellow.toLCH())).toBe('lch(97.138% 96.91 102.852)');
|
|
273
|
+
expect(yellow.toLCHString()).toBe('lch(97.138% 96.91 102.852)');
|
|
274
|
+
const cyan = new Color('#00ffff');
|
|
275
|
+
expect(lchToString(cyan.toLCH())).toBe('lch(91.117% 50.115 196.386)');
|
|
276
|
+
expect(cyan.toLCHString()).toBe('lch(91.117% 50.115 196.386)');
|
|
277
|
+
const magenta = new Color('#ff00ff');
|
|
278
|
+
expect(lchToString(magenta.toLCH())).toBe('lch(60.32% 115.567 328.233)');
|
|
279
|
+
expect(magenta.toLCHString()).toBe('lch(60.32% 115.567 328.233)');
|
|
280
|
+
const custom = new Color('#abc123');
|
|
281
|
+
expect(lchToString(custom.toLCH())).toBe('lch(74.138% 73.934 110.756)');
|
|
282
|
+
expect(custom.toLCHString()).toBe('lch(74.138% 73.934 110.756)');
|
|
283
|
+
});
|
|
284
|
+
it('rounds lch components to three decimals', () => {
|
|
285
|
+
expect(lchToString({ l: 12.3456, c: 7.654321, h: 123.4567 })).toBe('lch(12.346% 7.654 123.457)');
|
|
286
|
+
});
|
|
287
|
+
});
|
|
288
|
+
describe('oklabToString', () => {
|
|
289
|
+
it('generates oklab strings', () => {
|
|
290
|
+
const black = new Color('#000000');
|
|
291
|
+
expect(oklabToString(black.toOKLAB())).toBe('oklab(0 0 0)');
|
|
292
|
+
expect(black.toOKLABString()).toBe('oklab(0 0 0)');
|
|
293
|
+
const white = new Color('#ffffff');
|
|
294
|
+
expect(oklabToString(white.toOKLAB())).toBe('oklab(1 0 0)');
|
|
295
|
+
expect(white.toOKLABString()).toBe('oklab(1 0 0)');
|
|
296
|
+
const gray = new Color('#808080');
|
|
297
|
+
expect(oklabToString(gray.toOKLAB())).toBe('oklab(0.599871 0 0)');
|
|
298
|
+
expect(gray.toOKLABString()).toBe('oklab(0.599871 0 0)');
|
|
299
|
+
const red = new Color('#ff0000');
|
|
300
|
+
expect(oklabToString(red.toOKLAB())).toBe('oklab(0.627955 0.224863 0.125846)');
|
|
301
|
+
expect(red.toOKLABString()).toBe('oklab(0.627955 0.224863 0.125846)');
|
|
302
|
+
});
|
|
303
|
+
it('rounds oklab components to six decimals', () => {
|
|
304
|
+
expect(oklabToString({ l: 0.123456789, a: 0.987654321, b: 0.111213141 })).toBe('oklab(0.123457 0.987654 0.111213)');
|
|
305
|
+
});
|
|
306
|
+
});
|
|
307
|
+
describe('oklchToString', () => {
|
|
308
|
+
it('generates oklch strings', () => {
|
|
309
|
+
const black = new Color('#000000');
|
|
310
|
+
expect(oklchToString(black.toOKLCH())).toBe('oklch(0 0 0)');
|
|
311
|
+
expect(black.toOKLCHString()).toBe('oklch(0 0 0)');
|
|
312
|
+
const white = new Color('#ffffff');
|
|
313
|
+
expect(oklchToString(white.toOKLCH())).toBe('oklch(1 0 89.876)');
|
|
314
|
+
expect(white.toOKLCHString()).toBe('oklch(1 0 89.876)');
|
|
315
|
+
const gray = new Color('#808080');
|
|
316
|
+
expect(oklchToString(gray.toOKLCH())).toBe('oklch(0.599871 0 89.876)');
|
|
317
|
+
expect(gray.toOKLCHString()).toBe('oklch(0.599871 0 89.876)');
|
|
318
|
+
const red = new Color('#ff0000');
|
|
319
|
+
expect(oklchToString(red.toOKLCH())).toBe('oklch(0.627955 0.257683 29.234)');
|
|
320
|
+
expect(red.toOKLCHString()).toBe('oklch(0.627955 0.257683 29.234)');
|
|
321
|
+
const green = new Color('#00ff00');
|
|
322
|
+
expect(oklchToString(green.toOKLCH())).toBe('oklch(0.86644 0.294827 142.495)');
|
|
323
|
+
expect(green.toOKLCHString()).toBe('oklch(0.86644 0.294827 142.495)');
|
|
324
|
+
const blue = new Color('#0000ff');
|
|
325
|
+
expect(oklchToString(blue.toOKLCH())).toBe('oklch(0.452014 0.313214 264.052)');
|
|
326
|
+
expect(blue.toOKLCHString()).toBe('oklch(0.452014 0.313214 264.052)');
|
|
327
|
+
const yellow = new Color('#ffff00');
|
|
328
|
+
expect(oklchToString(yellow.toOKLCH())).toBe('oklch(0.967983 0.211006 109.769)');
|
|
329
|
+
expect(yellow.toOKLCHString()).toBe('oklch(0.967983 0.211006 109.769)');
|
|
330
|
+
const cyan = new Color('#00ffff');
|
|
331
|
+
expect(oklchToString(cyan.toOKLCH())).toBe('oklch(0.905399 0.15455 194.769)');
|
|
332
|
+
expect(cyan.toOKLCHString()).toBe('oklch(0.905399 0.15455 194.769)');
|
|
333
|
+
const magenta = new Color('#ff00ff');
|
|
334
|
+
expect(oklchToString(magenta.toOKLCH())).toBe('oklch(0.701674 0.322491 328.363)');
|
|
335
|
+
expect(magenta.toOKLCHString()).toBe('oklch(0.701674 0.322491 328.363)');
|
|
336
|
+
const custom = new Color('#abc123');
|
|
337
|
+
expect(oklchToString(custom.toOKLCH())).toBe('oklch(0.768123 0.169623 117.914)');
|
|
338
|
+
expect(custom.toOKLCHString()).toBe('oklch(0.768123 0.169623 117.914)');
|
|
339
|
+
});
|
|
340
|
+
it('rounds oklch components to six decimals', () => {
|
|
341
|
+
expect(oklchToString({ l: 0.123456789, c: 0.987654321, h: 123.456789 })).toBe('oklch(0.123457 0.987654 123.457)');
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
describe('getColorFormatType', () => {
|
|
345
|
+
it('detects hex values', () => {
|
|
346
|
+
expect(getColorFormatType('#000').formatType).toBe('HEX');
|
|
347
|
+
expect(getColorFormatType('#000')).toEqual({
|
|
348
|
+
formatType: 'HEX',
|
|
349
|
+
value: '#000000',
|
|
350
|
+
});
|
|
351
|
+
expect(getColorFormatType('#abcdef')).toEqual({
|
|
352
|
+
formatType: 'HEX',
|
|
353
|
+
value: '#abcdef',
|
|
354
|
+
});
|
|
355
|
+
expect(getColorFormatType('#ABCDEF')).toEqual({
|
|
356
|
+
formatType: 'HEX',
|
|
357
|
+
value: '#abcdef',
|
|
358
|
+
});
|
|
359
|
+
expect(getColorFormatType('#11223344')).toEqual({
|
|
360
|
+
formatType: 'HEX8',
|
|
361
|
+
value: '#11223344',
|
|
362
|
+
});
|
|
363
|
+
});
|
|
364
|
+
it('detects object formats', () => {
|
|
365
|
+
expect(getColorFormatType({ r: 1, g: 2, b: 3 })).toEqual({
|
|
366
|
+
formatType: 'RGB',
|
|
367
|
+
value: { r: 1, g: 2, b: 3 },
|
|
368
|
+
});
|
|
369
|
+
expect(getColorFormatType({ r: 1, g: 2, b: 3, a: 0.4 })).toEqual({
|
|
370
|
+
formatType: 'RGBA',
|
|
371
|
+
value: { r: 1, g: 2, b: 3, a: 0.4 },
|
|
372
|
+
});
|
|
373
|
+
expect(getColorFormatType({ h: 10, s: 20, l: 30 })).toEqual({
|
|
374
|
+
formatType: 'HSL',
|
|
375
|
+
value: { h: 10, s: 20, l: 30 },
|
|
376
|
+
});
|
|
377
|
+
expect(getColorFormatType({ h: 10, s: 20, l: 30, a: 0.5 })).toEqual({
|
|
378
|
+
formatType: 'HSLA',
|
|
379
|
+
value: { h: 10, s: 20, l: 30, a: 0.5 },
|
|
380
|
+
});
|
|
381
|
+
expect(getColorFormatType({ h: 10, w: 20, b: 30 })).toEqual({
|
|
382
|
+
formatType: 'HWB',
|
|
383
|
+
value: { h: 10, w: 20, b: 30 },
|
|
384
|
+
});
|
|
385
|
+
expect(getColorFormatType({ h: 10, w: 20, b: 30, a: 0.5 })).toEqual({
|
|
386
|
+
formatType: 'HWBA',
|
|
387
|
+
value: { h: 10, w: 20, b: 30, a: 0.5 },
|
|
388
|
+
});
|
|
389
|
+
expect(getColorFormatType({ h: 10, s: 20, v: 30 })).toEqual({
|
|
390
|
+
formatType: 'HSV',
|
|
391
|
+
value: { h: 10, s: 20, v: 30 },
|
|
392
|
+
});
|
|
393
|
+
expect(getColorFormatType({ h: 10, s: 20, v: 30, a: 0.5 })).toEqual({
|
|
394
|
+
formatType: 'HSVA',
|
|
395
|
+
value: { h: 10, s: 20, v: 30, a: 0.5 },
|
|
396
|
+
});
|
|
397
|
+
expect(getColorFormatType({ c: 1, m: 2, y: 3, k: 4 })).toEqual({
|
|
398
|
+
formatType: 'CMYK',
|
|
399
|
+
value: { c: 1, m: 2, y: 3, k: 4 },
|
|
400
|
+
});
|
|
401
|
+
expect(getColorFormatType({ l: 50, a: 10, b: -20 })).toEqual({
|
|
402
|
+
formatType: 'LAB',
|
|
403
|
+
value: { l: 50, a: 10, b: -20 },
|
|
404
|
+
});
|
|
405
|
+
expect(getColorFormatType({ l: 0.6, a: 0.2, b: -0.1 })).toEqual({
|
|
406
|
+
formatType: 'OKLAB',
|
|
407
|
+
value: { l: 0.6, a: 0.2, b: -0.1, format: 'OKLAB' },
|
|
408
|
+
});
|
|
409
|
+
expect(getColorFormatType({ l: 0.6, a: 0.2, b: -0.1, format: 'OKLAB' })).toEqual({
|
|
410
|
+
formatType: 'OKLAB',
|
|
411
|
+
value: { l: 0.6, a: 0.2, b: -0.1, format: 'OKLAB' },
|
|
412
|
+
});
|
|
413
|
+
expect(getColorFormatType({ l: 50, c: 20, h: 100 })).toEqual({
|
|
414
|
+
formatType: 'LCH',
|
|
415
|
+
value: { l: 50, c: 20, h: 100, format: 'LCH' },
|
|
416
|
+
});
|
|
417
|
+
expect(getColorFormatType({ l: 0.5, c: 0.2, h: 100 })).toEqual({
|
|
418
|
+
formatType: 'OKLCH',
|
|
419
|
+
value: { l: 0.5, c: 0.2, h: 100, format: 'OKLCH' },
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
it('disambiguates lch and oklch based on expected ranges', () => {
|
|
423
|
+
expect(getColorFormatType({ l: 0.5, c: 50, h: 120 })).toEqual({
|
|
424
|
+
formatType: 'OKLCH',
|
|
425
|
+
value: { l: 0.5, c: 50, h: 120, format: 'OKLCH' },
|
|
426
|
+
});
|
|
427
|
+
expect(getColorFormatType({ l: 0.5, c: 50, h: 120, format: 'LCH' })).toEqual({
|
|
428
|
+
formatType: 'LCH',
|
|
429
|
+
value: { l: 0.5, c: 50, h: 120, format: 'LCH' },
|
|
430
|
+
});
|
|
431
|
+
expect(getColorFormatType({ l: 0.5, c: 0.1, h: 120 })).toEqual({
|
|
432
|
+
formatType: 'OKLCH',
|
|
433
|
+
value: { l: 0.5, c: 0.1, h: 120, format: 'OKLCH' },
|
|
434
|
+
});
|
|
435
|
+
expect(getColorFormatType({ l: 1, c: 0.4, h: 90 })).toEqual({
|
|
436
|
+
formatType: 'OKLCH',
|
|
437
|
+
value: { l: 1, c: 0.4, h: 90, format: 'OKLCH' },
|
|
438
|
+
});
|
|
439
|
+
expect(getColorFormatType({ l: 1.0001, c: 0.4, h: 90 })).toEqual({
|
|
440
|
+
formatType: 'LCH',
|
|
441
|
+
value: { l: 1.0001, c: 0.4, h: 90, format: 'LCH' },
|
|
442
|
+
});
|
|
443
|
+
expect(getColorFormatType({ l: 0.9, c: 0.7, h: 200, format: 'OKLCH' })).toEqual({
|
|
444
|
+
formatType: 'OKLCH',
|
|
445
|
+
value: { l: 0.9, c: 0.7, h: 200, format: 'OKLCH' },
|
|
446
|
+
});
|
|
447
|
+
expect(getColorFormatType({ l: 99.999, c: 0.6, h: 270 })).toEqual({
|
|
448
|
+
formatType: 'LCH',
|
|
449
|
+
value: { l: 99.999, c: 0.6, h: 270, format: 'LCH' },
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
it('disambiguates lab and oklab based on expected ranges', () => {
|
|
453
|
+
expect(getColorFormatType({ l: 0.7, a: 0.1, b: 0.2 })).toEqual({
|
|
454
|
+
formatType: 'OKLAB',
|
|
455
|
+
value: { l: 0.7, a: 0.1, b: 0.2, format: 'OKLAB' },
|
|
456
|
+
});
|
|
457
|
+
expect(getColorFormatType({ l: 0.7, a: 0.1, b: 0.2, format: 'LAB' })).toEqual({
|
|
458
|
+
formatType: 'LAB',
|
|
459
|
+
value: { l: 0.7, a: 0.1, b: 0.2, format: 'LAB' },
|
|
460
|
+
});
|
|
461
|
+
expect(getColorFormatType({ l: 75, a: 20, b: -30 })).toEqual({
|
|
462
|
+
formatType: 'LAB',
|
|
463
|
+
value: { l: 75, a: 20, b: -30 },
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
it('throws on unknown formats', () => {
|
|
467
|
+
expect(() => getColorFormatType('abc')).toThrow(/unknown color format/);
|
|
468
|
+
expect(() => getColorFormatType({})).toThrow(/unknown color format/);
|
|
469
|
+
});
|
|
470
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|