diff --git a/docs/assets/scripts/tweak/data.js b/docs/assets/scripts/tweak/data.js index 810b62a9d..1e9c91448 100644 --- a/docs/assets/scripts/tweak/data.js +++ b/docs/assets/scripts/tweak/data.js @@ -123,6 +123,25 @@ export const MAX_CHROMA_BY_TINT = { 95: 0.11, }; +/** + * Chroma levels to identify gray. + * First number: below this we identify as gray regardless + * Second number: below this we identify as gray if it's also in the bottom 25% of colors when sorted by chroma + */ +export const GRAY_CHROMA_BY_TINT = { + '05': [0.03, 0.05], + 10: [0.035, 0.06], + 20: [0.045, 0.06], + 30: [0.05, 0.06], + 40: [0.05, 0.06], + 50: [0.04, 0.06], + 60: [0.03, 0.05], + 70: [0.02, 0.04], + 80: [0.015, 0.03], + 90: [0.007, 0.01], + 95: [0.004, 0.005], +}; + export const moreHue = { red: 'Redder', orange: 'More orange', // https://www.reddit.com/r/grammar/comments/u9n0uo/is_it_oranger_or_more_orange/ diff --git a/docs/docs/palettes/app/color/util.js b/docs/docs/palettes/app/color/util.js index af5ea351b..eaaef470a 100644 --- a/docs/docs/palettes/app/color/util.js +++ b/docs/docs/palettes/app/color/util.js @@ -1,21 +1,41 @@ import { - CHROMA_CURVES, - CHROMA_SCALE_LIGHTEST, CHROMA_TOLERANCE, DEFAULT_ACCENT, + GRAY_CHROMA_BY_TINT, HUE_RANGES, HUE_SHIFTS, L_RANGES, MAX_ACCENT, - MAX_CHROMA_BY_TINT, MIN_ACCENT, tints, } from '/assets/scripts/tweak/data.js'; import { clamp, getRange, mapRange } from '/assets/scripts/tweak/util.js'; -export function identifyColor(color) { - let hue = getRange(HUE_RANGES, color.get('oklch.h'), { type: 'angle' }).key; - let level = getRange(L_RANGES, color.get('oklch.l')).key; +export function identifyColor(color, colors) { + let [l, c, h] = color.getAll('oklch'); + let level = getRange(L_RANGES, l).key; + let hue; + + // Identify grays + let grayBounds = GRAY_CHROMA_BY_TINT[level]; + if (c <= grayBounds[1]) { + // Possibly gray + if (c <= grayBounds[0]) { + // Definitely gray + hue = 'gray'; + } else if (colors) { + // May or may not be gray, compare to palette max chroma + // FIXME this does not take level into account, so is more likely to identify lighter colors as gray + let maxChroma = Math.max(...colors.map(color => color.get('oklch.c'))); + + if (c / maxChroma < 0.2) { + hue = 'gray'; + } + } + } + + hue ??= getRange(HUE_RANGES, h, { type: 'angle' }).key; + return { hue, level }; } diff --git a/docs/docs/palettes/app/tweak.js b/docs/docs/palettes/app/tweak.js index 0cbb36b28..da72e6ae3 100644 --- a/docs/docs/palettes/app/tweak.js +++ b/docs/docs/palettes/app/tweak.js @@ -254,7 +254,9 @@ let paletteAppSpec = { }, seedColorInfo() { - return this.seedColorObjectsRaw.map(colorObject => (colorObject ? identifyColor(colorObject) : null)); + return this.seedColorObjectsRaw.map(colorObject => + colorObject ? identifyColor(colorObject, this.seedColorObjects) : null, + ); }, seedHueList() { @@ -264,6 +266,7 @@ let paletteAppSpec = { seedHues() { // Make sure hues are in the right order let ret = {}; + for (let hue of hues) { Object.defineProperty(ret, hue, { value: undefined, enumerable: false, writable: true, configurable: true }); }