diff --git a/packages/builder/src/components/userInterface/Colorpicker/Colorpicker.svelte b/packages/builder/src/components/userInterface/Colorpicker/Colorpicker.svelte new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/builder/src/components/userInterface/Colorpicker/utils/HSVAColor.js b/packages/builder/src/components/userInterface/Colorpicker/utils/HSVAColor.js new file mode 100644 index 0000000000..e39e700903 --- /dev/null +++ b/packages/builder/src/components/userInterface/Colorpicker/utils/HSVAColor.js @@ -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] + } +} diff --git a/packages/builder/src/components/userInterface/Colorpicker/utils/utils.js b/packages/builder/src/components/userInterface/Colorpicker/utils/utils.js new file mode 100644 index 0000000000..7412c42e27 --- /dev/null +++ b/packages/builder/src/components/userInterface/Colorpicker/utils/utils.js @@ -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] +}