hsl rgb color conversion

This commit is contained in:
Rüdiger Diedrich 2021-09-10 11:44:50 +02:00
parent b67adb823d
commit 1c78ab3522
4 changed files with 79 additions and 6 deletions

BIN
src/assets/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -1,11 +1,20 @@
import { mergeProps } from "solid-js";
function ColorInput(props) {
type ColorInputProps = {
label: string;
min: number;
max: number;
value: number;
onInput: (a: number) => void;
step?: number
}
function ColorInput(props: ColorInputProps) {
const options = mergeProps({ step: 1 }, props);
const setValue = (e) => {
let value = parseFloat(e.currentTarget.value);
options.onInput(value);
const setValue = (e: InputEvent) => {
let eventTarget = e.currentTarget as HTMLInputElement;
options.onInput(parseFloat(eventTarget.value));
}
return (

View File

@ -1,11 +1,74 @@
import { useHslaContext } from "/@/hsla-context";
import ColorInput from "/@lib/color-input";
function Colorer(props) {
function Colorer() {
const [hsla, { setH, setS, setL, setA }] = useHslaContext();
const hslColor = () => `hsla(${hsla().h}, ${hsla().s}%, ${hsla().l}%, ${hsla().a})`;
const rgbColor = () => {
const [r, g, b] = hsl2rgb(hsla().h, hsla().s / 100, hsla().l / 100)
return `rbga(${r}, ${g}, ${b}, ${hsla().a})`
}
const hsl2rgb = (h: number, s: number, l: number) => {
const defrange = {
h: (h: number) => 0 <= h && h < 360,
s: (s: number) => 0 <= s && s <= 1,
l: (l: number) => 0 <= l && l <= 1
}
if (!defrange.h(h)) throw "h out of range"
if (!defrange.s(s)) throw "s out of range"
if (!defrange.l(l)) throw "l out of range"
let c = (1 - Math.abs(2 * l - 1)) * s
let x = c * (1 - Math.abs((h / 60) % 2 - 1))
let m = l - (c / 2)
const rgb = (rd: number, gd: number, bd: number) => [
Math.ceil((rd + m) * 255),
Math.ceil((gd + m) * 255),
Math.ceil((bd + m) * 255)
]
if (h < 60) return rgb(c, x, 0)
else if (h < 120) return rgb(x, c, 0)
else if (h < 180) return rgb(0, c, x)
else if (h < 240) return rgb(0, x, c)
else if (h < 300) return rgb(x, 0, c)
else return rgb(c, 0, x)
}
const rgb2hsl = (r: number, g: number, b: number) => {
const
rd = r / 255,
gd = g / 255,
bd = b / 255,
cmax = Math.max(rd, gd, bd),
cmin = Math.min(rd, gd, bd),
delta = (cmax - cmin),
l = (cmax + cmin) / 2
let
h: number = 0,
s: number = 0
// for this case h and s == 0
if (delta === 0)
return [h, s, l]
if (cmax == rd)
h = ((gd - bd) / delta) + (gd < bd ? 6 : 0)
else if (cmax == gd)
h = ((bd - rd) / delta) + 2
else if (cmax == bd)
h = ((rd - gd) / delta) + 4
h = 60 * h
s = delta / (1 - Math.abs(2 * l - 1))
return [h, s, l]
}
return (
<div class="main-container">
<div id="colorer">
@ -17,7 +80,7 @@ function Colorer(props) {
<div class="color-box" style={{
"background-color": hslColor()
}}></div>
<pre>{hslColor()}</pre>
<pre>{rgbColor()} {hslColor()}</pre>
</div>
);
}

View File

@ -6,6 +6,7 @@
"allowSyntheticDefaultImports": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"strict": true,
"jsx": "preserve",
"jsxImportSource": "solid-js",
"types": ["vite/client"]