perspective_viewer/utils/
modal_position.rs1use perspective_js::utils::global;
14use web_sys::*;
15
16#[derive(Clone, Copy, Debug, Default)]
18pub enum ModalAnchor {
19 BottomRightTopLeft,
20 BottomRightBottomLeft,
21 BottomRightTopRight,
22 BottomLeftTopLeft,
23 TopRightTopLeft,
24 TopRightBottomRight,
25
26 #[default]
27 TopLeftBottomLeft,
28}
29
30impl ModalAnchor {
31 pub const fn is_rev_vert(&self) -> bool {
32 matches!(
33 self,
34 Self::BottomLeftTopLeft
35 | Self::BottomRightBottomLeft
36 | Self::BottomRightTopLeft
37 | Self::BottomRightTopRight
38 )
39 }
40}
41
42pub fn calc_relative_position(target: &DomRect, modal: &DomRect) -> ModalAnchor {
45 let window = global::window();
46 let inner_width = window.inner_width().unwrap().as_f64().unwrap();
47 let inner_height = window.inner_height().unwrap().as_f64().unwrap();
48 let top = target.top();
49 let left = target.left();
50 let height = target.height();
51 let width = target.width();
52 let modal_height = modal.height();
53 let modal_width = modal.width();
54
55 let elem_over_y = inner_height < top + height - 1.0 + modal_height;
56 let elem_over_x = inner_width < left + modal_width;
57 let target_over_x = inner_width < left + width;
58 let target_over_y = inner_height < top + height;
59
60 match (elem_over_y, elem_over_x, target_over_x, target_over_y) {
62 (true, _, true, true) => ModalAnchor::BottomRightTopLeft,
63 (true, _, true, false) => ModalAnchor::BottomRightBottomLeft,
64 (true, true, false, _) => {
65 if left + width - modal_width > 0.0 {
66 ModalAnchor::BottomRightTopRight
67 } else {
68 ModalAnchor::BottomLeftTopLeft
69 }
70 },
71 (true, false, false, _) => ModalAnchor::BottomLeftTopLeft,
72 (false, true, true, _) => ModalAnchor::TopRightTopLeft,
73 (false, true, false, _) => {
74 if left + width - modal_width > 0.0 {
75 ModalAnchor::TopRightBottomRight
76 } else {
77 ModalAnchor::TopLeftBottomLeft
78 }
79 },
80 _ => ModalAnchor::TopLeftBottomLeft,
81 }
82}
83
84pub fn calc_anchor_position(anchor: ModalAnchor, target: &DomRect, modal: &DomRect) -> (f64, f64) {
88 let height = target.height();
89 let width = target.width();
90 let top = target.top();
91 let left = target.left();
92 let rect_height = modal.height();
93 let rect_width = modal.width();
94
95 match anchor {
96 ModalAnchor::BottomRightTopLeft => (top - rect_height, left - rect_width + 1.0),
97 ModalAnchor::BottomRightBottomLeft => (top - rect_height + height, left - rect_width + 1.0),
98 ModalAnchor::BottomRightTopRight => (top - rect_height + 1.0, left + width - rect_width),
99 ModalAnchor::BottomLeftTopLeft => (top - rect_height + 1.0, left),
100 ModalAnchor::TopRightTopLeft => (top, left - rect_width + 1.0),
101 ModalAnchor::TopRightBottomRight => (top + height - 1.0, left + width - rect_width),
102 ModalAnchor::TopLeftBottomLeft => (top + height - 1.0, left),
103 }
104}