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::None)
|
||||||
| Value::Dimension(n, Unit::Percent)
|
| Value::Dimension(n, Unit::Percent)
|
||||||
| Value::Dimension(n, Unit::Deg) => n,
|
| 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)))
|
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()
|
(((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 {
|
pub fn adjust_hue(&self, degrees: Number) -> Self {
|
||||||
let hue = self.hue();
|
let (hue, saturation, luminance, alpha) = self.as_hsla();
|
||||||
let saturation = Number::ratio(self.saturation(), 100);
|
Color::from_hsla(hue + degrees, saturation, luminance, alpha)
|
||||||
let luminance = Number::ratio(self.lightness(), 100);
|
}
|
||||||
Color::from_hsla(hue + degrees, saturation, luminance, self.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 {
|
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: adjust-hue($color: hsl(120, 30%, 90%), $degrees: 60deg);\n}\n",
|
||||||
// "a {\n color: #deeded;\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