flow_rs_core/auto_layout/
transitions.rs1use std::collections::HashMap;
4
5use crate::graph::Graph;
6use crate::types::{NodeId, Position};
7
8#[derive(Debug)]
10pub struct TransitionState {
11 pub progress: f64,
12 pub duration: f64,
13 pub from_positions: HashMap<NodeId, Position>,
14 pub to_positions: HashMap<NodeId, Position>,
15}
16
17impl TransitionState {
18 pub fn new(
20 duration: f64,
21 from_positions: HashMap<NodeId, Position>,
22 to_positions: HashMap<NodeId, Position>,
23 ) -> Self {
24 Self {
25 progress: 0.0,
26 duration,
27 from_positions,
28 to_positions,
29 }
30 }
31}
32
33pub fn ease_in_out(t: f64) -> f64 {
35 if t < 0.5 {
36 2.0 * t * t
37 } else {
38 -1.0 + (4.0 - 2.0 * t) * t
39 }
40}
41
42pub fn interpolate_position(from: Position, to: Position, t: f64) -> Position {
44 Position::new(
45 from.x + (to.x - from.x) * t,
46 from.y + (to.y - from.y) * t,
47 )
48}
49
50pub fn update_transition<N, E>(
52 transition_state: &mut Option<TransitionState>,
53 graph: &mut Graph<N, E>,
54 delta_time: f64,
55) -> Result<bool, crate::error::FlowError> {
56 let should_remove_state = if let Some(ref mut state) = transition_state {
57 state.progress += delta_time / state.duration;
58
59 if state.progress >= 1.0 {
60 for node in graph.nodes_mut() {
62 if let Some(&target_pos) = state.to_positions.get(&node.id) {
63 node.position = target_pos;
64 }
65 }
66 return Ok(true); } else {
68 let progress = state.progress;
70 let transitions: Vec<_> = graph
71 .nodes()
72 .filter_map(|node| {
73 if let (Some(&from_pos), Some(&to_pos)) = (
74 state.from_positions.get(&node.id),
75 state.to_positions.get(&node.id),
76 ) {
77 Some((node.id.clone(), from_pos, to_pos))
78 } else {
79 None
80 }
81 })
82 .collect();
83
84 let t = ease_in_out(progress);
86 for (node_id, from_pos, to_pos) in transitions {
87 if let Some(node) = graph.get_node_mut(&node_id) {
88 node.position = interpolate_position(from_pos, to_pos, t);
89 }
90 }
91 return Ok(false); }
93 } else {
94 false
95 };
96
97 if should_remove_state {
98 *transition_state = None;
99 }
100
101 Ok(true) }