diff options
Diffstat (limited to 'src/transform.rs')
| -rw-r--r-- | src/transform.rs | 74 |
1 files changed, 28 insertions, 46 deletions
diff --git a/src/transform.rs b/src/transform.rs index d074c03..2e9ea0b 100644 --- a/src/transform.rs +++ b/src/transform.rs @@ -77,59 +77,41 @@ impl Transform { ) } - /* Helper function to make sure the standard zoom factor is always exact. This helps - * normalising zoom levels even when the user zooms in and out extremely often, assuming they - * pass the standard zoom factor. - */ - fn normalise_zoom(&mut self) { - self.pixels_per_m = self.pixels_per_m as u32 as f32; - if self.pixels_per_m < MIN_PIXELS_PER_M { - self.pixels_per_m = MIN_PIXELS_PER_M; - } - - if self.pixels_per_m > STANDARD_PIXELS_PER_M - 5. - && self.pixels_per_m < STANDARD_PIXELS_PER_M + 5. + /// Attempts to zoom the pixels per meter by the amount of factor. + /// + /// # Arguments + /// `factor`: A number greater than one means zooming in, a number less than one means zooming out. What happens when you try to + /// zoom with a negative factor you'll have to figure out yourself. + /// `mouse_pos_px`: Position of the mouse cursor, this time not in meters, but in screen + /// pixels. This will be used to tether zoom on that point. + pub fn try_zoom(&mut self, mouse_pos_px: Vec2<f32>, factor: f32) -> bool { + // Abort zooming when the scale would not be in the min-max-bounds anymore. + let desired_px_per_m = self.pixels_per_m * factor; + if (factor < 1. && desired_px_per_m <= MIN_PIXELS_PER_M) + || (factor > 1. && desired_px_per_m >= MAX_PIXELS_PER_M) { - self.pixels_per_m = STANDARD_PIXELS_PER_M; + return false; } - } - /// Attempts to zoom in a step and return true. - /// If the maximum zoom is reached, this function changes nothing and returns false. - pub fn try_zoom_in(&mut self, mouse_pos_px: Vec2<f32>) -> bool { - if self.pixels_per_m < MAX_PIXELS_PER_M { - // Save the absolute mouse position for tethering later - let mouse_pos_m = self.point_px_to_m(mouse_pos_px); + // Save the absolute mouse position in meters for tethering later + let mouse_pos_m = self.point_px_to_m(mouse_pos_px); - self.pixels_per_m *= 1.2; - self.normalise_zoom(); - - // Perform tethering (zoom in on mouse position) - self.translation_px += mouse_pos_px - self.point_m_to_px(mouse_pos_m); - - true + // Make sure the desired scale stays within the bounds and in whole numbers + let desired_px_per_m = if desired_px_per_m < MIN_PIXELS_PER_M { + MIN_PIXELS_PER_M as u32 as f32 + } else if desired_px_per_m > MAX_PIXELS_PER_M { + MAX_PIXELS_PER_M as u32 as f32 } else { - false - } - } - - /// Attempts to zoom out a step and return true. - /// If the minimum zoom is reached, this function changes nothing and returns false. - pub fn try_zoom_out(&mut self, mouse_pos_px: Vec2<f32>) -> bool { - if self.pixels_per_m > MIN_PIXELS_PER_M { - // Save the absolute mouse position for tethering later - let mouse_pos_m = self.point_px_to_m(mouse_pos_px); - - self.pixels_per_m /= 1.2; - self.normalise_zoom(); + desired_px_per_m as u32 as f32 + }; - // Perform tethering (zoom out at mouse position) - self.translation_px += mouse_pos_px - self.point_m_to_px(mouse_pos_m); + /* Adjust to the desired scale and bring the map back to its desired position according to + * the mouse pointer position. + */ + self.pixels_per_m = desired_px_per_m; + self.translation_px += mouse_pos_px - self.point_m_to_px(mouse_pos_m); - true - } else { - false - } + true } /// Move the canvas by the vector in pixels. |
