|
@@ -1,5 +1,5 @@
|
|
|
/**
|
|
|
- * Copyright (c) 2018-2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
*
|
|
|
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
|
*/
|
|
@@ -15,19 +15,19 @@ export type Color = { readonly '@type': 'color' } & number
|
|
|
export function Color(hex: number) { return hex as Color; }
|
|
|
|
|
|
export namespace Color {
|
|
|
- export function toStyle(hexColor: Color) {
|
|
|
+ export function toStyle(hexColor: Color): string {
|
|
|
return `rgb(${hexColor >> 16 & 255}, ${hexColor >> 8 & 255}, ${hexColor & 255})`;
|
|
|
}
|
|
|
|
|
|
- export function toHexStyle(hexColor: Color) {
|
|
|
+ export function toHexStyle(hexColor: Color): string {
|
|
|
return '#' + ('000000' + hexColor.toString(16)).slice(-6);
|
|
|
}
|
|
|
|
|
|
- export function toHexString(hexColor: Color) {
|
|
|
+ export function toHexString(hexColor: Color): string {
|
|
|
return '0x' + ('000000' + hexColor.toString(16)).slice(-6);
|
|
|
}
|
|
|
|
|
|
- export function toRgbString(hexColor: Color) {
|
|
|
+ export function toRgbString(hexColor: Color): string {
|
|
|
return `RGB: ${Color.toRgb(hexColor).join(', ')}`;
|
|
|
}
|
|
|
|
|
@@ -64,7 +64,7 @@ export namespace Color {
|
|
|
}
|
|
|
|
|
|
/** Copies hex color to rgb array */
|
|
|
- export function toArray(hexColor: Color, array: NumberArray, offset: number) {
|
|
|
+ export function toArray<T extends NumberArray>(hexColor: Color, array: T, offset: number): T {
|
|
|
array[offset] = (hexColor >> 16 & 255);
|
|
|
array[offset + 1] = (hexColor >> 8 & 255);
|
|
|
array[offset + 2] = (hexColor & 255);
|
|
@@ -72,7 +72,7 @@ export namespace Color {
|
|
|
}
|
|
|
|
|
|
/** Copies normalized (0 to 1) hex color to rgb array */
|
|
|
- export function toArrayNormalized<T extends NumberArray>(hexColor: Color, array: T, offset: number) {
|
|
|
+ export function toArrayNormalized<T extends NumberArray>(hexColor: Color, array: T, offset: number): T {
|
|
|
array[offset] = (hexColor >> 16 & 255) / 255;
|
|
|
array[offset + 1] = (hexColor >> 8 & 255) / 255;
|
|
|
array[offset + 2] = (hexColor & 255) / 255;
|
|
@@ -80,7 +80,7 @@ export namespace Color {
|
|
|
}
|
|
|
|
|
|
/** Copies hex color to rgb vec3 */
|
|
|
- export function toVec3(out: Vec3, hexColor: Color) {
|
|
|
+ export function toVec3(out: Vec3, hexColor: Color): Vec3 {
|
|
|
out[0] = (hexColor >> 16 & 255);
|
|
|
out[1] = (hexColor >> 8 & 255);
|
|
|
out[2] = (hexColor & 255);
|
|
@@ -88,7 +88,7 @@ export namespace Color {
|
|
|
}
|
|
|
|
|
|
/** Copies normalized (0 to 1) hex color to rgb vec3 */
|
|
|
- export function toVec3Normalized(out: Vec3, hexColor: Color) {
|
|
|
+ export function toVec3Normalized(out: Vec3, hexColor: Color): Vec3 {
|
|
|
out[0] = (hexColor >> 16 & 255) / 255;
|
|
|
out[1] = (hexColor >> 8 & 255) / 255;
|
|
|
out[2] = (hexColor & 255) / 255;
|
|
@@ -131,13 +131,38 @@ export namespace Color {
|
|
|
return darken(c, -amount);
|
|
|
}
|
|
|
|
|
|
+ function _luminance(x: number): number {
|
|
|
+ return x <= 0.03928 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Relative luminance
|
|
|
+ * http://www.w3.org/TR/2008/REC-WCAG20-20081211/#relativeluminancedef
|
|
|
+ */
|
|
|
+ export function luminance(c: Color): number {
|
|
|
+ const r = _luminance((c >> 16 & 255) / 255);
|
|
|
+ const g = _luminance((c >> 8 & 255) / 255);
|
|
|
+ const b = _luminance((c & 255) / 255);
|
|
|
+ return 0.2126 * r + 0.7152 * g + 0.0722 * b;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * WCAG contrast ratio
|
|
|
+ * http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef
|
|
|
+ */
|
|
|
+ export function contrast(a: Color, b: Color): number {
|
|
|
+ const l1 = luminance(a);
|
|
|
+ const l2 = luminance(b);
|
|
|
+ return l1 > l2 ? (l1 + 0.05) / (l2 + 0.05) : (l2 + 0.05) / (l1 + 0.05);
|
|
|
+ };
|
|
|
+
|
|
|
//
|
|
|
|
|
|
- function _sRGBToLinear(c: number) {
|
|
|
+ function _sRGBToLinear(c: number): number {
|
|
|
return (c < 0.04045) ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
|
|
|
}
|
|
|
|
|
|
- export function sRGBToLinear(c: Color) {
|
|
|
+ export function sRGBToLinear(c: Color): Color {
|
|
|
return fromNormalizedRgb(
|
|
|
_sRGBToLinear((c >> 16 & 255) / 255),
|
|
|
_sRGBToLinear((c >> 8 & 255) / 255),
|
|
@@ -145,11 +170,11 @@ export namespace Color {
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- function _linearToSRGB(c: number) {
|
|
|
+ function _linearToSRGB(c: number): number {
|
|
|
return (c < 0.0031308) ? c * 12.92 : 1.055 * (Math.pow(c, 0.41666)) - 0.055;
|
|
|
}
|
|
|
|
|
|
- export function linearToSRGB(c: Color) {
|
|
|
+ export function linearToSRGB(c: Color): Color {
|
|
|
return fromNormalizedRgb(
|
|
|
_linearToSRGB((c >> 16 & 255) / 255),
|
|
|
_linearToSRGB((c >> 8 & 255) / 255),
|