diff --git a/README.md b/README.md index ef9cc006..01d4b79f 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ The 2D graph displays hue/chroma graph and the 1D graph displays lightness. You - [x] Reduce the visual impact of the axes and labels by making them transparent gray. Set the colors, made them adaptive, set the luminance flip to .3 (50% visually) - [x] Flip the Y axis (zero at the bottom) -- [ ] Make the labels integers for CIELAB +- [x] Make the labels integers for CIELAB - [x] Make the axis scale sliders less visualy prominent. - [ ] Consider removing the axis sliders, replace them with zoom controls in the same panel as the background color selection. Changing these values is rare, they don't need to take up so much UX space. - [ ] The 2D graph should always be a centered hue/chroma graph. CIELAB and CIELCH would therefore use the same graph. Leave the LAB vs LCH distinction for slider based editing. @@ -59,12 +59,12 @@ To raise the sliders, you need to click on one of the examples that are displaye - [ ] Eval response options - [ ] higher card. vis examples - [ ] Distribute radially -- [ ] Rearrange some of the colors in the color area eg make rg on xy and b on z etc -- [ ] "opposing color" to "Convert selection to opposing" +- [?] Rearrange some of the colors in the color area eg make rg on xy and b on z etc - [ ] Insert color theory options, eg insert opposing, inserting analogous color, etc, mine from the adobe picker - [ ] NTH: Rest of basic geometry manipulations: flip (horizontal, vertical), scale - [ ] Examples held as assets somewhere that are downloaded rather than components (for consistency) - [ ] Labels, tooltips, etc +- [x] "opposing color" to "Convert selection to opposing" - [x] Meta: figure out all the other features in maureen's setup - [x] order as diverging - [x] Make it possible to ignore / dismiss lints diff --git a/src/components/ColorScatterPlot.svelte b/src/components/ColorScatterPlot.svelte index 9b6d3cf4..4a822272 100644 --- a/src/components/ColorScatterPlot.svelte +++ b/src/components/ColorScatterPlot.svelte @@ -9,10 +9,9 @@ import { makeExtents, deDup, toggleElement } from "../lib/utils"; import navStore from "../stores/nav-store"; import { scaleLinear } from "d3-scale"; - import DoubleRangeSlider from "../components/DoubleRangeSlider.svelte"; - import VerticalDoubleRangeSlider from "../components/VerticalDoubleRangeSlider.svelte"; import simulate_cvd from "../lib/blindness"; import ColorScatterPlotXyGuides from "./ColorScatterPlotXYGuides.svelte"; + import ColorScatterPlotZGuide from "./ColorScatterPlotZGuide.svelte"; export let scatterPlotMode: "moving" | "looking"; @@ -38,7 +37,11 @@ const margin = { top: 15, right: 15, bottom: 15, left: 15 }; const plotWidth = width - margin.left - margin.right; const plotHeight = height - margin.top - margin.bottom; - let extents = { x: [0, 1], y: [0, 1], z: [0, 1] }; + $: extents = { + x: $navStore.xZoom, + y: $navStore.yZoom, + z: $navStore.zZoom, + }; $: pickedColors = focusedColors.map((x) => colors[x].toChannels()); $: selectionExtents = makeExtents(pickedColors); $: xPos = xScale(selectionExtents.x[0] - 7.5); @@ -58,13 +61,27 @@ $: xRange = config.xDomain; $: domainXScale = scaleLinear().domain([0, 1]).range(xRange); $: xScale = scaleLinear() - .domain([domainXScale(extents.x[0]), domainXScale(extents.x[1])]) + .domain([ + xRange[0] > xRange[1] + ? domainXScale(extents.x[1]) + : domainXScale(extents.x[0]), + xRange[0] > xRange[1] + ? domainXScale(extents.x[0]) + : domainXScale(extents.x[1]), + ]) .range([0, plotWidth]); $: yRange = config.yDomain; $: domainYScale = scaleLinear().domain([0, 1]).range(yRange); $: yScale = scaleLinear() - .domain([domainYScale(extents.y[0]), domainYScale(extents.y[1])]) + .domain([ + yRange[0] > yRange[1] + ? domainYScale(extents.y[1]) + : domainYScale(extents.y[0]), + yRange[0] > yRange[1] + ? domainYScale(extents.y[0]) + : domainYScale(extents.y[1]), + ]) .range([0, plotHeight]); $: zRange = config.zDomain; @@ -72,7 +89,6 @@ $: zScale = scaleLinear() .domain([domainLScale(extents.z[0]), domainLScale(extents.z[1])]) .range([0, plotHeight]); - $: [zMin, zMax] = zScale.domain(); let dragging: false | { x: number; y: number } = false; let dragBox: false | { x: number; y: number } = false; @@ -223,18 +239,6 @@ onFocusedColorsChange([...newFocusedColors]); } - $: zPoints = { - top: { - y: zScale.range()[0] + 15, - label: `${config.zChannel.toUpperCase()}: ${zScale - .domain()[0] - .toFixed(1)}`, - }, - bottom: { - y: zScale.range()[1] - 5, - label: zScale.domain()[1].toFixed(1), - }, - }; // $: axisColor = bg.luminance() > 0.5 ? "gray" : "white"; $: luminance = bg.toChroma().luminance(); $: axisColor = luminance > 0.4 ? "#00000022" : "#ffffff55"; @@ -249,19 +253,17 @@ -
+
- {config.xyTitle} + + {config.title} +
-
- -
+
{/if} - + {/if} {/each} {#each blindColors as blindColor, i} @@ -409,19 +411,16 @@ fill-opacity="0" pointer-events="none" stroke-dasharray="5,5" - stroke-width="2" + stroke-width="1" cursor="grab" /> {/if}
-
- -
- {config.zTitle} + {config.zTitle}
@@ -433,6 +432,14 @@ on:touchend={stopDrag} > + - {#each Object.values(zPoints) as point} - - {point.label} - - {/each} + {#each deDup(colors) as color, i} @@ -503,8 +499,7 @@ y={Math.min(dragging.y, dragBox.y) - parentPos.y} width={80 - 10} height={Math.abs(dragging.y - dragBox.y)} - fill="steelblue" - fill-opacity="0.5" + fill={selectionColor} class="pointer-events-none" /> {/if} @@ -514,30 +509,17 @@ y={zPos - 5} width={80 - 10} height={selectionDepth + 15} - stroke="steelblue" + stroke={selectionColor} fill="white" fill-opacity="0" pointer-events="none" stroke-dasharray="5,5" - stroke-width="2" + stroke-width="1" cursor="grab" /> {/if} - -
-
-
diff --git a/src/components/ColorScatterPlotZGuide.svelte b/src/components/ColorScatterPlotZGuide.svelte new file mode 100644 index 00000000..19acc00b --- /dev/null +++ b/src/components/ColorScatterPlotZGuide.svelte @@ -0,0 +1,58 @@ + + + + + +{#each Object.values(zPoints) as point} + + {point.label} + +{/each} diff --git a/src/content-modules/LeftPanel.svelte b/src/content-modules/LeftPanel.svelte index 49001156..bc019717 100644 --- a/src/content-modules/LeftPanel.svelte +++ b/src/content-modules/LeftPanel.svelte @@ -11,6 +11,7 @@ import PickAi from "./context-free-tools/PickAI.svelte"; import { buttonStyle } from "../lib/styles"; import ShortCuts from "./context-free-tools/ShortCuts.svelte"; + import Zoom from "./context-free-tools/Zoom.svelte"; import SavedPals from "./SavedPals.svelte"; import SetColorSpace from "./SetColorSpace.svelte"; @@ -66,6 +67,7 @@ + diff --git a/src/content-modules/Swatches.svelte b/src/content-modules/Swatches.svelte index f578a0a0..d05e43e9 100644 --- a/src/content-modules/Swatches.svelte +++ b/src/content-modules/Swatches.svelte @@ -14,16 +14,16 @@ let common = "cursor-pointer mr-2 mb-2 transition-all"; let classes = [ { - className: `${common} w-14 h-14 `, + className: `${common} w-8 h-8 `, styleMap: (color: Color): string => `background-color: ${color.toHex()};`, }, { - className: `${common} w-8 h-8`, + className: `${common} w-6 h-6`, styleMap: (color: Color): string => `background-color: ${color.toHex()};`, }, { - className: `${common} w-8 h-8 rounded-full`, - styleMap: (color: Color): string => `border: 4px solid ${color.toHex()};`, + className: `${common} w-4 h-4 rounded-full`, + styleMap: (color: Color): string => `border: 2px solid ${color.toHex()};`, }, ]; @@ -86,7 +86,7 @@ let:tooltipOpen slot="target" class={className} - style={styleMap(color)} + style={`${styleMap(color)}`} on:click={(e) => { const isFocused = focusSet.has(idx); const shiftKey = e.shiftKey; @@ -104,7 +104,6 @@ focusStore.clearColors(); } } else if (tooltipOpen && !isFocused) { - console.log("C"); if (shiftKey) { focusStore.addColor(idx); } else { @@ -126,8 +125,12 @@
{/each}
- {#each colors as color} -
+ {#each colors as color, i} +
{color.toHex()}
{/each} diff --git a/src/content-modules/context-free-tools/AddFamiliarPal.svelte b/src/content-modules/context-free-tools/AddFamiliarPal.svelte index c55f22e4..a22450ca 100644 --- a/src/content-modules/context-free-tools/AddFamiliarPal.svelte +++ b/src/content-modules/context-free-tools/AddFamiliarPal.svelte @@ -39,9 +39,6 @@ }); }); Object.entries(chroma.brewer).forEach(([name, colors]) => { - if (!colorBrewerMapToType[name.toLowerCase()]) { - console.log(name); - } newPals.push({ name, colors: colors.map((x) => colorFromString(x, colorSpace)), diff --git a/src/content-modules/context-free-tools/Zoom.svelte b/src/content-modules/context-free-tools/Zoom.svelte new file mode 100644 index 00000000..196921e5 --- /dev/null +++ b/src/content-modules/context-free-tools/Zoom.svelte @@ -0,0 +1,52 @@ + + + + +
+
Zoom levels
+
+
{xName}
+ +
+
+
{yName}
+ +
+
+
{zName}
+ +
+ +
+
diff --git a/src/stores/nav-store.ts b/src/stores/nav-store.ts index 685953fa..4b10e81f 100644 --- a/src/stores/nav-store.ts +++ b/src/stores/nav-store.ts @@ -5,6 +5,9 @@ interface StoreData { comparePal: string | undefined; colorSim: "deuteranopia" | "protanopia" | "tritanopia" | "none"; includeQuotes: boolean; + xZoom: [number, number]; + yZoom: [number, number]; + zZoom: [number, number]; } const InitialStore: StoreData = { @@ -12,6 +15,9 @@ const InitialStore: StoreData = { comparePal: undefined, colorSim: "none", includeQuotes: false, + xZoom: [0, 1], + yZoom: [0, 1], + zZoom: [0, 1], }; const storeName = "color-pal-nav-store"; @@ -47,6 +53,8 @@ function createStore() { persistUpdate((old) => ({ ...old, colorSim })), setIncludeQuotes: (includeQuotes: StoreData["includeQuotes"]) => persistUpdate((old) => ({ ...old, includeQuotes })), + setZoom: (axis: "x" | "y" | "z", zoom: [number, number]) => + persistUpdate((old) => ({ ...old, [axis + "Zoom"]: zoom })), }; }