MCPcopy Create free account
hub / github.com/GraphiteEditor/Graphite / lerp_graphic

Function lerp_graphic

node-graph/nodes/vector/src/vector_nodes.rs:2310–2364  ·  view source on GitHub ↗

Lerp between two graphics. Solid color and gradient pairings interpolate; all other pairings step at the midpoint.

(a: Option<&List<Graphic>>, b: Option<&List<Graphic>>, time: f64)

Source from the content-addressed store, hash-verified

2308
2309 // Lerp between two graphics. Solid color and gradient pairings interpolate; all other pairings step at the midpoint.
2310 fn lerp_graphic(a: Option<&List<Graphic>>, b: Option<&List<Graphic>>, time: f64) -> Option<List<Graphic>> {
2311 let transparent = List::new_from_element(Color::TRANSPARENT).into_graphic_list();
2312
2313 let a = a.filter(|graphic_list| is_paint_present(graphic_list));
2314 let b = b.filter(|graphic_list| is_paint_present(graphic_list));
2315
2316 let (a, b) = match (a, b) {
2317 (None, None) => return None,
2318 (Some(a), None) => (a, &transparent),
2319 (None, Some(b)) => (&transparent, b),
2320 (Some(a), Some(b)) => (a, b),
2321 };
2322
2323 // This keeps the gradient metadata attributes
2324 let gradient_with_stops = |mut gradient_list: List<GradientStops>, stops: GradientStops| -> Graphic {
2325 if let Some(target) = gradient_list.element_mut(0) {
2326 *target = stops;
2327 } else {
2328 gradient_list.push(Item::new_from_element(stops));
2329 }
2330 Graphic::Gradient(gradient_list)
2331 };
2332
2333 let graphic = match (a.element(0), b.element(0)) {
2334 (Some(Graphic::Color(color_list_a)), Some(Graphic::Color(color_list_b))) => color_list_a
2335 .element(0)
2336 .zip(color_list_b.element(0))
2337 .map(|(color_a, color_b)| Graphic::from(color_a.lerp(color_b, time as f32))),
2338 (Some(Graphic::Color(color_list_a)), Some(Graphic::Gradient(gradient_list_b))) => color_list_a.element(0).zip(gradient_list_b.element(0)).map(|(color_a, stops_b)| {
2339 let mut solid_to_gradient = stops_b.clone();
2340 solid_to_gradient.color.iter_mut().for_each(|color| *color = *color_a);
2341 let stops = solid_to_gradient.lerp(stops_b, time);
2342 gradient_with_stops(gradient_list_b.clone(), stops)
2343 }),
2344 (Some(Graphic::Gradient(gradient_list_a)), Some(Graphic::Color(color_list_b))) => gradient_list_a.element(0).zip(color_list_b.element(0)).map(|(stops_a, color_b)| {
2345 let mut gradient_to_solid = stops_a.clone();
2346 gradient_to_solid.color.iter_mut().for_each(|color| *color = *color_b);
2347 let stops = stops_a.lerp(&gradient_to_solid, time);
2348 gradient_with_stops(gradient_list_a.clone(), stops)
2349 }),
2350 (Some(Graphic::Gradient(gradient_list_a)), Some(Graphic::Gradient(gradient_list_b))) => gradient_list_a.element(0).zip(gradient_list_b.element(0)).map(|(stops_a, stops_b)| {
2351 let stops = stops_a.lerp(stops_b, time);
2352 let metadata_source = if time < 0.5 { gradient_list_a } else { gradient_list_b };
2353
2354 let mut gradient_list = metadata_source.clone();
2355 gradient_list.set_attribute(ATTR_TRANSFORM, 0, lerp_gradient_transform(gradient_list_a, gradient_list_b, time));
2356
2357 gradient_with_stops(gradient_list, stops)
2358 }),
2359 // Pairings beyond solid colors and gradients (raster, vector, or mixed) can't be interpolated, so step at the midpoint
2360 _ => return Some(if time < 0.5 { a.clone() } else { b.clone() }),
2361 };
2362
2363 graphic.map(List::new_from_element)
2364 }
2365
2366 // Preserve original `List<Graphic>` as upstream data so this group layer's nested layers can be edited by the tools.
2367 let mut graphic_list_content = content.clone().into_graphic_list();

Callers 1

morphFunction · 0.85

Calls 11

is_paint_presentFunction · 0.85
GradientClass · 0.85
lerp_gradient_transformFunction · 0.85
element_mutMethod · 0.80
elementMethod · 0.80
set_attributeMethod · 0.80
into_graphic_listMethod · 0.45
pushMethod · 0.45
lerpMethod · 0.45
cloneMethod · 0.45
iter_mutMethod · 0.45

Tested by

no test coverage detected