From 883f5584844b02a3a56edd526e6b8b33c7f313c7 Mon Sep 17 00:00:00 2001 From: mineejo Date: Thu, 23 Nov 2023 22:49:28 +0300 Subject: [PATCH] feat: add color blindness filters --- .idea/dictionaries/mineejo.xml | 7 ++ .../color_blind/achromatopsia_color.ts | 21 +++++ .../color_blind/deuteranomaly_color.ts | 21 +++++ .../color_blind/deuteranopia_color.ts | 21 +++++ color_effects/color_blind/mod.ts | 9 ++ color_effects/color_blind/mod_test.ts | 92 +++++++++++++++++++ .../color_blind/protanomaly_color.ts | 21 +++++ color_effects/color_blind/protanopia_color.ts | 21 +++++ .../color_blind/tritanomaly_color.ts | 21 +++++ color_effects/color_blind/tritanopia_color.ts | 21 +++++ color_effects/mod.ts | 2 + 11 files changed, 257 insertions(+) create mode 100644 color_effects/color_blind/achromatopsia_color.ts create mode 100644 color_effects/color_blind/deuteranomaly_color.ts create mode 100644 color_effects/color_blind/deuteranopia_color.ts create mode 100644 color_effects/color_blind/mod.ts create mode 100644 color_effects/color_blind/mod_test.ts create mode 100644 color_effects/color_blind/protanomaly_color.ts create mode 100644 color_effects/color_blind/protanopia_color.ts create mode 100644 color_effects/color_blind/tritanomaly_color.ts create mode 100644 color_effects/color_blind/tritanopia_color.ts diff --git a/.idea/dictionaries/mineejo.xml b/.idea/dictionaries/mineejo.xml index 60d3b69..09ef884 100644 --- a/.idea/dictionaries/mineejo.xml +++ b/.idea/dictionaries/mineejo.xml @@ -1,8 +1,15 @@ + achromatopsia chalkpot + deuteranomaly + deuteranopia mineejo + protanomaly + protanopia + tritanomaly + tritanopia \ No newline at end of file diff --git a/color_effects/color_blind/achromatopsia_color.ts b/color_effects/color_blind/achromatopsia_color.ts new file mode 100644 index 0000000..c317067 --- /dev/null +++ b/color_effects/color_blind/achromatopsia_color.ts @@ -0,0 +1,21 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../../color.ts"; +import { matrixColor } from "../matrix_color.ts"; + +/** + * ### Example + * + * ```ts + * const red = new Color(false, 255, 0, 0); + * console.log(achromatopsiaColor(red).components); // [76.24..., 76.24..., 76.24...] + * ``` + */ +export function achromatopsiaColor(color: Color): Color { + // deno-fmt-ignore + return matrixColor(color, [ + 0.299, 0.588, 0.114, + 0.299, 0.588, 0.114, + 0.299, 0.588, 0.114, + ]) +} diff --git a/color_effects/color_blind/deuteranomaly_color.ts b/color_effects/color_blind/deuteranomaly_color.ts new file mode 100644 index 0000000..b34e4fe --- /dev/null +++ b/color_effects/color_blind/deuteranomaly_color.ts @@ -0,0 +1,21 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../../color.ts"; +import { matrixColor } from "../matrix_color.ts"; + +/** + * ### Example + * + * ```ts + * const red = new Color(false, 255, 0, 0); + * console.log(deuteranomalyColor(red).components); // [204, 65.79, 0] + * ``` + */ +export function deuteranomalyColor(color: Color): Color { + // deno-fmt-ignore + return matrixColor(color, [ + 0.8, 0.2, 0, + 0.258, 0.742, 0, + 0, 0.142, 0.858, + ]) +} diff --git a/color_effects/color_blind/deuteranopia_color.ts b/color_effects/color_blind/deuteranopia_color.ts new file mode 100644 index 0000000..eb392d7 --- /dev/null +++ b/color_effects/color_blind/deuteranopia_color.ts @@ -0,0 +1,21 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../../color.ts"; +import { matrixColor } from "../matrix_color.ts"; + +/** + * ### Example + * + * ```ts + * const red = new Color(false, 255, 0, 0); + * console.log(deuteranopiaColor(red).components); // [159.37..., 178.5, 0] + * ``` + */ +export function deuteranopiaColor(color: Color): Color { + // deno-fmt-ignore + return matrixColor(color, [ + 0.625, 0.375, 0, + 0.7, 0.3, 0, + 0, 0.3, 0.7, + ]) +} diff --git a/color_effects/color_blind/mod.ts b/color_effects/color_blind/mod.ts new file mode 100644 index 0000000..4554d75 --- /dev/null +++ b/color_effects/color_blind/mod.ts @@ -0,0 +1,9 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +export { achromatopsiaColor } from "./achromatopsia_color.ts"; +export { deuteranomalyColor } from "./deuteranomaly_color.ts"; +export { deuteranopiaColor } from "./deuteranopia_color.ts"; +export { protanomalyColor } from "./protanomaly_color.ts"; +export { protanopiaColor } from "./protanopia_color.ts"; +export { tritanomalyColor } from "./tritanomaly_color.ts"; +export { tritanopiaColor } from "./tritanopia_color.ts"; diff --git a/color_effects/color_blind/mod_test.ts b/color_effects/color_blind/mod_test.ts new file mode 100644 index 0000000..e89e932 --- /dev/null +++ b/color_effects/color_blind/mod_test.ts @@ -0,0 +1,92 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../../color.ts"; +import * as originalFilters from "./mod.ts"; +import { assertEquals } from "../../dev_deps.ts"; +import { truncComponents } from "../../advanced_color_test.ts"; + +// deno-lint-ignore no-explicit-any +const filters = originalFilters as any; + +// deno-lint-ignore no-explicit-any +const functionValues: any = { + achromatopsiaColor: [ + [76, 76, 76], + [149, 149, 149], + [29, 29, 29], + ], + deuteranomalyColor: [ + [204, 65, 0], + [51, 189, 36], + [0, 0, 218], + ], + deuteranopiaColor: [ + [159, 178, 0], + [95, 76, 76], + [0, 0, 178], + ], + protanomalyColor: [ + [208, 84, 0], + [46, 170, 31], + [0, 0, 223], + ], + protanopiaColor: [ + [144, 142, 0], + [110, 112, 61], + [0, 0, 193], + ], + tritanomalyColor: [ + [246, 0, 0], + [8, 186, 46], + [0, 68, 208], + ], + tritanopiaColor: [ + [242, 0, 0], + [12, 110, 121], + [0, 144, 133], + ], +}; + +Deno.test("color blindness functions correct", async (t) => { + const red: Color = new Color(false, 255, 0, 0); + const green: Color = new Color(false, 0, 255, 0); + const blue: Color = new Color(false, 0, 0, 255); + const white: Color = new Color(false, 255, 255, 255); + const black: Color = new Color(false, 0, 0, 0); + + for (const filter in originalFilters) { + const func = filters[filter]; + + await t.step(`${func.name} function correct`, () => { + assertEquals( + truncComponents(func(red)), + functionValues?.[func.name]?.[0], + `"truncComponents(func(red))"`, + ); + + assertEquals( + truncComponents(func(green)), + functionValues?.[func.name]?.[1], + `"truncComponents(func(green))"`, + ); + + assertEquals( + truncComponents(func(blue)), + functionValues?.[func.name]?.[2], + `"truncComponents(func(blue))"`, + ); + + assertEquals( + truncComponents(func(white)), + [255, 255, 255], + `"truncComponents(func(white))"`, + ); + + assertEquals( + truncComponents(func(black)), + [0, 0, 0], + `"truncComponents(func(black))"`, + ); + }); + } +}); diff --git a/color_effects/color_blind/protanomaly_color.ts b/color_effects/color_blind/protanomaly_color.ts new file mode 100644 index 0000000..170ac7f --- /dev/null +++ b/color_effects/color_blind/protanomaly_color.ts @@ -0,0 +1,21 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../../color.ts"; +import { matrixColor } from "../matrix_color.ts"; + +/** + * ### Example + * + * ```ts + * const red = new Color(false, 255, 0, 0); + * console.log(protanomalyColor(red).components); // [208.33..., 84.91..., 0] + * ``` + */ +export function protanomalyColor(color: Color): Color { + // deno-fmt-ignore + return matrixColor(color, [ + 0.817, 0.183, 0, + 0.333, 0.667, 0, + 0, 0.125, 0.875, + ]) +} diff --git a/color_effects/color_blind/protanopia_color.ts b/color_effects/color_blind/protanopia_color.ts new file mode 100644 index 0000000..a757416 --- /dev/null +++ b/color_effects/color_blind/protanopia_color.ts @@ -0,0 +1,21 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../../color.ts"; +import { matrixColor } from "../matrix_color.ts"; + +/** + * ### Example + * + * ```ts + * const red = new Color(false, 255, 0, 0); + * console.log(protanopiaColor(red).components); // [144.58..., 142.29, 0] + * ``` + */ +export function protanopiaColor(color: Color): Color { + // deno-fmt-ignore + return matrixColor(color, [ + 0.567, 0.433, 0, + 0.558, 0.442, 0, + 0, 0.242, 0.758, + ]) +} diff --git a/color_effects/color_blind/tritanomaly_color.ts b/color_effects/color_blind/tritanomaly_color.ts new file mode 100644 index 0000000..772d6ca --- /dev/null +++ b/color_effects/color_blind/tritanomaly_color.ts @@ -0,0 +1,21 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../../color.ts"; +import { matrixColor } from "../matrix_color.ts"; + +/** + * ### Example + * + * ```ts + * const red = new Color(false, 255, 0, 0); + * console.log(tritanomalyColor(red).components); // [246.58..., 0, 0] + * ``` + */ +export function tritanomalyColor(color: Color): Color { + // deno-fmt-ignore + return matrixColor(color, [ + 0.967, 0.033, 0, + 0, 0.733, 0.267, + 0, 0.183, 0.817, + ]) +} diff --git a/color_effects/color_blind/tritanopia_color.ts b/color_effects/color_blind/tritanopia_color.ts new file mode 100644 index 0000000..aa468fe --- /dev/null +++ b/color_effects/color_blind/tritanopia_color.ts @@ -0,0 +1,21 @@ +// Copyright 2023 mineejo. All rights reserved. MIT license. + +import { Color } from "../../color.ts"; +import { matrixColor } from "../matrix_color.ts"; + +/** + * ### Example + * + * ```ts + * const red = new Color(false, 255, 0, 0); + * console.log(tritanopiaColor(red).components); // [242.25, 0, 0] + * ``` + */ +export function tritanopiaColor(color: Color): Color { + // deno-fmt-ignore + return matrixColor(color, [ + 0.95, 0.05, 0, + 0, 0.433, 0.567, + 0, 0.475, 0.525, + ]) +} diff --git a/color_effects/mod.ts b/color_effects/mod.ts index 1da386f..7eec971 100644 --- a/color_effects/mod.ts +++ b/color_effects/mod.ts @@ -6,3 +6,5 @@ export { matrixColor } from "./matrix_color.ts"; export { mixColors } from "./mix_colors.ts"; export { subtractColors } from "./subtract_colors.ts"; export { summarizeColors } from "./summarize_colors.ts"; + +export * from "./color_blind/mod.ts";