diff --git a/README.md b/README.md index d65e3465..80e0ca15 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ First time you start it up you should also run `yarn prep data` - [ ] Bug: rotate in polar coordinates doesn't work right - [ ] Ad hoc lints seem possible, do a spike - [ ] Directional subtlies for aligns, they do not work in polar also +- [ ] Bug: make a selection. interpolate it. undo the interpolation, crash. Proposed solution: if the number of points changes clear the selection? +- [x] Show simulated colors on examples, add a gray scale check - [x] Bug: if comparing the same palette in two spaces, make a change and the space reverts - [x] Compare: should show the values a pal preview - [x] Deselect: In the row of colors, clicking on a selected color should deselect it diff --git a/src/App.svelte b/src/App.svelte index ba454a82..db8213e6 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -17,7 +17,6 @@ import Background from "./components/Background.svelte"; import SetColorSpace from "./controls/SetColorSpace.svelte"; import PalPreview from "./components/PalPreview.svelte"; - import Sort from "./controls/Sort.svelte"; import SuggestName from "./controls/SuggestName.svelte"; import GetColorsFromString from "./controls/GetColorsFromString.svelte"; import NewPal from "./controls/NewPal.svelte"; @@ -68,7 +67,7 @@
-
+
Current Pal:
diff --git a/src/components/MiniPalPreview.svelte b/src/components/MiniPalPreview.svelte index 44b386d6..63bf1338 100644 --- a/src/components/MiniPalPreview.svelte +++ b/src/components/MiniPalPreview.svelte @@ -6,7 +6,7 @@
-
+
{#each pal.colors as color}
{#if ComparisonPal !== undefined} -
- Compare Pal: {ComparisonPal.name} +
+ Compare: {ComparisonPal.name}
focusStore.clearColors()} > - Clear + Deselect @@ -129,6 +133,21 @@ Reset to defaults + {#if $configStore.colorSim !== "none"} + + {/if} {#if numberHidden > 0}
diff --git a/src/example/Swatches.svelte b/src/example/Swatches.svelte index 7c3441bd..03e46701 100644 --- a/src/example/Swatches.svelte +++ b/src/example/Swatches.svelte @@ -2,13 +2,25 @@ import { Color } from "../lib/Color"; import colorStore from "../stores/color-store"; import focusStore from "../stores/focus-store"; + import configStore from "../stores/config-store"; import Tooltip from "../components/Tooltip.svelte"; import exampleStore from "../stores/example-store"; import SwatchTooltipContent from "../components/SwatchTooltipContent.svelte"; import { buttonStyle } from "../lib/styles"; + import simulate_cvd from "../lib/blindness"; $: currentPal = $colorStore.palettes[$colorStore.currentPal]; $: colors = currentPal.colors; + $: { + if ( + $configStore.colorSim !== "none" && + $configStore.useSimulatorOnExamples + ) { + colors = colors.map((x) => simulate_cvd($configStore.colorSim, x)); + } else { + colors = currentPal.colors; + } + } $: bg = currentPal.background; $: focused = $focusStore.focusedColors; $: focusSet = new Set(focused); diff --git a/src/lib/blindness.ts b/src/lib/blindness.ts index 58b1b48c..2cf7667e 100644 --- a/src/lib/blindness.ts +++ b/src/lib/blindness.ts @@ -102,10 +102,10 @@ function blackAndWhite(color: Channels): Channels { } function dl_simulate_cvd( - deficiency: DLDeficiency | "black-and-white", + deficiency: DLDeficiency | "grayscale", color: Channels ): Channels { - if (deficiency == "black-and-white") { + if (deficiency == "grayscale") { return blackAndWhite(color); } return brettelFunctions[deficiency](color); diff --git a/src/lib/lints/blind-check.ts b/src/lib/lints/blind-check.ts index 41af60a3..bd3f10f6 100644 --- a/src/lib/lints/blind-check.ts +++ b/src/lib/lints/blind-check.ts @@ -27,7 +27,7 @@ function indexesWithSmallDeltaE(colors: Color[]) { return indexes; } -function checkType(colors: Color[], type: BlindnessTypes) { +function checkType(colors: Color[], type: BlindnessTypes | "grayscale") { const blindColors = colors.map((x) => simulate_cvd(type, x)); let notOKColorIndexes: [number, number][] = indexesWithSmallDeltaE(blindColors); @@ -93,4 +93,25 @@ const checks = blindnessTypes.map((key) => { }; }); +class Grayscale extends ColorLint<[number, number][], false> { + name = `Grayscale friendly`; + taskTypes = ["sequential", "diverging", "categorical"] as TaskType[]; + group: string = "accessibility"; + description: string = `Colors should be discernable in gray scale. For instance if printing in black and white, colors should still be distinguishable.`; + _runCheck() { + const colors = this.palette.colors; + const { pass, notOKColorIndexes } = checkType(colors, "grayscale"); + return { passCheck: pass, data: notOKColorIndexes }; + } + buildMessage(): string { + const colors = this.palette.colors.map((x) => x.toHex()); + const pairs = this.checkData + .map(([a, b]) => `(${colors[a]} and ${colors[b]})`) + .join(", "); + return `These color pairs are not distinguishable in grayscale: ${pairs}.`; + } +} + +checks.push(Grayscale); + export default checks; diff --git a/src/linting/Eval.svelte b/src/linting/Eval.svelte index 0d8f3a41..f5240390 100644 --- a/src/linting/Eval.svelte +++ b/src/linting/Eval.svelte @@ -151,14 +151,24 @@
- {#if Object.keys(currentPal.evalConfig)} - - {/if} +
+ {#if Object.keys(currentPal.evalConfig)} + + {/if} + {#if $configStore.colorSim !== "none"} + + {/if} +
This collection of checks validates whether or not your palette matches a number of commonly held beliefs about best practices. They will not diff --git a/src/linting/EvalResponse.svelte b/src/linting/EvalResponse.svelte index ab2232cc..0439c817 100644 --- a/src/linting/EvalResponse.svelte +++ b/src/linting/EvalResponse.svelte @@ -59,9 +59,14 @@ }); } - const options = ["deuteranopia", "protanopia", "tritanopia"] as const; + const options = [ + "deuteranopia", + "protanopia", + "tritanopia", + "grayscale", + ] as const; $: cbMatch = options.find((x) => - check.name.includes(x) + check.name.toLowerCase().includes(x) ) as (typeof options)[number]; diff --git a/src/stores/config-store.ts b/src/stores/config-store.ts index 55593536..8170428b 100644 --- a/src/stores/config-store.ts +++ b/src/stores/config-store.ts @@ -5,7 +5,7 @@ interface StoreData { controlsOpen: boolean; savedPalsOpen: boolean; comparePal: number | undefined; - colorSim: "deuteranopia" | "protanopia" | "tritanopia" | "none"; + colorSim: "deuteranopia" | "protanopia" | "tritanopia" | "none" | "grayscale"; includeQuotes: boolean; xZoom: [number, number]; yZoom: [number, number]; @@ -14,6 +14,7 @@ interface StoreData { showColorBackground: boolean; tooltipXY?: [string, string]; scatterplotMode: "moving" | "putting"; + useSimulatorOnExamples: boolean; } const InitialStore: StoreData = { @@ -30,6 +31,7 @@ const InitialStore: StoreData = { xZoom: [0, 1], yZoom: [0, 1], zZoom: [0, 1], + useSimulatorOnExamples: false, }; const storeName = "color-pal-nav-store"; @@ -77,6 +79,8 @@ function createStore() { persist((old) => ({ ...old, savedPalsOpen: n })), setScatterplotMode: (n: StoreData["scatterplotMode"]) => persist((old) => ({ ...old, scatterplotMode: n })), + setUseSimulatorOnExamples: (n: StoreData["useSimulatorOnExamples"]) => + persist((old) => ({ ...old, useSimulatorOnExamples: n })), }; }