three_d/renderer/control/
control2d.rs1use super::*;
2
3#[derive(Clone, Copy, Debug)]
7pub struct Control2D {
8 pub min_zoom_factor: f32,
10 pub max_zoom_factor: f32,
12}
13
14impl Control2D {
15 pub fn new(min_zoom_factor: f32, max_zoom_factor: f32) -> Self {
17 Self {
18 min_zoom_factor,
19 max_zoom_factor,
20 }
21 }
22
23 pub fn handle_events(
25 &mut self,
26 camera: &mut three_d_asset::Camera,
27 events: &mut [Event],
28 device_pixel_ratio: f32,
29 ) -> bool {
30 let mut change = false;
31 for event in events.iter_mut() {
32 match event {
33 Event::PinchGesture {
34 delta,
35 position,
36 handled,
37 ..
38 } if !*handled => {
39 self.zoom(camera, *delta, *position, 0.5);
40 *handled = true;
41 change = true;
42 }
43 Event::MouseWheel {
44 delta,
45 position,
46 handled,
47 ..
48 } if !*handled && delta.0.abs() + delta.1.abs() > f32::EPSILON => {
49 if delta.0.abs() < f32::EPSILON && delta.1.fract().abs() > f32::EPSILON {
50 self.zoom(camera, delta.1, *position, 0.005);
51 } else {
52 self.pan(camera, *delta, device_pixel_ratio);
53 }
54 *handled = true;
55 change = true;
56 }
57 Event::MouseMotion {
58 delta,
59 button,
60 handled,
61 ..
62 } if !*handled && Some(MouseButton::Right) == *button => {
63 self.pan(camera, *delta, device_pixel_ratio);
64 *handled = true;
65 change = true;
66 }
67 _ => {}
68 }
69 }
70 change
71 }
72
73 fn zoom(
74 &self,
75 camera: &mut three_d_asset::Camera,
76 delta: f32,
77 position: PhysicalPoint,
78 sensitivity: f32,
79 ) {
80 let mut target = camera.position_at_pixel(position);
81 target.z = 0.0;
82 let distance = 1.0 / camera.zoom_factor();
83 let zoom_amount = distance * (1.0 - (-delta * sensitivity).exp());
84 camera.zoom_towards(
85 target,
86 zoom_amount,
87 1.0 / self.max_zoom_factor,
88 1.0 / self.min_zoom_factor,
89 );
90 }
91
92 fn pan(&self, camera: &mut three_d_asset::Camera, delta: (f32, f32), device_pixel_ratio: f32) {
93 let origo = camera.position_at_pixel(vec2(0.0, 0.0));
94 let point = camera.position_at_pixel(vec2(device_pixel_ratio * delta.0, 0.0));
95 let x = delta.0.signum() * (point - origo).magnitude();
96 let point = camera.position_at_pixel(vec2(device_pixel_ratio * delta.1, 0.0));
97 let y = delta.1.signum() * (point - origo).magnitude();
98 let right = camera.right_direction();
99 let up = right.cross(camera.view_direction());
100 camera.translate(-right * x + up * y);
101 }
102}