Coloris icon indicating copy to clipboard operation
Coloris copied to clipboard

Alpha channel loses information

Open ut4 opened this issue 9 months ago • 5 comments

When pasting a transparent color into the picker, such as #000000d7, it gets converted to #000000d6 (another example is #00000022 -> #00000021). I believe this is due to the a * 255 | 0 conversion in the RGBAToHex function. Is this conversion necessary, or could it be removed? Here is a proposed fix that addresses the issue:

@@ -922,16 +922,23 @@
     if (rgba.b < 16) {
       B = '0' + B;
     }
 
     if (settings.alpha && (rgba.a < 1 || settings.forceAlpha)) {
-      const alpha = rgba.a * 255 | 0;
-      A = alpha.toString(16);
-
-      if (alpha < 16) {
-        A = '0' + A;
-      }
+      const alphaHex = rgba.a.toString(16); // Examples: float (hex) -> result
+                                            //           0     (00)  -> '0'
+                                            //           0.01  (01)  -> '0.028f5c28f5c28f6'
+                                            //           0.133 (22)  -> '0.220c49ba5e354'
+                                            //           0.843 (d7)  -> '0.d7ced916872b'
+                                            //           0.98  (fa)  -> '0.fae147ae147ae'
+                                            //           0.996 (fe)  -> '0.fef9db22d0e56'
+                                            //           1     (ff)  -> '1'
+      A = (function () {
+        if (alphaHex === '0') return '00';
+        if (alphaHex === '1') return 'ff';
+        return alphaHex.slice(2, 4);
+      })();
     }
 
     return '#' + R + G + B + A;
   }

Alternatively:

@@ -922,16 +922,12 @@
     if (rgba.b < 16) {
       B = '0' + B;
     }
 
     if (settings.alpha && (rgba.a < 1 || settings.forceAlpha)) {
-      const alpha = rgba.a * 255 | 0;
-      A = alpha.toString(16);
-
-      if (alpha < 16) {
-        A = '0' + A;
-      }
+      const alphaHex = rgba.a.toString(16); // Examples: '0', '0.220c49ba5e354', '1'
+      A = alphaHex === '0' ? '00' : alphaHex === '1' ? 'ff' : alphaHex.slice(2, 4);
     }
 
     return '#' + R + G + B + A;
   }

Feel free to adjust the code and comments as necessary.

ut4 avatar May 18 '24 10:05 ut4