Skip to content

Commit

Permalink
feat: color hex string support alpha channel
Browse files Browse the repository at this point in the history
  • Loading branch information
JiatLn committed Apr 25, 2023
1 parent 61db491 commit c367381
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 2 deletions.
19 changes: 17 additions & 2 deletions src/color/stringify.rs
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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
Expand Down
35 changes: 35 additions & 0 deletions src/conversion/hex.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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();
Expand Down Expand Up @@ -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");
}
}
110 changes: 110 additions & 0 deletions src/data/alpha_hex_map.rs
Original file line number Diff line number Diff line change
@@ -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"),
])
};
}
1 change: 1 addition & 0 deletions src/data/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod alpha_hex_map;
pub mod w3cx11;
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

0 comments on commit c367381

Please sign in to comment.