Utils update and Jest Tests
This commit is contained in:
parent
e1ecc3f31b
commit
ed1b30d83a
|
@ -1,23 +1,28 @@
|
||||||
<script>
|
<script>
|
||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import { getAndConvertHexa, getAndConvertRgba, getHSLA, hsvaToHexa, hsvaToRgba } from "./utils.js"
|
import { getAndConvertHexa, getAndConvertRgba, getHSLA, hsvaToHexa, hsvaToRgba, getColorFormat, convertToHSVA } from "./utils.js"
|
||||||
import Slider from "./Slider.svelte";
|
import Slider from "./Slider.svelte";
|
||||||
import Palette from "./Palette.svelte";
|
import Palette from "./Palette.svelte";
|
||||||
|
|
||||||
export let value = "#00bfffff";
|
export let value = "rgba(255,255,255,1)";
|
||||||
export let format = "hexa";
|
export let format = "hexa";
|
||||||
|
|
||||||
let h = 0;
|
let h = null;
|
||||||
let s = 0;
|
let s = null;
|
||||||
let v = 0;
|
let v = null;
|
||||||
let a = 1;
|
let a = null;
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
let hsva = getFormatAndConvert(value)
|
format = getColorFormat(value)
|
||||||
|
if(format) {
|
||||||
|
let hsva = convertToHSVA(value, format)
|
||||||
setHSVA(hsva)
|
setHSVA(hsva)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
function getFormatAndConvert() {
|
const hsvaIsNull = () => [h,s,v,a].every(c => c === null)
|
||||||
|
|
||||||
|
function setFormatAndConvert() {
|
||||||
if (value.startsWith('#')) {
|
if (value.startsWith('#')) {
|
||||||
format = "hexa"
|
format = "hexa"
|
||||||
return getAndConvertHexa(value)
|
return getAndConvertHexa(value)
|
||||||
|
@ -29,20 +34,47 @@
|
||||||
|
|
||||||
function setHSVA([hue, sat, val, alpha]) {
|
function setHSVA([hue, sat, val, alpha]) {
|
||||||
h = hue;
|
h = hue;
|
||||||
s = sat / 100;
|
s = sat;
|
||||||
v - val / 100;
|
v = val;
|
||||||
a = alpha;
|
a = alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//fired by choosing a color from the palette
|
||||||
function setSaturationAndValue({detail}) {
|
function setSaturationAndValue({detail}) {
|
||||||
s = detail.s
|
s = detail.s
|
||||||
v = detail.v
|
v = detail.v
|
||||||
|
let res = convertHSVA()
|
||||||
|
console.log("SAT-VAL", res)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setHue(hue) {
|
||||||
|
h = hue
|
||||||
|
let res = convertHSVA()
|
||||||
|
console.log("HUE",res)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setAlpha(alpha) {
|
||||||
|
a = alpha
|
||||||
|
let res = convertHSVA()
|
||||||
|
console.log("ALPHA",res)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertHSVA() {
|
||||||
|
let hsva = [h, s, v, a]
|
||||||
|
let _value = format === "hexa" ? hsvaToHexa(hsva, true) : hsvaToRgba(hsva, true)
|
||||||
|
return _value;
|
||||||
|
// onchange(_value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// $: {
|
// $: {
|
||||||
|
// if(!hsvaIsNull()) {
|
||||||
// let hsva = [h, s, v, a]
|
// let hsva = [h, s, v, a]
|
||||||
|
// // let t = value + "abs"
|
||||||
// value = format === "hexa" ? hsvaToHexa(hsva) : hsvaToRgba(hsva)
|
// value = format === "hexa" ? hsvaToHexa(hsva) : hsvaToRgba(hsva)
|
||||||
// console.log("VAL", value)
|
// debugger
|
||||||
|
// // console.log("VAL", value)
|
||||||
|
// }
|
||||||
// }
|
// }
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -62,7 +94,7 @@
|
||||||
|
|
||||||
<Palette on:change={setSaturationAndValue} {h} {s} {v} {a} />
|
<Palette on:change={setSaturationAndValue} {h} {s} {v} {a} />
|
||||||
|
|
||||||
<Slider type="hue" value={h} on:change={hue => (h = hue.detail)} />
|
<Slider type="hue" value={h} on:change={hue => setHue(hue.detail)} />
|
||||||
|
|
||||||
<Slider type="alpha" value={a} on:change={alpha => (a = alpha.detail)} />
|
<Slider type="alpha" value={a} on:change={alpha => setAlpha(alpha.detail)} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,17 +1,82 @@
|
||||||
export const getRgbaValues = (rgbaString) => rgbaString.replace(/[a-z()\s]/gi, '').split(',');
|
export const isValidHex = (str) => /^#(?:[A-F0-9]{3}$|[A-F0-9]{6}$|[A-F0-9]{8})$/gi.test(str)
|
||||||
|
|
||||||
export const getHexaValues = (hexString) => hexString.match(/[A-F]{2}|[A-F]\d{1}|\d{2}|\d[A-F]/gi);
|
const getHexaValues = (hexString) => hexString.match(/[A-F0-9]{2}/gi);
|
||||||
|
|
||||||
export const isValidRgba = (rgba) => {
|
export const isValidRgb = (str) => {
|
||||||
let [ r, g, b, a = 1 ] = rgba;
|
const hasValidStructure = /^(?:rgba\(|rgb\()[0-9,.\s]*\)$/gi.test(str);
|
||||||
|
if(hasValidStructure) {
|
||||||
|
return testRgbaValues(str.toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let isValidLengthRange = rgba.length === 3 || rgba.length === 4;
|
const findNonNumericChars = /[a-z()%\s]/gi
|
||||||
|
|
||||||
|
export const getNumericValues = (str) => str.replace(findNonNumericChars, '').split(',').map(c => Number(c));
|
||||||
|
|
||||||
|
export const testRgbaValues = (str) => {
|
||||||
|
const rgba = getNumericValues(str)
|
||||||
|
let [ r, g, b, a ] = rgba;
|
||||||
|
|
||||||
|
let isValidLengthRange = (str.startsWith("rgb(") && rgba.length === 3) || (str.startsWith("rgba(") && rgba.length === 4);
|
||||||
let isValidColorRange = [ r, g, b ].every((v) => v >= 0 && v <= 255);
|
let isValidColorRange = [ r, g, b ].every((v) => v >= 0 && v <= 255);
|
||||||
let isValidAlphaRange = rgba.length === 3 || (a >= 0 && a <= 1);
|
let isValidAlphaRange = str.startsWith("rgba(") ? a >= 0 && a <= 1 : true;
|
||||||
|
|
||||||
return isValidLengthRange && isValidColorRange && isValidAlphaRange;
|
return isValidLengthRange && isValidColorRange && isValidAlphaRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isValidHsl = (str) => {
|
||||||
|
const hasValidStructure = /^(?:hsl\(|hsla\()[0-9,.\s]*\)$/gi.test(str)
|
||||||
|
if(hasValidStructure) {
|
||||||
|
return testHslaValues(str.toLowerCase())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const testHslaValues = (str) => {
|
||||||
|
|
||||||
|
const hsla = getNumericValues(str)
|
||||||
|
const [h, s, l, a] = hsla
|
||||||
|
|
||||||
|
let isValidLengthRange = (str.startsWith("hsl(") && hsla.length === 3) || (str.startsWith("hsla(") && hsla.length === 4);
|
||||||
|
let isValidColorRange = (h >= 0 && h <= 360) && [s, l].every(v => v >= 0 && v <= 100)
|
||||||
|
let isValidAlphaRange = str.startsWith("hsla(") ? (a >= 0 && a <= 1) : true
|
||||||
|
|
||||||
|
return isValidLengthRange && isValidColorRange && isValidAlphaRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getColorFormat = (color) => {
|
||||||
|
if(typeof color === "string") {
|
||||||
|
if(isValidHex(color)) {
|
||||||
|
return 'hex'
|
||||||
|
}else if(isValidRgb(color)) {
|
||||||
|
return 'rgb'
|
||||||
|
}else if(isValidHsl(color)) {
|
||||||
|
return 'hsl'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const convertToHSVA = (value, format) => {
|
||||||
|
switch(format) {
|
||||||
|
case "hex":
|
||||||
|
return getAndConvertHexa(value)
|
||||||
|
case "rgb":
|
||||||
|
return getAndConvertRgba(value)
|
||||||
|
case "hsl":
|
||||||
|
return getAndConvertHsla(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const convertHsvaToFormat = (hsva, format) => {
|
||||||
|
switch(format) {
|
||||||
|
case "hex":
|
||||||
|
return hsvaToHexa(hsva, true)
|
||||||
|
case "rgb":
|
||||||
|
return hsvaToRgba(hsva, true)
|
||||||
|
case "hsl":
|
||||||
|
return hsvaToHsla(hsva, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export const getAndConvertHexa = (color) => {
|
export const getAndConvertHexa = (color) => {
|
||||||
let [ rHex, gHex, bHex, aHex ] = getHexaValues(color);
|
let [ rHex, gHex, bHex, aHex ] = getHexaValues(color);
|
||||||
|
@ -19,40 +84,71 @@ export const getAndConvertHexa = (color) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getAndConvertRgba = color => {
|
export const getAndConvertRgba = color => {
|
||||||
let rgba = getRgbaValues(color);
|
let rgba = getNumericValues(color);
|
||||||
return rgbaToHSVA(rgba);
|
return rgbaToHSVA(rgba);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getAndConvertHsla = color => {
|
||||||
|
let hsla = getNumericValues(color);
|
||||||
|
return hslaToHSVA(hsla)
|
||||||
|
}
|
||||||
|
|
||||||
export const getHSLA = ([hue, sat, val, a]) => {
|
export const getHSLA = ([hue, sat, val, a]) => {
|
||||||
const [ h, s, l ] = _hsvToHSL([hue, sat, val]);
|
const [ h, s, l ] = _hsvToHSL([hue, sat, val]);
|
||||||
return `hsla(${h}, ${s}, ${l}, ${a})`;
|
return `hsla(${h}, ${s}, ${l}, ${a})`;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const hexaToHSVA = (hex, alpha = 'FF') => {
|
export const hexaToHSVA = (hex, alpha = 'FF') => {
|
||||||
const rgba = hex.map((v) => parseInt(v, 16)).concat((parseInt(alpha, 16) / 255).toFixed(1));
|
const rgba = hex.map((v) => parseInt(v, 16)).concat(Number((parseInt(alpha, 16) / 255).toFixed(2)));
|
||||||
return rgbaToHSVA(rgba);
|
return rgbaToHSVA(rgba);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const rgbaToHSVA = (rgba) => {
|
export const rgbaToHSVA = (rgba) => {
|
||||||
if (isValidRgba(rgba)) {
|
const [ r, g, b, a = 1 ] = rgba;
|
||||||
const [ r, g, b, a = '1' ] = rgba;
|
|
||||||
let hsv = _rgbToHSV([ r, g, b ]);
|
let hsv = _rgbToHSV([ r, g, b ]);
|
||||||
return [ ...hsv, a ];
|
return [ ...hsv, a ];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const hslaToHSVA = ([h, s, l, a = 1]) => {
|
||||||
|
let hsv = _hslToHSV([h, s, l])
|
||||||
|
return [...hsv, a]
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
export const hsvaToHexa = (hsva) => {
|
export const hsvaToHexa = (hsva, asString = false) => {
|
||||||
const [ r, g, b, a ] = hsvaToRgba(hsva);
|
const [ r, g, b, a ] = hsvaToRgba(hsva);
|
||||||
const hexa = [ r, g, b ].map((v) => v.toString(16)).concat((a * 255).toFixed(1).toString(16));
|
|
||||||
return `#${hexa.join()}`
|
const hexa = [ r, g, b ].map((v) => Math.round(v).toString(16)).concat(Math.round((a * 255)).toString(16));
|
||||||
|
return asString ? `#${hexa.join('')}` : hexa
|
||||||
};
|
};
|
||||||
|
|
||||||
export const hsvaToRgba = ([h, s, v, a]) => {
|
export const hsvaToRgba = ([h, s, v, a], asString = false) => {
|
||||||
let rgb = _hsvToRgb([ h, s, v ]);
|
let rgb = _hsvToRgb([ h, s, v ]).map(x => Math.round(x));
|
||||||
let rgba = [ ...rgb, a ];
|
let rgba = [ ...rgb, a ];
|
||||||
return `rgba(${rgba.join(",")})`
|
return asString ? `rgba(${rgba.join(",")})` : rgba
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const hsvaToHsla = ([h, s, v, a = 1], asString = false) => {
|
||||||
|
let hsl = _hsvToHSL([h, s, v])
|
||||||
|
let hsla = [...hsl, a]
|
||||||
|
return asString ? `hsla(${hsla.join(",")})` : hsla
|
||||||
|
}
|
||||||
|
|
||||||
|
export const _hslToHSV = (hsl) => {
|
||||||
|
const h = hsl[0];
|
||||||
|
let s = hsl[1] / 100;
|
||||||
|
let l = hsl[2] / 100;
|
||||||
|
let smin = s;
|
||||||
|
const lmin = Math.max(l, 0.01);
|
||||||
|
|
||||||
|
l *= 2;
|
||||||
|
s *= (l <= 1) ? l : 2 - l;
|
||||||
|
smin *= lmin <= 1 ? lmin : 2 - lmin;
|
||||||
|
const v = (l + s) / 2;
|
||||||
|
const sv = l === 0 ? (2 * smin) / (lmin + smin) : (2 * s) / (l + s);
|
||||||
|
|
||||||
|
return [h, sv * 100, v * 100];
|
||||||
|
}
|
||||||
|
|
||||||
//Credit : https://github.com/Qix-/color-convert
|
//Credit : https://github.com/Qix-/color-convert
|
||||||
export const _rgbToHSV = (rgb) => {
|
export const _rgbToHSV = (rgb) => {
|
||||||
let rdif;
|
let rdif;
|
||||||
|
@ -94,7 +190,7 @@ export const _rgbToHSV = (rgb) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const hsvResult = [ h * 360, s * 100, v * 100 ].map((v) => v.toFixed(0));
|
const hsvResult = [ h * 360, s * 100, v * 100 ].map((v) => Math.round(v));
|
||||||
return hsvResult;
|
return hsvResult;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -129,6 +225,7 @@ export const _hsvToRgb = (hsv) => {
|
||||||
|
|
||||||
//Credit : https://github.com/Qix-/color-convert
|
//Credit : https://github.com/Qix-/color-convert
|
||||||
export const _hsvToHSL = (hsv) => {
|
export const _hsvToHSL = (hsv) => {
|
||||||
|
|
||||||
const h = hsv[0];
|
const h = hsv[0];
|
||||||
const s = hsv[1] / 100;
|
const s = hsv[1] / 100;
|
||||||
const v = hsv[2] / 100;
|
const v = hsv[2] / 100;
|
||||||
|
@ -143,5 +240,5 @@ export const _hsvToHSL = (hsv) => {
|
||||||
sl = sl || 0;
|
sl = sl || 0;
|
||||||
l /= 2;
|
l /= 2;
|
||||||
|
|
||||||
return [ h, sl * 100, l * 100 ];
|
return [ h, Number((sl * 100).toFixed(1)), Number((l * 100).toFixed(1)) ];
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
import {getColorFormat, convertToHSVA, convertHsvaToFormat} from "./utils"
|
||||||
|
|
||||||
|
describe('convertToHSVA - convert to hsva from format', () => {
|
||||||
|
test("convert from hexa", () => {
|
||||||
|
expect(convertToHSVA("#f222d382", "hex")).toEqual([309, 86, 95, 0.51])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("convert from hex", () => {
|
||||||
|
expect(convertToHSVA("#f222d3", "hex")).toEqual([309, 86, 95, 1])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("convert from rgba", () => {
|
||||||
|
expect(convertToHSVA("rgba(242, 34, 211, 1)", "rgb")).toEqual([309, 86, 95, 1])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("convert from rgb", () => {
|
||||||
|
expect(convertToHSVA("rgb(150, 80, 255)", "rgb")).toEqual([264, 69, 100, 1])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("convert from from hsl", () => {
|
||||||
|
expect(convertToHSVA("hsl(264, 100%, 65.7%)", "hsl")).toEqual([264, 68.6, 100, 1])
|
||||||
|
})
|
||||||
|
|
||||||
|
test("convert from from hsla", () => {
|
||||||
|
expect(convertToHSVA("hsla(264, 100%, 65.7%, 0.51)", "hsl")).toEqual([264, 68.6, 100, 0.51])
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('convertHsvaToFormat - convert from hsva to format', () => {
|
||||||
|
test('Convert to hexa', () => {
|
||||||
|
expect(convertHsvaToFormat([264, 68.63, 100, 0.5], "hex")).toBe("#9650ff80")
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Convert to rgba', () => {
|
||||||
|
expect(convertHsvaToFormat([264, 68.63, 100, 0.75], "rgb")).toBe("rgba(150,80,255,0.75)")
|
||||||
|
})
|
||||||
|
|
||||||
|
test('Convert to hsla', () => {
|
||||||
|
expect(convertHsvaToFormat([264, 68.63, 100, 1], "hsl")).toBe("hsla(264,100,65.7,1)")
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
describe('Get Color Format', () => {
|
||||||
|
test("Testing valid hex string", () => {
|
||||||
|
expect(getColorFormat("#FFF")).toBe("hex")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Testing invalid hex string", () => {
|
||||||
|
expect(getColorFormat("#FFZ")).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Testing valid hex with alpha", () => {
|
||||||
|
expect(getColorFormat("#FF00BB80")).toBe("hex")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Test valid rgb value", () => {
|
||||||
|
expect(getColorFormat("RGB(255, 20, 50)")).toBe("rgb")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Testing invalid rgb value", () => {
|
||||||
|
expect(getColorFormat("rgb(255, 0)")).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Testing rgb value with alpha", () => {
|
||||||
|
expect(getColorFormat("rgba(255, 0, 50, 0.5)")).toBe("rgb")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Testing rgb value with incorrectly provided alpha", () => {
|
||||||
|
expect(getColorFormat("rgb(255, 0, 50, 0.5)")).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Testing invalid hsl value", () => {
|
||||||
|
expect(getColorFormat("hsla(255, 0)")).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Testing hsla value with alpha", () => {
|
||||||
|
expect(getColorFormat("hsla(150, 60, 50, 0.5)")).toBe("hsl")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Testing hsl value with incorrectly provided alpha", () => {
|
||||||
|
expect(getColorFormat("hsl(150, 0, 50, 0.5)")).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("Testing out of bounds hsl", () => {
|
||||||
|
expect(getColorFormat("hsl(375, 0, 50)")).toBeUndefined()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in New Issue