Implement builtin function lighten()
This commit is contained in:
parent
6427a7ab81
commit
db8e8eaebb
@ -175,8 +175,20 @@ pub(crate) fn register(f: &mut BTreeMap<String, Builtin>) {
|
||||
Value::Dimension(n, Unit::None)
|
||||
| Value::Dimension(n, Unit::Percent)
|
||||
| Value::Dimension(n, Unit::Deg) => n,
|
||||
_ => todo!("expected either unitless or % number for alpha"),
|
||||
_ => todo!("expected either unitless or % number for degrees"),
|
||||
};
|
||||
Some(Value::Color(color.adjust_hue(degrees)))
|
||||
});
|
||||
decl!(f "lighten", |args, _| {
|
||||
let color = match arg!(args, 0, "color").eval() {
|
||||
Value::Color(c) => c,
|
||||
_ => todo!("non-color given to builtin function `lighten()`")
|
||||
};
|
||||
let amount = match arg!(args, 1, "amount").eval() {
|
||||
Value::Dimension(n, Unit::None) => n,
|
||||
Value::Dimension(n, Unit::Percent) => n / Number::from(100),
|
||||
_ => todo!("expected either unitless or % number for amount"),
|
||||
};
|
||||
Some(Value::Color(color.lighten(amount)))
|
||||
});
|
||||
}
|
||||
|
@ -102,11 +102,54 @@ impl Color {
|
||||
(((min + max) / Number::from(2)) * Number::from(100)).round()
|
||||
}
|
||||
|
||||
pub fn as_hsla(&self) -> (Number, Number, Number, Number) {
|
||||
let red = self.red.clone() / Number::from(255);
|
||||
let green = self.green.clone() / Number::from(255);
|
||||
let blue = self.blue.clone() / Number::from(255);
|
||||
let min = red.clone().min(green.clone().min(blue.clone()));
|
||||
let max = red.clone().max(green.clone().max(blue.clone()));
|
||||
|
||||
let lightness = (min.clone() + max.clone()) / Number::from(2);
|
||||
|
||||
let saturation = if &min == &max {
|
||||
Number::from(0)
|
||||
} else {
|
||||
let d = max.clone() - min.clone();
|
||||
let mm = max.clone() + min.clone();
|
||||
d / if mm > Number::from(1) {
|
||||
Number::from(2) - mm
|
||||
} else {
|
||||
mm
|
||||
}
|
||||
};
|
||||
|
||||
let mut hue = if min == max {
|
||||
Number::from(0)
|
||||
} else if red == max {
|
||||
(green - blue) / (max - min)
|
||||
} else if green == max {
|
||||
Number::from(2) + (blue - red) / (max - min)
|
||||
} else {
|
||||
Number::from(4) + (red - green) / (max - min)
|
||||
};
|
||||
|
||||
if hue < Number::from(0) {
|
||||
hue += Number::from(360);
|
||||
}
|
||||
|
||||
hue *= Number::from(60);
|
||||
|
||||
(hue, saturation, lightness, self.alpha())
|
||||
}
|
||||
|
||||
pub fn adjust_hue(&self, degrees: Number) -> Self {
|
||||
let hue = self.hue();
|
||||
let saturation = Number::ratio(self.saturation(), 100);
|
||||
let luminance = Number::ratio(self.lightness(), 100);
|
||||
Color::from_hsla(hue + degrees, saturation, luminance, self.alpha())
|
||||
let (hue, saturation, luminance, alpha) = self.as_hsla();
|
||||
Color::from_hsla(hue + degrees, saturation, luminance, alpha)
|
||||
}
|
||||
|
||||
pub fn lighten(&self, amount: Number) -> Self {
|
||||
let (hue, saturation, luminance, alpha) = self.as_hsla();
|
||||
Color::from_hsla(hue, saturation, luminance + amount, alpha)
|
||||
}
|
||||
|
||||
pub fn alpha(&self) -> Number {
|
||||
|
@ -217,3 +217,20 @@ test!(
|
||||
// "a {\n color: adjust-hue($color: hsl(120, 30%, 90%), $degrees: 60deg);\n}\n",
|
||||
// "a {\n color: #deeded;\n}\n"
|
||||
// );
|
||||
// test!(
|
||||
// lighten_named_args,
|
||||
// "a {\n color: lighten($color: hsl(0, 0%, 0%), $amount: 30%);\n}\n",
|
||||
// "a {\n color: #deeded;\n}\n"
|
||||
// );
|
||||
test!(
|
||||
lighten_basic,
|
||||
"a {\n color: lighten(hsl(0, 0%, 0%), 30%);\n}\n",
|
||||
"a {\n color: #4d4d4d;\n}\n"
|
||||
);
|
||||
test!(
|
||||
lighten_3_hex,
|
||||
"a {\n color: lighten(#800, 20%);\n}\n",
|
||||
// eventually, this should become `#e00`
|
||||
// blocked on recognizing when to use 3-hex over 6-hex
|
||||
"a {\n color: #ee0000;\n}\n"
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user