Commit 25b0ead4 authored by Zéfling's avatar Zéfling 🎨

Add support to hsl() color

parent dc4471fe
......@@ -3,7 +3,8 @@
const pattern = {
hexa: /^^#?(([\da-f]{3})(([\da-f]{3})([\da-f]{2})?|[\da-f]{1})?)$/i,
rgba: /^rgba?\(([\d]*(\.[\d]+)?)(,?\s*|\s+)([\d]*(\.[\d]+)?)(,?\s*|\s+)([\d]*(\.[\d]+)?)((,\s*)([\d]*(\.[\d]+)?))?\)$/i
rgba: /^rgba?\(([\d]*(\.[\d]+)?)(,?\s*|\s+)([\d]*(\.[\d]+)?)(,?\s*|\s+)([\d]*(\.[\d]+)?)((,\s*)([\d]*(\.[\d]+)?))?\)$/i,
hsva: /^hsla?\(([\d]*(\.[\d]+)?)(,?\s*|\s+)([\d]*(\.[\d]+)?)\%(,?\s*|\s+)([\d]*(\.[\d]+)?)\%((,\s*)([\d]*(\.[\d]+)?))?\)$/i
};
export class Coloration {
......@@ -49,7 +50,18 @@ export class Coloration {
rebeccapurple: '#663399'
};
constructor(public color: string) { }
private intColor: number;
constructor(public color: string) {
this.intColor = this.parseColor(color);
}
/**
* HEX color
*/
getColor() {
return this.intRbgToString(this.intColor);
}
/**
* change the luminosity of a color
......@@ -76,11 +88,11 @@ export class Coloration {
const R = baseColor >> 16;
const G = baseColor >> 8 & 0x00FF;
const B = baseColor & 0x0000FF;
return '#' + (0x1000000 +
(Math.round(((additionalColor >> 16) - R) * lum) + R) * 0x10000
+ (Math.round(((additionalColor >> 8 & 0x00FF) - G) * lum) + G) * 0x100
+ (Math.round(((additionalColor & 0x0000FF) - B) * lum) + B)
).toString(16).slice(1);
return this.intRbgToString(this.rgbToInt(
Math.round(((additionalColor >> 16) - R) * lum) + R,
Math.round(((additionalColor >> 8 & 0x00FF) - G) * lum) + G,
Math.round(((additionalColor & 0x0000FF) - B) * lum) + B
));
}
/**
......@@ -110,7 +122,15 @@ export class Coloration {
// validate rgb() / rgba()
const matchRgb = String(color).match(pattern.rgba);
if (matchRgb) {
intColor = parseInt(matchRgb[1], 10) * 65536 + parseInt(matchRgb[3], 10) * 256 + parseInt(matchRgb[5], 10);
intColor = this.rgbToInt(parseInt(matchRgb[1], 10), parseInt(matchRgb[4], 10), parseInt(matchRgb[7], 10));
}
}
if (intColor === undefined) {
// validate hsv() / hsva()
const matchHsv = String(color).match(pattern.hsva);
if (matchHsv) {
intColor = this.hsv(parseInt(matchHsv[1], 10), parseInt(matchHsv[4], 10), parseInt(matchHsv[7], 10));
}
}
......@@ -118,4 +138,48 @@ export class Coloration {
}
/**
* convert HSV/HSL to int RGB
* @param hue Hue [0, 360]
* @param saturation Saturation [0, 100]
* @param value Value [0, 100]
* @returns int RGB
* @see https://stackoverflow.com/questions/2353211/hsl-to-rgb-color-conversion
*/
private hsv(hue: number, saturation: number, value: number): number {
saturation = Math.max(0, saturation);
const s = saturation / 100;
const v = value / 100;
const h = hue / 360;
if (saturation === 0) {
return this.rgbToInt(v * 256, v * 256, v * 256);
}
const q = v < 0.5 ? v * (1 + s) : v + s - v * s;
const p = 2 * v - q;
const r = this.hue2rgb(p, q, h + 1 / 3);
const g = this.hue2rgb(p, q, h);
const b = this.hue2rgb(p, q, h - 1 / 3);
return this.rgbToInt(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255));
}
private hue2rgb(p: number, q: number, t: number): number {
if (t < 0) { t += 1; } else if (t > 1) { t -= 1; }
if (t < 1 / 6) { return p + (q - p) * 6 * t; }
if (t < 1 / 2) { return q; }
if (t < 2 / 3) { return p + (q - p) * (2 / 3 - t) * 6; }
return p;
}
private rgbToInt(r: number, g: number, b: number): number {
return r * 0x10000 + g * 0x100 + b;
}
private intRbgToString(int: number) {
return '#' + (0x1000000 + int).toString(16).slice(1);
}
}
......@@ -22,4 +22,12 @@
<hr>
<div>Color : {{color}}</div>
<div>ColorFinal : {{colorFinal}}</div>
<div [style.background-color]="colorFinal">&nbsp;</div>
\ No newline at end of file
<div [style.background-color]="colorFinal">&nbsp;</div>
<hr>
<div>ColorRgb : {{colorRgb}} -> {{colorRgbHex}}</div>
<div [style.background-color]="colorRgb">&nbsp;</div>
<div [style.background-color]="colorRgbHex">&nbsp;</div>
<hr>
<div>ColorHsv : {{colorHsv}} -> {{colorHsvHex}}</div>
<div [style.background-color]="colorHsv">&nbsp;</div>
<div [style.background-color]="colorHsvHex">&nbsp;</div>
\ No newline at end of file
......@@ -10,6 +10,10 @@ export class AppComponent {
title = 'coloration-demo';
color = '#FF0000';
colorRgb = 'rgb(50, 75, 255)';
colorRgbHex: string;
colorHsv = 'hsl(300, 50%, 70%)';
colorHsvHex: string;
luminosity = 0;
......@@ -17,6 +21,13 @@ export class AppComponent {
constructor() {
this.calculColor();
const colorRgb = new Coloration(this.colorRgb);
this.colorRgbHex = colorRgb.getColor();
const colorHsv = new Coloration(this.colorHsv);
this.colorHsvHex = colorHsv.getColor();
}
changeColor(event: Event) {
......@@ -33,4 +44,5 @@ export class AppComponent {
const color = new Coloration(this.color);
this.colorFinal = color.changeLuminosity(this.luminosity);
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment