Skip to content

Commit

Permalink
Rework color storage
Browse files Browse the repository at this point in the history
  • Loading branch information
mcnuttandrew committed Jan 11, 2024
1 parent a4e722a commit 197b4fa
Show file tree
Hide file tree
Showing 19 changed files with 133 additions and 56 deletions.
4 changes: 2 additions & 2 deletions src/components/ColorScatterPlot.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -403,15 +403,15 @@
fill={color.toHex()}
/>
{/if}
<!-- {#if !color.inGamut()}
{#if !color.inGamut()}
<g
pointer-events="none"
transform={`translate(${x(color)} ${y(color)})`}
>
<line stroke="black" x1={-7} y1={-7} x2={7} y2={7}></line>
<line stroke="black" x1={-7} y1={7} x2={7} y2={-7}></line>
</g>
{/if} -->
{/if}
{/each}
{#each blindColors as blindColor, i}
<!-- svelte-ignore a11y-click-events-have-key-events -->
Expand Down
2 changes: 1 addition & 1 deletion src/components/KeyboardHooks.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import focusStore from "../stores/focus-store";
$: focusedSet = new Set($focusStore.focusedColors);
$: copiedData = [] as Color[];
$: colorSpace = $colorStore.currentPal.colors[0].spaceName;
$: colorSpace = $colorStore.currentPal.colorSpace;
$: [_zStep, xStep, yStep] = stepSize[colorSpace];
function onKeyDown(e: any) {
if (e.target.tagName.toLowerCase() === "input") {
Expand Down
2 changes: 1 addition & 1 deletion src/content-modules/Background.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import ColorChannelPicker from "../components/ColorChannelPicker.svelte";
import Tooltip from "../components/Tooltip.svelte";
$: bg = $colorStore.currentPal.background;
$: colorSpace = $colorStore.currentPal.colors[0].spaceName || "lab";
$: colorSpace = $colorStore.currentPal.colorSpace;
function onChange(color: Color) {
colorStore.setBackground(color);
}
Expand Down
13 changes: 5 additions & 8 deletions src/content-modules/SetColorSpace.svelte
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
<script lang="ts">
import colorStore from "../stores/color-store";
import { colorPickerConfig, toColorSpace } from "../lib/Color";
$: colors = $colorStore.currentPal.colors;
import { colorPickerConfig } from "../lib/Color";
$: colorSpace = $colorStore.currentPal.colorSpace;
const notAllowed = new Set(["rgb", "hsv", "hsl"]);
</script>

<div class="w-full flex flex-col">
<label for="color-space-select">Color Space</label>
<select
id="color-space-select"
value={colors[0] && colors[0].spaceName}
value={colorSpace}
on:change={(e) => {
const newColors = colors.map((color) =>
// @ts-ignore
toColorSpace(color, e.target.value)
);
colorStore.setCurrentPalColors(newColors);
// @ts-ignore
colorStore.setColorSpace(e.target.value);
}}
>
{#each Object.entries(colorPickerConfig).filter((x) => !notAllowed.has(x[0])) as [space, { title }]}
Expand Down
2 changes: 1 addition & 1 deletion src/content-modules/SwatchTooltipContent.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
export let color: Color;
export let closeTooltip: () => void;
$: colors = $colorStore.currentPal.colors;
$: colorSpace = colors[0].spaceName || "lab";
$: colorSpace = $colorStore.currentPal.colorSpace;
function updateColor(color: Color) {
const updatedColors = [...colors];
Expand Down
4 changes: 3 additions & 1 deletion src/content-modules/context-free-tools/AddFamiliarPal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
group: string;
}
$: familiarPals = [] as ExtendedPal[];
$: colorSpace = $colorStore.currentPal.colors[0]?.spaceName || "lab";
$: colorSpace = $colorStore.currentPal.colorSpace;
onMount(() => {
const toHex = (x: string) => {
Expand All @@ -35,6 +35,7 @@
group: "vega",
type: "categorical",
evalConfig: {},
colorSpace,
});
});
Object.entries(chroma.brewer).forEach(([name, colors]) => {
Expand All @@ -48,6 +49,7 @@
group: "brewer",
type: colorBrewerMapToType[name.toLowerCase()],
evalConfig: {},
colorSpace,
});
});
familiarPals = newPals;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import navStore from "../../stores/nav-store";
$: colors = $colorStore.currentPal.colors;
let state: "idle" | "error" = "idle";
$: colorSpace = $colorStore.currentPal.colors[0]?.spaceName || "lab";
$: colorSpace = $colorStore.currentPal.colorSpace;
function processBodyInput(body: string) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
import PalPreview from "../../components/PalPreview.svelte";
import { buttonStyle, AIButtonStyle } from "../../lib/styles";
$: colorSpace = $colorStore.currentPal.colors[0]?.spaceName || "lab";
$: colorSpace = $colorStore.currentPal.colorSpace;
let requestState: "idle" | "loading" | "loaded" | "failed" = "idle";
let newPal: Palette = {
colors: [],
background: colorFromString("#000000", colorSpace),
name: "blank",
type: "categorical",
evalConfig: {},
colorSpace,
};
let palPrompt: string = "";
Expand Down
2 changes: 1 addition & 1 deletion src/content-modules/contextual-tools/AddColor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Tooltip from "../../components/Tooltip.svelte";
$: colors = $colorStore.currentPal.colors;
$: colorSpace = colors[0]?.spaceName || "lab";
$: colorSpace = $colorStore.currentPal.colorSpace;
let suggestions = [randColor(), randColor(), randColor()].map((x) =>
x.toHex()
Expand Down
2 changes: 1 addition & 1 deletion src/content-modules/contextual-tools/AdjustColor.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
$: colors = $colorStore.currentPal.colors;
$: focusedColors = $focusStore.focusedColors;
$: colorSpace = $colorStore.currentPal.colors[0]?.spaceName || "lab";
$: colorSpace = $colorStore.currentPal.colorSpace;
function actionOnColor(idx: number, action: (Color: Color) => any) {
const newColor = action(colors[idx]);
Expand Down
2 changes: 1 addition & 1 deletion src/content-modules/contextual-tools/AlignSelection.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
$: focusedColors = $focusStore.focusedColors;
$: focusSet = new Set(focusedColors);
$: focusLabs = focusedColors.map((idx) => colors[idx].toChannels());
$: colorSpace = $colorStore.currentPal.colors[0]?.spaceName || "lab";
$: colorSpace = $colorStore.currentPal.colorSpace;
const ALIGNS = [
{ pos: 1, name: "Left", op: Math.min },
{ pos: 1, name: "Right", op: Math.max },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
$: colors = $colorStore.currentPal.colors;
$: focusedColors = $focusStore.focusedColors;
$: colorSpace = $colorStore.currentPal.colors[0]?.spaceName || "lab";
$: colorSpace = $colorStore.currentPal.colorSpace;
type Direction = "horizontal" | "vertical" | "in z space";
function distributePoints(direction: Direction) {
Expand Down
2 changes: 1 addition & 1 deletion src/content-modules/contextual-tools/Rotate.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
$: colors = $colorStore.currentPal.colors;
$: angle = 0;
$: colorSpace = $colorStore.currentPal.colors[0].spaceName;
$: colorSpace = $colorStore.currentPal.colorSpace;
$: angle, rotatePoints();
$: memorizedColors = false as false | Color[];
let rotationPoint = "avg" as number | "avg" | "zero";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import PalDiff from "../../components/PalDiff.svelte";
let requestState: "idle" | "loading" | "loaded" | "failed" = "idle";
$: colorSpace = $colorStore.currentPal.colors[0]?.spaceName || "lab";
$: colorSpace = $colorStore.currentPal.colorSpace;
$: colors = $colorStore.currentPal.colors;
$: selectedColors = $focusStore.focusedColors
.map((x) => colors[x]?.toHex())
Expand All @@ -23,6 +23,7 @@
background: $colorStore.currentPal.background,
type: $colorStore.currentPal.type,
evalConfig: {},
colorSpace,
};
}
Expand Down
22 changes: 22 additions & 0 deletions src/lib/Color.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { expect, test } from "vitest";
import { stringToChannels } from "./Color";

test("Color string extractor works", () => {
expect(stringToChannels("lab", "lab(50% 0 0)")).toStrictEqual([50, 0, 0]);
expect(
stringToChannels(
"lab",
"lab(100.00000139649632% -0.000007807961277528364 0.000006766250648659877)"
)
).toStrictEqual([
100.00000139649632, -0.000007807961277528364, 0.000006766250648659877,
]);
expect(
stringToChannels(
"oklab",
"oklab(1.000000009791752,-3.3637913787742946e-8,6.836016341882356e-8)"
)
).toStrictEqual([
1.000000009791752, -3.3637913787742946e-8, 6.836016341882356e-8,
]);
});
60 changes: 49 additions & 11 deletions src/lib/Color.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ export class Color {
}
toString(): string {
const channelsString = Object.values(this.channels)
// .map((x) => x.toPrecision(4))
.join(",");
.map((x) => x || 0)
.map((x) => (x < 1e-7 ? 0 : x))
.join(", ");
return `${this.spaceName}(${channelsString})`;
}
getChannel(channel: keyof typeof this.channels): number {
Expand All @@ -41,7 +42,10 @@ export class Color {
inGamut(): boolean {
// return new ColorIO(this.spaceName, this.toChannels()).inGamut();
const x = this.toHex();
const y = colorFromHex(x, this.spaceName).toHex();
const y = colorFromHex(x, "srgb").toHex();
// if (x !== y) {
// console.log("x", x, "y", y);
// }
return x === y;
}
toColorIO(): ColorIO {
Expand All @@ -53,14 +57,19 @@ export class Color {
const channels = new ColorIO(colorString).to(this.spaceName).coords;
return this.fromChannels(channels);
}
// extract the numbers from the string
const regex = new RegExp(`${this.spaceName}\\((.*)% (.*) (.*)\\)`);
const match = colorString.match(regex);
if (!match) {
throw new Error(`Invalid color string: ${colorString}`);
}
const [_, ...channels] = match;
return this.fromChannels([+channels[0], +channels[1], +channels[2]]);
return this.fromChannels(stringToChannels(this.spaceName, colorString));
// // extract the numbers from the string
// // const regex = new RegExp(`${this.spaceName}\\((.*)% (.*) (.*)\\)`);
// const regex = new RegExp(
// `${this.spaceName}\\((.*?)(%|,)(.*?) (.*?)(%|,) (.*?)\\)\\)`
// );
// const match = colorString.match(regex);
// if (!match) {
// throw new Error(`Invalid color string: ${colorString}`);
// }
// const [_, ...channels] = match;
// console.log(channels);
// return this.fromChannels([+channels[0], +channels[1], +channels[2]]);
}
fromChannels(channels: [number, number, number]): Color {
const newColor = new (this.constructor as typeof Color)();
Expand All @@ -83,6 +92,35 @@ export class Color {
}
}

export function stringToChannels(spaceName: string, str: string) {
// const regex = new RegExp(
// `${spaceName}\\((.*?)(%|,)(.*?) (.*?)(%|,) (.*?)\\)\\)`
// );
let temp = str
.replace(`${spaceName}(`, "")
.replace(")", "")
.replace(/%/g, "")
.replace(/,/g, " ")
.trim()
.split(" ")
.filter((x) => x.length);
const allNumbers = temp.every((x) => !isNaN(+x));

if (!(temp.length === 3 && allNumbers)) {
throw new Error(`Invalid color string: ${str}`);
}
return temp.map((x) => Number(x) * 1) as [number, number, number];
// console.log(temp);
// const regex = new RegExp(/(\-?\d+(?:\.\d+)?%){3}/);
// const match = str.match(regex);
// console.log(str, match, regex);
// if (!match) {
// throw new Error(`Invalid color string: ${str}`);
// }
// const [_, ...channels] = match;
// return channels.map((x) => +x) as [number, number, number];
}

export class CIELAB extends Color {
name = "CIELAB";
channels = { L: 0, a: 0, b: 0 };
Expand Down
1 change: 1 addition & 0 deletions src/lib/ColorLint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ function makePalFromHexes(hexes: string[]): Palette {
name: "test",
type: "categorical",
evalConfig: {},
colorSpace: "lab",
};
}

Expand Down
3 changes: 1 addition & 2 deletions src/lib/lints/background-differentiability.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default class BackgroundDifferentiability extends ColorLint<
return `This palette has some colors (${str}) that are close to the background color`;
}
async suggestFix() {
const { colors, background } = this.palette;
const { colors, background, colorSpace } = this.palette;
const backgroundL = background.toColorIO().to("lab").coords[0];
const bgCloserToWhite = backgroundL > 50;
const clamp = (x: number) => Math.max(0, Math.min(100, x));
Expand All @@ -38,7 +38,6 @@ export default class BackgroundDifferentiability extends ColorLint<
return x;
}
const color = colors[idx];
const colorSpace = color.spaceName;
const newColor = toColorSpace(color, "lab");
const [_l, a, b] = newColor.toChannels();
return toColorSpace(newColor.fromChannels([newL, a, b]), colorSpace);
Expand Down
Loading

0 comments on commit 197b4fa

Please sign in to comment.