mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-21 04:48:11 +08:00
New node: 'Gradient to Colors' for unwrapping a gradient ramp into its colors (#4425)
* New node: 'Gradient to Colors' for unwrapping a gradient ramp into its colors * Update 'Gradient Midpoints' wording
This commit is contained in:
@@ -1057,12 +1057,18 @@ pub async fn flatten_gradient<T: IntoGraphicList>(_: impl Ctx, #[implementations
|
||||
content.into_flattened_list()
|
||||
}
|
||||
|
||||
/// Constructs a gradient from a `Color[]`, where the colors are evenly distributed as gradient stops across the range from 0 to 1.
|
||||
/// Constructs a gradient from a `Color[]`, where each color becomes a gradient stop. A `position` attribute on the colors places their stops along the ramp and a `midpoint` attribute skews each transition, while colors carrying neither are distributed evenly across the 0 to 1 range.
|
||||
#[node_macro::node(category("Gradient"), name("Colors to Gradient"))]
|
||||
fn colors_to_gradient<T: IntoGraphicList>(_: impl Ctx, #[implementations(List<Graphic>, List<Color>)] colors: T) -> Item<Gradient> {
|
||||
Item::new_from_element(Gradient::from(colors.into_flattened_list::<Color>()))
|
||||
}
|
||||
|
||||
/// Unwraps a gradient into a `Color[]` of its stops, keeping any `position` and `midpoint` attributes that place them along the ramp. Attributes belonging to the gradient as a whole (like spread and interpolation), rather than its individual color stops, are not preserved.
|
||||
#[node_macro::node(category("Gradient"), name("Gradient to Colors"))]
|
||||
fn gradient_to_colors(_: impl Ctx, gradient: Item<Gradient>) -> List<Color> {
|
||||
gradient.into_element().into_color_list()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
@@ -1186,4 +1192,30 @@ mod test {
|
||||
let portion = list_slice((), list_of([1., 2., 3., 4., 5.]), Item::new_from_element(3.), Item::new_from_element(3.));
|
||||
assert!(elements(&portion).is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gradient_to_colors_round_trips_the_stops_with_their_placement() {
|
||||
let mut gradient = Gradient::from(vec![Color::RED, Color::GREEN, Color::BLUE]);
|
||||
gradient.set_positions(&[0., 0.25, 1.]);
|
||||
gradient.set_midpoints(&[0.3, 0.5, 0.5]);
|
||||
|
||||
let colors = gradient_to_colors((), Item::new_from_element(gradient.clone()));
|
||||
assert_eq!(elements(&colors), [Color::RED, Color::GREEN, Color::BLUE], "every stop should come out as its color");
|
||||
|
||||
let restored = colors_to_gradient((), colors);
|
||||
assert_eq!(
|
||||
restored.element(),
|
||||
&gradient,
|
||||
"wrapping the stops back up should restore the uneven placement rather than redistributing them"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gradient_to_colors_leaves_an_untouched_ramp_without_placement_attributes() {
|
||||
let gradient = Gradient::from(vec![Color::RED, Color::GREEN, Color::BLUE]);
|
||||
assert!(!gradient.has_position_attribute(), "even spacing is stored as the attribute's absence");
|
||||
|
||||
let restored = colors_to_gradient((), gradient_to_colors((), Item::new_from_element(gradient.clone())));
|
||||
assert_eq!(restored.element(), &gradient, "a default ramp should round trip without gaining attributes it never had");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user