Ver código fonte

add Color.contrast/.luminance

Alexander Rose 2 anos atrás
pai
commit
72055442b7
1 arquivos alterados com 38 adições e 13 exclusões
  1. 38 13
      src/mol-util/color/color.ts

+ 38 - 13
src/mol-util/color/color.ts

@@ -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),