forked from tsai/budibase
3 changed files with 174 additions and 0 deletions
@ -0,0 +1,66 @@ |
|||
import { |
|||
getHexaValues, |
|||
getRgbaValues, |
|||
hsvToHSL, |
|||
isValidRgba, |
|||
rgbToHSV, |
|||
hsvToRgb, |
|||
} from "./utils" |
|||
|
|||
export class HSVAColor { |
|||
h = 0 |
|||
s = 0 |
|||
v = 0 |
|||
a = 1 |
|||
|
|||
constructor(color) { |
|||
if (color.startsWith("#")) { |
|||
let [rHex, gHex, bHex, aHex] = getHexaValues(color) |
|||
this.hexaToHSVA([rHex, gHex, bHex], aHex) |
|||
} else if (color.startsWith("rgb")) { |
|||
let rgba = getRgbaValues(color) |
|||
this.rgbaToHSVA(rgba) |
|||
} |
|||
} |
|||
|
|||
setHSVA([h, s, v, a]) { |
|||
this.h = h |
|||
this.s = s |
|||
this.v = v |
|||
this.a = a |
|||
} |
|||
|
|||
getHSLA() { |
|||
const [h, s, l] = hsvToHSL([this.h, this.s, this.v]) |
|||
return `hsla(${h}, ${s}, ${l}, ${this.a})` |
|||
} |
|||
|
|||
hexaToHSVA(hex, alpha = "FF") { |
|||
const rgba = hex |
|||
.map(v => parseInt(v, 16)) |
|||
.concat((parseInt(alpha, 16) / 255).toFixed(1)) |
|||
this.rgbaToHSVA(rgba) |
|||
} |
|||
|
|||
rgbaToHSVA(rgba) { |
|||
if (isValidRgba(rgba)) { |
|||
const [r, g, b, a = "1"] = rgba |
|||
let hsv = rgbToHSV([r, g, b]) |
|||
this.setHSVA([...hsv, a]) |
|||
} |
|||
} |
|||
|
|||
hsvaToHexa() { |
|||
const [r, g, b, a] = this.hsvaToRgba() |
|||
const hexa = [r, g, b] |
|||
.map(v => v.toString(16)) |
|||
.concat((a * 255).toFixed(1).toString(16)) |
|||
return hexa |
|||
} |
|||
|
|||
hsvaToRgba() { |
|||
const { h, s, v, a } = this |
|||
let rgb = hsvToRgb([h, s, v]) |
|||
return [...rgb, a] |
|||
} |
|||
} |
|||
@ -0,0 +1,108 @@ |
|||
export const getRgbaValues = rgbaString => |
|||
rgbaString.replace(/[a-z\(\)\s]/gi, "").split(",") |
|||
|
|||
export const getHexaValues = hexString => |
|||
hexString.match(/[A-F]{2}|[A-F]\d{1}|\d{2}|\d[A-F]/gi) |
|||
|
|||
export const isValidRgba = rgba => { |
|||
let [r, g, b, a = 1] = rgba |
|||
|
|||
let isValidLengthRange = rgba.length === 3 || rgba.length === 4 |
|||
let isValidColorRange = [r, g, b].every(v => v >= 0 && v <= 255) |
|||
let isValidAlphaRange = rgba.length === 3 || (a >= 0 && a <= 1) |
|||
|
|||
return isValidLengthRange && isValidColorRange && isValidAlphaRange |
|||
} |
|||
|
|||
//Credit : https://github.com/Qix-/color-convert
|
|||
export const rgbToHSV = rgb => { |
|||
let rdif |
|||
let gdif |
|||
let bdif |
|||
let h |
|||
let s |
|||
|
|||
const r = rgb[0] / 255 |
|||
const g = rgb[1] / 255 |
|||
const b = rgb[2] / 255 |
|||
const v = Math.max(r, g, b) |
|||
const diff = v - Math.min(r, g, b) |
|||
const diffc = function(c) { |
|||
return (v - c) / 6 / diff + 1 / 2 |
|||
} |
|||
|
|||
if (diff === 0) { |
|||
h = 0 |
|||
s = 0 |
|||
} else { |
|||
s = diff / v |
|||
rdif = diffc(r) |
|||
gdif = diffc(g) |
|||
bdif = diffc(b) |
|||
|
|||
if (r === v) { |
|||
h = bdif - gdif |
|||
} else if (g === v) { |
|||
h = 1 / 3 + rdif - bdif |
|||
} else if (b === v) { |
|||
h = 2 / 3 + gdif - rdif |
|||
} |
|||
|
|||
if (h < 0) { |
|||
h += 1 |
|||
} else if (h > 1) { |
|||
h -= 1 |
|||
} |
|||
} |
|||
|
|||
const hsvResult = [h * 360, s * 100, v * 100].map(v => v.toFixed(0)) |
|||
return hsvResult |
|||
} |
|||
|
|||
//Credit : https://github.com/Qix-/color-convert
|
|||
export const hsvToRgb = hsv => { |
|||
const h = hsv[0] / 60 |
|||
const s = hsv[1] / 100 |
|||
let v = hsv[2] / 100 |
|||
const hi = Math.floor(h) % 6 |
|||
|
|||
const f = h - Math.floor(h) |
|||
const p = 255 * v * (1 - s) |
|||
const q = 255 * v * (1 - s * f) |
|||
const t = 255 * v * (1 - s * (1 - f)) |
|||
v *= 255 |
|||
|
|||
switch (hi) { |
|||
case 0: |
|||
return [v, t, p] |
|||
case 1: |
|||
return [q, v, p] |
|||
case 2: |
|||
return [p, v, t] |
|||
case 3: |
|||
return [p, q, v] |
|||
case 4: |
|||
return [t, p, v] |
|||
case 5: |
|||
return [v, p, q] |
|||
} |
|||
} |
|||
|
|||
//Credit : https://github.com/Qix-/color-convert
|
|||
export const hsvToHSL = hsv => { |
|||
const h = hsv[0] |
|||
const s = hsv[1] / 100 |
|||
const v = hsv[2] / 100 |
|||
const vmin = Math.max(v, 0.01) |
|||
let sl |
|||
let l |
|||
|
|||
l = (2 - s) * v |
|||
const lmin = (2 - s) * vmin |
|||
sl = s * vmin |
|||
sl /= lmin <= 1 ? lmin : 2 - lmin |
|||
sl = sl || 0 |
|||
l /= 2 |
|||
|
|||
return [h, sl * 100, l * 100] |
|||
} |
|||
Loading…
Reference in new issue