Skip to content

Commit

Permalink
Add even lightness, some ux bugs (#59)
Browse files Browse the repository at this point in the history
* Add even lightness, some ux bugs

* fix tests
  • Loading branch information
mcnuttandrew authored Mar 21, 2024
1 parent fbd0acc commit eaa6c0c
Show file tree
Hide file tree
Showing 13 changed files with 442 additions and 246 deletions.
4 changes: 2 additions & 2 deletions netlify/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ const engines = {
openai: (prompt: string) =>
openai.chat.completions.create({
messages: [{ role: "user", content: prompt }],
model: "gpt-3.5-turbo",
// model: "gpt-3.5-turbo",
n: 1,
temperature: 0.7,
// model: "gpt-4",
model: "gpt-4",
// model: "gpt-4-turbo-preview",
}),
};
Expand Down
172 changes: 107 additions & 65 deletions public/lang-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,113 @@ Program:



### Even Distribution in Hue

Description: Categorical values should have an even distribution around the hue circle in LCH color space

Natural Language: (std(speed(sort(colors, x => lch.h(x)))) < 10 OR std(speed(sort(colors, x => lch.h(x) + 180 % 360))) < 10)

Palettes that will fail this test:

- #ffb9ba, #67de25, #25d4c3, #724dd6, #6d0e44 with a #fff background



Palettes that will pass this test:

- #ffc5b8, #00dec1, #006095, #b7d119, #6e0074 with a #fff background

- #4682b4 with a #fff background


Program:

```json
{
"$schema": "http://localhost:8888/lint-schema.json",
"or": [
{
"<": {
"left": {
"std": {
"speed": { "sort": "colors", "func": {"lch.h": "x"}, "varb": "x" }
}
},
"right": 10
}
},
{
"<": {
"left": {
"std": {
"speed": {
"sort": "colors",
"varb": "x",
"func": {
"%": {
"left": {
"+": { "left": {"lch.h": "x"}, "right": 180 }
},
"right": 360
}
}
}
}
},
"right": 10
}
}
]
}

```





### Even Distribution in Lightness

Description: Values should be space evenly in lightness in LCH color space

Natural Language: std(speed(sort(colors, x => lch.l(x)))) < 5

Palettes that will fail this test:

- #ffb9ba, #67de25, #25d4c3, #724dd6, #6d0e44 with a #fff background

- #174c00, #166100, #267500, #78c12d, #b7ff6d with a #fff background



Palettes that will pass this test:

- #1a4400, #1f6e00, #4a9500, #74bd28, #9ee754 with a #fff background

- #4682b4 with a #fff background


Program:

```json
{
"$schema": "http://localhost:8888/lint-schema.json",
"<": {
"left": {
"std": {
"speed": { "sort": "colors", "func": {"lch.l": "x"}, "varb": "x" }
}
},
"right": 5
}
}

```





### Fair

Description: Do the colors stand out equally? A color palette is described as fair if both chroma and luminance ranges are below a certain threshold and unfair if one of them is above a certain threshold.
Expand Down Expand Up @@ -1308,71 +1415,6 @@ Program:



### Even Distribution

Description: Categorical values should have an even distribution around the hue circle in LCH color space

Natural Language: (std(speed(sort(colors, x => lch.h(x)))) < 10 OR std(speed(sort(colors, x => lch.h(x) + 180 % 360))) < 10)

Palettes that will fail this test:

- #ffb9ba, #67de25, #25d4c3, #724dd6, #6d0e44 with a #fff background



Palettes that will pass this test:

- #ffc5b8, #00dec1, #006095, #b7d119, #6e0074 with a #fff background

- #4682b4 with a #fff background


Program:

```json
{
"$schema": "http://localhost:8888/lint-schema.json",
"or": [
{
"<": {
"left": {
"std": {
"speed": { "sort": "colors", "func": {"lch.h": "x"}, "varb": "x" }
}
},
"right": 10
}
},
{
"<": {
"left": {
"std": {
"speed": {
"sort": "colors",
"varb": "x",
"func": {
"%": {
"left": {
"+": { "left": {"lch.h": "x"}, "right": 180 }
},
"right": 360
}
}
}
}
},
"right": 10
}
}
]
}

```





### In Gamut

Description: Checks if the colors are in the sRGB gamut. This is important to ensure that the colors are visible and can be displayed on most devices.
Expand Down
64 changes: 12 additions & 52 deletions src/controls/DistributePoints.svelte
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<script lang="ts">
import { Color, colorPickerConfig } from "../lib/Color";
import { colorPickerConfig } from "../lib/Color";
import colorStore from "../stores/color-store";
import focusStore from "../stores/focus-store";
import { buttonStyle } from "../lib/styles";
import { distributePoints } from "../lib/utils";
import type { Direction } from "../lib/utils";
$: currentPal = $colorStore.palettes[$colorStore.currentPal];
$: colors = currentPal.colors;
Expand All @@ -11,57 +13,9 @@
$: config = colorPickerConfig[colorSpace];
$: zName = colorPickerConfig[colorSpace].zChannel;
interface Direction {
direction: "horizontal" | "vertical" | "in z space";
name: string;
}
function distributePoints(dir: Direction) {
let sortedIndexes = focusedColors.sort((a, b) => {
const modeToIdx = { horizontal: 1, vertical: 2, "in z space": 0 };
const idx = modeToIdx[dir.direction] || 0;
const pointA = colors[a].color.toChannels()[idx];
const pointB = colors[b].color.toChannels()[idx];
return pointA - pointB;
});
type Channels = [number, number, number];
const minPoint = colors[sortedIndexes[0]].color.toChannels() as Channels;
const maxPoint = colors[
sortedIndexes[sortedIndexes.length - 1]
].color.toChannels() as Channels;
const numPoints = sortedIndexes.length - 1;
let newPoints = sortedIndexes.map((colorIdx, arrIdx) => {
const t = arrIdx / numPoints;
const newPoint = colors.at(colorIdx)!.color.toChannels() as Channels;
const xIdx = config.xChannelIndex;
const yIdx = config.yChannelIndex;
const zIdx = config.zChannelIndex;
if (dir.direction === "horizontal") {
newPoint[xIdx] = minPoint[xIdx] * (1 - t) + maxPoint[xIdx] * t;
} else if (dir.direction === "vertical") {
newPoint[yIdx] = minPoint[yIdx] * (1 - t) + maxPoint[yIdx] * t;
} else {
newPoint[zIdx] = minPoint[zIdx] * (1 - t) + maxPoint[zIdx] * t;
}
return newPoint as Channels;
});
const zip = <T, U>(arr1: T[], arr2: U[]) =>
arr1.map((k, i) => [k, arr2[i]] as [T, U]);
const pointsByIndex = Object.fromEntries(zip(sortedIndexes, newPoints));
const newColors = [...colors].map((color, idx) => {
const point = pointsByIndex[idx];
return point
? { ...color, color: Color.colorFromChannels(point, colorSpace) }
: color;
});
colorStore.setCurrentPalColors(newColors);
}
$: isPolar = config.isPolar;
$: directions = [
{ direction: "horizontal", name: isPolar ? "radial" : "horizontal" },
{ direction: "vertical", name: isPolar ? "angle" : "vertical" },
{ direction: "horizontal", name: config.isPolar ? "radial" : "horizontal" },
{ direction: "vertical", name: config.isPolar ? "angle" : "vertical" },
{ direction: "in z space", name: `in ${zName.toUpperCase()} space` },
] as Direction[];
</script>
Expand All @@ -71,7 +25,13 @@
<div class="font-bold">Distribute</div>
<div class="flex flex-wrap">
{#each directions as direction}
<button class={buttonStyle} on:click={() => distributePoints(direction)}>
<button
class={buttonStyle}
on:click={() =>
colorStore.setCurrentPalColors(
distributePoints(direction, focusedColors, colors, colorSpace)
)}
>
{direction.name}
</button>
{/each}
Expand Down
8 changes: 5 additions & 3 deletions src/lib/ColorLint.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,9 +61,11 @@ test("ColorLint - UglyColors", () => {
autoTest(UglyColors);
});

test("ColorLint - EvenDistribution", () => {
autoTest(EvenDistribution);
});
test("ColorLint - EvenDistribution (1) Hue", () =>
autoTest(EvenDistribution[0]));

test("ColorLint - EvenDistribution (2) Lightness", () =>
autoTest(EvenDistribution[1]));

test("ColorLint - Fair Nominal", () => {
autoTest(Fair[0]);
Expand Down
14 changes: 11 additions & 3 deletions src/lib/__snapshots__/ColorLint.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,19 @@ exports[`ColorLint - Contrast (3) contrastTextAAA 1`] = `"These colors () do not

exports[`ColorLint - Contrast (3) contrastTextAAA 2`] = `"These colors (#af3b4b) do not have a sufficient contrast ratio with the background and may be hard to discriminate in some contexts."`;

exports[`ColorLint - EvenDistribution 1`] = `"This palette does not evenly distribute the colors around its range correctly. Try making the spacing between the colors more regular to resolve this issue. "`;
exports[`ColorLint - EvenDistribution (1) Hue 1`] = `"This palette does not evenly distribute the colors around its range correctly. Try making the spacing between the colors more regular to resolve this issue. "`;

exports[`ColorLint - EvenDistribution 2`] = `"This palette does not evenly distribute the colors around its range correctly. Try making the spacing between the colors more regular to resolve this issue. "`;
exports[`ColorLint - EvenDistribution (1) Hue 2`] = `"This palette does not evenly distribute the colors around its range correctly. Try making the spacing between the colors more regular to resolve this issue. "`;

exports[`ColorLint - EvenDistribution 3`] = `"This palette does not evenly distribute the colors around its range correctly. Try making the spacing between the colors more regular to resolve this issue. "`;
exports[`ColorLint - EvenDistribution (1) Hue 3`] = `"This palette does not evenly distribute the colors around its range correctly. Try making the spacing between the colors more regular to resolve this issue. "`;

exports[`ColorLint - EvenDistribution (2) Lightness 1`] = `"This palette does not evenly distribute the colors in lightness (in LCH space) correctly. Try making the spacing between the colors more regular to resolve this issue."`;

exports[`ColorLint - EvenDistribution (2) Lightness 2`] = `"This palette does not evenly distribute the colors in lightness (in LCH space) correctly. Try making the spacing between the colors more regular to resolve this issue."`;

exports[`ColorLint - EvenDistribution (2) Lightness 3`] = `"This palette does not evenly distribute the colors in lightness (in LCH space) correctly. Try making the spacing between the colors more regular to resolve this issue."`;

exports[`ColorLint - EvenDistribution (2) Lightness 4`] = `"This palette does not evenly distribute the colors in lightness (in LCH space) correctly. Try making the spacing between the colors more regular to resolve this issue."`;

exports[`ColorLint - Fair Nominal 1`] = `"This palette is unfair (meaning that some values may unduely stand out). Note that this check is naturally at odds with color vision deficiency friendly palettes. Maximum chroma range: 80, maximum luminance range: 50."`;

Expand Down
Loading

0 comments on commit eaa6c0c

Please sign in to comment.