diff --git a/src/color/stringify.rs b/src/color/stringify.rs index 37d82d8..5964c97 100644 --- a/src/color/stringify.rs +++ b/src/color/stringify.rs @@ -1,7 +1,14 @@ use crate::{ conversion::{ - cmyk::rgb2cmyk, hex::rgb2hex, hsl::rgb2hsl, hsv::rgb2hsv, hwb::rgb2hwb, lab::rgb2lab, - xyz::rgb2xyz, ycbcr::rgb2ycbcr, yuv::rgb2yuv, + cmyk::rgb2cmyk, + hex::{rgb2hex, rgba2hex}, + hsl::rgb2hsl, + hsv::rgb2hsv, + hwb::rgb2hwb, + lab::rgb2lab, + xyz::rgb2xyz, + ycbcr::rgb2ycbcr, + yuv::rgb2yuv, }, helper::round, Color, @@ -17,8 +24,16 @@ impl Color { /// /// let color = Color::new(255.0, 255.0, 255.0, 1.0); /// assert_eq!(color.hex(), "#ffffff"); + /// + /// let color = Color::new(255.0, 255.0, 255.0, 0.5); + /// assert_eq!(color.hex(), "#ffffff80"); /// ``` pub fn hex(self) -> String { + if self.alpha != 1.0 { + // TODO: better way to do this? + let color = (self.rgb.0, self.rgb.1, self.rgb.2, self.alpha); + return rgba2hex(color); + } rgb2hex(self.rgb) } /// `rgb` string of the color diff --git a/src/conversion/hex.rs b/src/conversion/hex.rs index f90889d..e8d4dd5 100644 --- a/src/conversion/hex.rs +++ b/src/conversion/hex.rs @@ -1,3 +1,5 @@ +use crate::{helper::round, ALPHA_HEX_MAP}; + pub fn rgb2hex(color: (f64, f64, f64)) -> String { let (r, g, b) = color; let r = r.round() as u8; @@ -6,6 +8,16 @@ pub fn rgb2hex(color: (f64, f64, f64)) -> String { format!("#{:02x}{:02x}{:02x}", r, g, b) } +pub fn rgba2hex(color: (f64, f64, f64, f64)) -> String { + let (r, g, b, a) = color; + let r = r.round() as u8; + let g = g.round() as u8; + let b = b.round() as u8; + let a = round(a, 2).to_string(); + let a = ALPHA_HEX_MAP.get(a.as_str()).unwrap().to_lowercase(); + format!("#{:02x}{:02x}{:02x}{}", r, g, b, a) +} + pub fn hex2rgb(hex: &str) -> (f64, f64, f64) { let mut hex = String::from(hex); let len = hex.len(); @@ -54,4 +66,27 @@ mod tests { let hex = rgb2hex(rgb); assert_eq!(hex, "#008080"); } + + #[test] + fn test_rgba2hex() { + let rgba = (255.0, 255.0, 255.0, 1.0); + let hex = rgba2hex(rgba); + assert_eq!(hex, "#ffffffff"); + + let rgba = (0.0, 0.0, 0.0, 0.5); + let hex = rgba2hex(rgba); + assert_eq!(hex, "#00000080"); + + let rgba = (0.0, 128.0, 128.0, 0.4); + let hex = rgba2hex(rgba); + assert_eq!(hex, "#00808066"); + + let rgba = (0.0, 128.0, 128.0, 0.23); + let hex = rgba2hex(rgba); + assert_eq!(hex, "#0080803b"); + + let rgba = (0.0, 128.0, 128.0, 0.222222); + let hex = rgba2hex(rgba); + assert_eq!(hex, "#00808038"); + } } diff --git a/src/data/alpha_hex_map.rs b/src/data/alpha_hex_map.rs new file mode 100644 index 0000000..743ede4 --- /dev/null +++ b/src/data/alpha_hex_map.rs @@ -0,0 +1,110 @@ +use std::collections::HashMap; + +lazy_static! { + /// alpha hex map + pub static ref ALPHA_HEX_MAP: HashMap<&'static str, &'static str> = { + HashMap::from([ + ("1", "FF"), + ("0.99", "FC"), + ("0.98", "FA"), + ("0.97", "F7"), + ("0.96", "F5"), + ("0.95", "F2"), + ("0.94", "F0"), + ("0.93", "ED"), + ("0.92", "EB"), + ("0.91", "E8"), + ("0.9", "E6"), + ("0.89", "E3"), + ("0.88", "E0"), + ("0.87", "DE"), + ("0.86", "DB"), + ("0.85", "D9"), + ("0.84", "D6"), + ("0.83", "D4"), + ("0.82", "D1"), + ("0.81", "CF"), + ("0.8", "CC"), + ("0.79", "C9"), + ("0.78", "C7"), + ("0.77", "C4"), + ("0.76", "C2"), + ("0.75", "BF"), + ("0.74", "BD"), + ("0.73", "BA"), + ("0.72", "B8"), + ("0.71", "B5"), + ("0.7", "B3"), + ("0.69", "B0"), + ("0.68", "AD"), + ("0.67", "AB"), + ("0.66", "A8"), + ("0.65", "A6"), + ("0.64", "A3"), + ("0.63", "A1"), + ("0.62", "9E"), + ("0.61", "9C"), + ("0.6", "99"), + ("0.59", "96"), + ("0.58", "94"), + ("0.57", "91"), + ("0.56", "8F"), + ("0.55", "8C"), + ("0.54", "8A"), + ("0.53", "87"), + ("0.52", "85"), + ("0.51", "82"), + ("0.5", "80"), + ("0.49", "7D"), + ("0.48", "7A"), + ("0.47", "78"), + ("0.46", "75"), + ("0.45", "73"), + ("0.44", "70"), + ("0.43", "6E"), + ("0.42", "6B"), + ("0.41", "69"), + ("0.4", "66"), + ("0.39", "63"), + ("0.38", "61"), + ("0.37", "5E"), + ("0.36", "5C"), + ("0.35", "59"), + ("0.34", "57"), + ("0.33", "54"), + ("0.32", "52"), + ("0.31", "4F"), + ("0.3", "4D"), + ("0.29", "4A"), + ("0.28", "47"), + ("0.27", "45"), + ("0.26", "42"), + ("0.25", "40"), + ("0.24", "3D"), + ("0.23", "3B"), + ("0.22", "38"), + ("0.21", "36"), + ("0.2", "33"), + ("0.19", "30"), + ("0.18", "2E"), + ("0.17", "2B"), + ("0.16", "29"), + ("0.15", "26"), + ("0.14", "24"), + ("0.13", "21"), + ("0.12", "1F"), + ("0.11", "1C"), + ("0.1", "1A"), + ("0.09", "17"), + ("0.08", "14"), + ("0.07", "12"), + ("0.06", "0F"), + ("0.05", "0D"), + ("0.04", "0A"), + ("0.03", "08"), + ("0.02", "05"), + ("0.01", "03"), + ("0.0", "00"), + ]) + }; +} diff --git a/src/data/mod.rs b/src/data/mod.rs index dfbaa91..8908539 100644 --- a/src/data/mod.rs +++ b/src/data/mod.rs @@ -1 +1,2 @@ +pub mod alpha_hex_map; pub mod w3cx11; diff --git a/src/lib.rs b/src/lib.rs index 55f8580..b3575bf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,4 +24,5 @@ pub use color::Color; pub use color_calc::blend::*; pub use color_calc::distance::*; pub use color_space::ColorSpace; +use data::alpha_hex_map::ALPHA_HEX_MAP; use data::w3cx11::W3CX11_HASHMAP as W3CX11;