leptos_motion_core/
math.rs1pub fn clamp(value: f64, min: f64, max: f64) -> f64 {
7 if min > max {
8 panic!("min must be less than or equal to max");
9 }
10 value.max(min).min(max)
11}
12
13pub fn map_range(value: f64, from_min: f64, from_max: f64, to_min: f64, to_max: f64) -> f64 {
15 let from_range = from_max - from_min;
16 let to_range = to_max - to_min;
17
18 if from_range == 0.0 {
19 return to_min;
20 }
21
22 let normalized = (value - from_min) / from_range;
23 to_min + (normalized * to_range)
24}
25
26pub fn distance_2d(x1: f64, y1: f64, x2: f64, y2: f64) -> f64 {
28 let dx = x2 - x1;
29 let dy = y2 - y1;
30 (dx * dx + dy * dy).sqrt()
31}
32
33pub fn smooth_step(t: f64) -> f64 {
35 let t = clamp(t, 0.0, 1.0);
36 t * t * (3.0 - 2.0 * t)
37}
38
39pub fn smoother_step(t: f64) -> f64 {
41 let t = clamp(t, 0.0, 1.0);
42 t * t * t * (t * (t * 6.0 - 15.0) + 10.0)
43}
44
45#[cfg(test)]
46mod tests {
47 use super::*;
48 use approx::assert_relative_eq;
49
50 #[test]
51 fn test_clamp() {
52 assert_eq!(clamp(5.0, 0.0, 10.0), 5.0);
53 assert_eq!(clamp(-1.0, 0.0, 10.0), 0.0);
54 assert_eq!(clamp(15.0, 0.0, 10.0), 10.0);
55 }
56
57 #[test]
58 fn test_map_range() {
59 assert_relative_eq!(map_range(0.5, 0.0, 1.0, 0.0, 100.0), 50.0);
60 assert_relative_eq!(map_range(2.0, 0.0, 4.0, 10.0, 20.0), 15.0);
61 assert_relative_eq!(map_range(0.0, 0.0, 0.0, 0.0, 100.0), 0.0); }
63
64 #[test]
65 fn test_distance_2d() {
66 assert_relative_eq!(distance_2d(0.0, 0.0, 3.0, 4.0), 5.0);
67 assert_relative_eq!(distance_2d(0.0, 0.0, 0.0, 0.0), 0.0);
68 }
69
70 #[test]
71 fn test_smooth_step() {
72 assert_eq!(smooth_step(0.0), 0.0);
73 assert_eq!(smooth_step(1.0), 1.0);
74 assert_relative_eq!(smooth_step(0.5), 0.5);
75
76 let linear_quarter = 0.25;
78 let smooth_quarter = smooth_step(0.25);
79 assert!(smooth_quarter < linear_quarter);
80 }
81
82 #[test]
83 fn test_smoother_step() {
84 assert_eq!(smoother_step(0.0), 0.0);
85 assert_eq!(smoother_step(1.0), 1.0);
86 assert_relative_eq!(smoother_step(0.5), 0.5);
87 }
88}