diff --git a/CHANGELOG.md b/CHANGELOG.md index 129b840..daa450e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- add `set_alpha` filter + + ## [2.3.0](https://github.com/InioX/matugen/compare/v2.2.0...v2.3.0) - 2024-05-29 ### Added diff --git a/example/colors.whatever-extension b/example/colors.whatever-extension index 8bcc5f7..63a4e3b 100644 --- a/example/colors.whatever-extension +++ b/example/colors.whatever-extension @@ -22,4 +22,8 @@ source_color {{colors.source_color.default.hex}}; <* for name, value in colors *> {{name | replace: "_", "-" }} {{value.default.hex}}; -<* endfor *> \ No newline at end of file +<* endfor *> + +Only works with rgba and hsla +{{ colors.source_color.default.rgba | set_alpha 0.5 }} +Output: rgba(r, g, b, 0.5) diff --git a/src/util/color.rs b/src/util/color.rs index a5b0a5d..fbef8bc 100644 --- a/src/util/color.rs +++ b/src/util/color.rs @@ -64,6 +64,16 @@ pub fn format_rgba(color: &Rgb) -> String { ) } +pub fn format_rgba_float(color: &Rgb) -> String { + format!( + "rgba({:?}, {:?}, {:?}, {:.1})", + color.red() as u8, + color.green() as u8, + color.blue() as u8, + color.alpha() + ) +} + pub fn format_hsl(color: &Hsl) -> String { format!( "hsl({:?}, {:?}%, {:?}%)", @@ -83,6 +93,16 @@ pub fn format_hsla(color: &Hsl) -> String { ) } +pub fn format_hsla_float(color: &Hsl) -> String { + format!( + "hsla({:?}, {:?}%, {:?}%, {:.1})", + color.hue() as u8, + color.saturation() as u8, + color.lightness() as u8, + color.alpha() + ) +} + pub fn get_color_distance_lab(c1: &str, c2: &str) -> f64 { let c1 = Lab::from(Argb::from_str(c1).unwrap()); let c2 = Lab::from(Argb::from_str(c2).unwrap()); diff --git a/src/util/filters.rs b/src/util/filters.rs index b21d0b8..91b07c2 100644 --- a/src/util/filters.rs +++ b/src/util/filters.rs @@ -1,3 +1,4 @@ +use colorsys::ColorAlpha; use colorsys::ColorTransform; use colorsys::Hsl; use colorsys::Rgb; @@ -7,7 +8,8 @@ use upon::Value; use crate::util::template::{check_string_value, parse_color}; use crate::util::color::{ - format_hex, format_hex_stripped, format_hsl, format_hsla, format_rgb, format_rgba, + format_hex, format_hex_stripped, format_hsl, format_hsla, format_hsla_float, format_rgb, + format_rgba, format_rgba_float, }; pub fn set_lightness(value: &Value, amount: f64) -> Result { @@ -67,3 +69,37 @@ pub fn set_lightness(value: &Value, amount: f64) -> Result { v => Ok(v.to_string()), } } + +pub fn set_alpha(value: &Value, amount: f64) -> Result { + let string = check_string_value(value).unwrap(); + + let format = parse_color(string); + + debug!("Setting alpha on string {} by {}", string, amount); + + if format.is_none() { + return Ok(string.to_string()); + } + + if !(0.0..=1.0).contains(&amount) { + return Err("alpha must be in range [0.0 to 1.0]".to_string()); + } + + match format.unwrap() { + "hex" => Err("cannot set alpha on hex color".to_string()), + "hex_stripped" => Err("cannot set alpha on hex color".to_string()), + "rgb" => Err("cannot set alpha on rgb color, use rgba".to_string()), + "rgba" => { + let mut color = Rgb::from_str(string).unwrap(); + color.set_alpha(amount); + Ok(format_rgba_float(&color)) + } + "hsl" => Err("cannot set alpha on hsl color, use hsla".to_string()), + "hsla" => { + let mut color = Hsl::from_str(string).unwrap(); + color.set_alpha(amount); + Ok(format_hsla_float(&color)) + } + v => Ok(v.to_string()), + } +} diff --git a/src/util/template.rs b/src/util/template.rs index cae13ba..5c77049 100644 --- a/src/util/template.rs +++ b/src/util/template.rs @@ -12,7 +12,7 @@ use upon::Value; use crate::util::color; use crate::util::color::color_to_string; -use crate::util::filters::set_lightness; +use crate::util::filters::{set_alpha, set_lightness}; use crate::util::variables::format_hook_text; use std::fs::canonicalize; @@ -302,6 +302,7 @@ fn export_template( fn add_engine_filters(engine: &mut Engine) { engine.add_filter("set_lightness", set_lightness); + engine.add_filter("set_alpha", set_alpha); engine.add_filter("to_upper", str::to_uppercase); engine.add_filter("to_lower", str::to_lowercase); engine.add_filter("replace", |s: String, from: String, to: String| {