Skip to content

Commit

Permalink
Generate separator in SVG
Browse files Browse the repository at this point in the history
  • Loading branch information
Николаев Андрей committed Aug 18, 2023
1 parent db60706 commit ca4a98f
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 65 deletions.
54 changes: 15 additions & 39 deletions dist/ui/index.html

Large diffs are not rendered by default.

38 changes: 37 additions & 1 deletion ui/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,17 @@ import { formatHex, formatHex8, converter, inGamut, clampChromaInGamut } from ".
import * as twgl from 'twgl.js';

import { colorConversion } from "./helpers/colorConversion";
import { PICKER_SIZE, SLIDER_SIZE, LOW_RES_PICKER_SIZE, LOW_RES_PICKER_SIZE_OKLCH, lOW_RES_FACTOR, lOW_RES_FACTOR_OKLCH, OKLCH_CHROMA_SCALE, debugMode } from "./constants";
import {
PICKER_SIZE,
SLIDER_SIZE,
LOW_RES_PICKER_SIZE,
LOW_RES_PICKER_SIZE_OKLCH,
lOW_RES_FACTOR,
lOW_RES_FACTOR_OKLCH,
OKLCH_CHROMA_SCALE,
OKLCH_RGB_BOUNDARY_COLOR,
debugMode
} from "./constants";

import { UiMessageTexts } from "./ui-messages";

Expand Down Expand Up @@ -149,6 +159,7 @@ export const App = function() {
const fileColorProfileSelect = useRef<HTMLSelectElement>(null);
const colorModelSelect = useRef<HTMLSelectElement>(null);
const colorSpaceOfCurrentColor = useRef<HTMLDivElement>(null);
const sRGBBoundary = useRef<SVGPathElement>(null);

const colorCode_currentColorModelInput = useRef<HTMLInputElement>(null);
const colorCode_colorInput = useRef<HTMLInputElement>(null);
Expand Down Expand Up @@ -390,6 +401,28 @@ export const App = function() {
colorPickerCanvas() {
if (debugMode) { console.log("UI: render.colorPickerCanvas()"); }

// show separator
if (fileColorProfile === 'p3') {
let d = 'M0 0 ';
const precision = 0.5
// Precision 0.5 to reduce the load; the rest will be rendered by the browser itself.
// It gives a slightly skewed angle at hue 0 and 360; it can be slightly increased
for (let l = 0; l < PICKER_SIZE; l += 1 / precision) {
const lumen = (PICKER_SIZE - l) / PICKER_SIZE;
const sRGBMaxChroma = clampChromaInGamut({
mode: "oklch",
l: lumen,
c: 0.37,
h: okhxyValues.hue.value
}, "oklch", "rgb");
d += `L${(sRGBMaxChroma.c * PICKER_SIZE * OKLCH_CHROMA_SCALE).toFixed(2)} ${l} `;
}

sRGBBoundary.current!.setAttribute('d', d);
} else {
sRGBBoundary.current!.setAttribute('d', '');
}

let dark = document.documentElement.classList.contains("figma-dark");

const gl = colorPickerGLContext!;
Expand Down Expand Up @@ -1245,6 +1278,9 @@ export const App = function() {
<div ref={colorSpaceOfCurrentColor} class="c-color-picker__color-space"></div>

<canvas ref={colorPickerCanvas} class="c-color-picker__canvas" id="okhxy-xy-picker"></canvas>
<svg class="c-color-picker__oklch-separator" width={PICKER_SIZE} height={PICKER_SIZE}>
<path fill="none" stroke={OKLCH_RGB_BOUNDARY_COLOR} ref={sRGBBoundary} />
</svg>

<svg class="c-color-picker__handler" width={PICKER_SIZE} height={PICKER_SIZE}>
<g ref={manipulatorColorPicker} transform="translate(0,0)">
Expand Down
1 change: 1 addition & 0 deletions ui/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const LOW_RES_PICKER_SIZE = PICKER_SIZE / lOW_RES_FACTOR;
export const LOW_RES_PICKER_SIZE_OKLCH = PICKER_SIZE / lOW_RES_FACTOR_OKLCH;

export const OKLCH_CHROMA_SCALE = 2.7;
export const OKLCH_RGB_BOUNDARY_COLOR = '#ffffff';

// Set this to true to get all the function calls in the console.
export const debugMode = false;
11 changes: 1 addition & 10 deletions ui/shaders/f_shader.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,8 @@ void main()

if (showP3) {
col = oklch2p3(oklch);

bool isInRgb = isInBounds(oklabRGB);
if (!isInRgb) {
float maxChroma = sRGBMaxChroma(oklch);
if (abs(c - maxChroma) < 0.002) {
col = vec3(1, 1, 1);
// col = pow(col,vec3(1./1.2)); increase gamma pixel out sRGB
}
}
} else {
col = pow(col,vec3(1./2.4)); // sRGB gamma correction
col = pow(col,vec3(1./2.2)); // sRGB gamma correction
}

bool inBounds = isInBounds(col);
Expand Down
15 changes: 0 additions & 15 deletions ui/shaders/utils.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -115,18 +115,3 @@ vec3 oklch2p3(in vec3 lch) {
bool isInBounds(in vec3 v) {
return all(greaterThanEqual(v, vec3(0.0))) && all(lessThanEqual(v, vec3(1.0)));
}

// backward search max chroma in sRGB space
float sRGBMaxChroma(in vec3 lch) {
float step = 0.0009;
float chroma = lch.y;

for(int i = 0; i < 100; i++) {
if (isInBounds(oklch2srgb(vec3(lch.x, chroma, lch.z)))) {
break;
}
chroma -= step;
}

return chroma - step;
}
4 changes: 4 additions & 0 deletions ui/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ select {
.c-color-picker__handler {
pointer-events: none;
}
.c-color-picker__oklch-separator {
position: absolute;
pointer-events: none;
}


body.deactivated .c-bottom-controls {
Expand Down

0 comments on commit ca4a98f

Please sign in to comment.