149 lines
4.4 KiB
Rust
149 lines
4.4 KiB
Rust
use std::str::FromStr;
|
|
|
|
use palette::{
|
|
cam16::{Cam16Jch, Parameters},
|
|
color_difference::Wcag21RelativeContrast,
|
|
convert::FromColorUnclamped,
|
|
FromColor, Hsl, IntoColor, IsWithinBounds, Lab, Oklch, Srgb,
|
|
};
|
|
use wasm_bindgen::prelude::*;
|
|
|
|
mod analysis;
|
|
mod color_card;
|
|
mod color_differ;
|
|
mod color_shifting;
|
|
mod convert;
|
|
mod errors;
|
|
mod palettes;
|
|
mod reversing;
|
|
mod schemes;
|
|
mod series;
|
|
mod theory;
|
|
|
|
#[wasm_bindgen]
|
|
pub fn represent_rgb(color: &str) -> Result<Box<[u8]>, errors::ColorError> {
|
|
let srgb = Srgb::from_str(color)
|
|
.map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))?
|
|
.into_format::<u8>();
|
|
Ok(Box::new([srgb.red, srgb.green, srgb.blue]))
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
pub fn rgb_to_hex(r: u8, g: u8, b: u8) -> Result<String, errors::ColorError> {
|
|
let srgb = Srgb::new(r, g, b);
|
|
Ok(format!("{:x}", srgb))
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
pub fn represent_hsl(color: &str) -> Result<Box<[f32]>, errors::ColorError> {
|
|
let origin_color = Srgb::from_str(color)
|
|
.map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))?
|
|
.into_format::<f32>();
|
|
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<String, errors::ColorError> {
|
|
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::<u8>()))
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
pub fn represent_lab(color: &str) -> Result<Box<[f32]>, errors::ColorError> {
|
|
let origin_color = Srgb::from_str(color)
|
|
.map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))?
|
|
.into_format::<f32>();
|
|
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<String, errors::ColorError> {
|
|
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::<u8>()))
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
pub fn represent_oklch(color: &str) -> Result<Box<[f32]>, errors::ColorError> {
|
|
let origin_color = Srgb::from_str(color)
|
|
.map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))?
|
|
.into_format::<f32>();
|
|
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<String, errors::ColorError> {
|
|
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::<u8>()))
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
pub fn represent_hct(color: &str) -> Result<Box<[f32]>, errors::ColorError> {
|
|
let origin_color = Srgb::from_str(color)
|
|
.map_err(|_| errors::ColorError::UnrecogniazedRGB(color.to_string()))?
|
|
.into_format::<f32>();
|
|
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<String, errors::ColorError> {
|
|
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::<u8>()))
|
|
}
|
|
|
|
#[wasm_bindgen]
|
|
pub fn wacg_relative_contrast(fg_color: &str, bg_color: &str) -> Result<f32, errors::ColorError> {
|
|
let fg_srgb = Srgb::from_str(fg_color)
|
|
.map_err(|_| errors::ColorError::UnrecogniazedRGB(fg_color.to_string()))?
|
|
.into_format::<f32>();
|
|
let bg_srgb = Srgb::from_str(bg_color)
|
|
.map_err(|_| errors::ColorError::UnrecogniazedRGB(bg_color.to_string()))?
|
|
.into_format::<f32>();
|
|
Ok(fg_srgb.relative_contrast(bg_srgb))
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! cond {
|
|
($s: expr, $a: expr, $b: expr) => {
|
|
if $s {
|
|
$a
|
|
} else {
|
|
$b
|
|
}
|
|
};
|
|
}
|