use std::str::FromStr; use palette::{ FromColor, Hsl, IntoColor, IsWithinBounds, Lab, Oklch, Srgb, cam16::{Cam16Jch, Parameters}, color_difference::Wcag21RelativeContrast, convert::FromColorUnclamped, }; use wasm_bindgen::prelude::*; mod analysis; mod color_card; mod color_differ; mod color_shifting; mod convert; mod errors; mod foreign_serializer; mod palettes; mod reversing; mod schemes; mod series; mod theory; #[wasm_bindgen] pub fn represent_rgb(color: &str) -> Result, errors::ColorError> { let srgb = Srgb::from_str(color) .map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))? .into_format::(); Ok(Box::new([srgb.red, srgb.green, srgb.blue])) } #[wasm_bindgen] pub fn rgb_to_hex(r: u8, g: u8, b: u8) -> Result { let srgb = Srgb::new(r, g, b); Ok(format!("{:x}", srgb)) } #[wasm_bindgen] pub fn represent_hsl(color: &str) -> Result, errors::ColorError> { let origin_color = Srgb::from_str(color) .map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))? .into_format::(); let hsl = Hsl::from_color(origin_color); Ok(Box::new([ hsl.hue.into_positive_degrees(), hsl.saturation, hsl.lightness, ])) } #[wasm_bindgen] pub fn hsl_to_hex(h: f32, s: f32, l: f32) -> Result { let hsl = Hsl::new(h, s, l); let srgb = Srgb::from_color_unclamped(hsl); if !srgb.is_within_bounds() { return Err(errors::ColorError::ComponentOutOfBounds); } Ok(format!("{:x}", srgb.into_format::())) } #[wasm_bindgen] pub fn represent_lab(color: &str) -> Result, errors::ColorError> { let origin_color = Srgb::from_str(color) .map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))? .into_format::(); let lab = Lab::from_color(origin_color); Ok(Box::new([lab.l, lab.a, lab.b])) } #[wasm_bindgen] pub fn lab_to_hex(l: f32, a: f32, b: f32) -> Result { let lab = Lab::new(l, a, b); let srgb = Srgb::from_color_unclamped(lab); if !srgb.is_within_bounds() { return Err(errors::ColorError::ComponentOutOfBounds); } Ok(format!("{:x}", srgb.into_format::())) } #[wasm_bindgen] pub fn represent_oklch(color: &str) -> Result, errors::ColorError> { let origin_color = Srgb::from_str(color) .map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))? .into_format::(); let lch = Oklch::from_color(origin_color); Ok(Box::new([ lch.l, lch.chroma, lch.hue.into_positive_degrees(), ])) } #[wasm_bindgen] pub fn oklch_to_hex(l: f32, c: f32, h: f32) -> Result { let lch = Oklch::new(l, c, h); let srgb = Srgb::from_color_unclamped(lch); if !srgb.is_within_bounds() { return Err(errors::ColorError::ComponentOutOfBounds); } Ok(format!("{:x}", srgb.into_format::())) } #[wasm_bindgen] pub fn represent_hct(color: &str) -> Result, errors::ColorError> { let origin_color = Srgb::from_str(color) .map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))? .into_format::(); let hct = Cam16Jch::from_xyz( origin_color.into_color(), Parameters::default_static_wp(40.0), ); Ok(Box::new([ hct.hue.into_positive_degrees(), hct.chroma, hct.lightness, ])) } #[wasm_bindgen] pub fn hct_to_hex(hue: f32, chroma: f32, tone: f32) -> Result { let hct = Cam16Jch::new(tone, chroma, hue); let srgb = Srgb::from_color_unclamped(hct.into_xyz(Parameters::default_static_wp(40.0))); if !srgb.is_within_bounds() { return Err(errors::ColorError::ComponentOutOfBounds); } Ok(format!("{:x}", srgb.into_format::())) } #[wasm_bindgen] pub fn wacg_relative_contrast(fg_color: &str, bg_color: &str) -> Result { let fg_srgb = Srgb::from_str(fg_color) .map_err(|_| errors::ColorError::UnrecogniazedRGB(fg_color.to_string()))? .into_format::(); let bg_srgb = Srgb::from_str(bg_color) .map_err(|_| errors::ColorError::UnrecogniazedRGB(bg_color.to_string()))? .into_format::(); Ok(fg_srgb.relative_contrast(bg_srgb)) } #[macro_export] macro_rules! cond { ($s: expr, $a: expr, $b: expr) => { if $s { $a } else { $b } }; }