Minimum viewport scale cover when zooming (#1282)
* Minimum viewport scale cover * Update const name
This commit is contained in:
parent
26473a8002
commit
4d1c5fc8bf
|
|
@ -5,6 +5,7 @@ pub const VIEWPORT_ZOOM_WHEEL_RATE: f64 = (1. / 600.) * 3.;
|
|||
pub const VIEWPORT_ZOOM_MOUSE_RATE: f64 = 1. / 400.;
|
||||
pub const VIEWPORT_ZOOM_SCALE_MIN: f64 = 0.000_000_1;
|
||||
pub const VIEWPORT_ZOOM_SCALE_MAX: f64 = 10_000.;
|
||||
pub const VIEWPORT_ZOOM_MIN_FRACTION_COVER: f64 = 0.01;
|
||||
pub const VIEWPORT_ZOOM_LEVELS: [f64; 74] = [
|
||||
0.0001, 0.000125, 0.00016, 0.0002, 0.00025, 0.00032, 0.0004, 0.0005, 0.00064, 0.0008, 0.001, 0.0016, 0.002, 0.0025, 0.0032, 0.004, 0.005, 0.0064, 0.008, 0.01, 0.01125, 0.015, 0.02, 0.025, 0.03,
|
||||
0.04, 0.05, 0.06, 0.08, 0.1, 0.125, 0.15, 0.2, 0.25, 0.33333333, 0.4, 0.5, 0.66666666, 0.8, 1., 1.25, 1.6, 2., 2.5, 3.2, 4., 5., 6.4, 8., 10., 12.5, 16., 20., 25., 32., 40., 50., 64., 80., 100.,
|
||||
|
|
|
|||
|
|
@ -181,8 +181,12 @@ impl MessageHandler<DocumentMessage, (u64, &InputPreprocessorMessageHandler, &Pe
|
|||
}
|
||||
#[remain::unsorted]
|
||||
Navigation(message) => {
|
||||
self.navigation_handler
|
||||
.process_message(message, responses, (&self.document_legacy, ipp, self.selected_visible_layers_bounding_box(&render_data)));
|
||||
let document_bounds = self.document_bounds(&render_data);
|
||||
self.navigation_handler.process_message(
|
||||
message,
|
||||
responses,
|
||||
(&self.document_legacy, document_bounds, ipp, self.selected_visible_layers_bounding_box(&render_data)),
|
||||
);
|
||||
}
|
||||
#[remain::unsorted]
|
||||
Overlays(message) => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use crate::consts::{
|
||||
VIEWPORT_ROTATE_SNAP_INTERVAL, VIEWPORT_SCROLL_RATE, VIEWPORT_ZOOM_LEVELS, VIEWPORT_ZOOM_MOUSE_RATE, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR,
|
||||
VIEWPORT_ZOOM_WHEEL_RATE,
|
||||
VIEWPORT_ROTATE_SNAP_INTERVAL, VIEWPORT_SCROLL_RATE, VIEWPORT_ZOOM_LEVELS, VIEWPORT_ZOOM_MIN_FRACTION_COVER, VIEWPORT_ZOOM_MOUSE_RATE, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN,
|
||||
VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR, VIEWPORT_ZOOM_WHEEL_RATE,
|
||||
};
|
||||
use crate::messages::frontend::utility_types::MouseCursorIcon;
|
||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeysGroup};
|
||||
|
|
@ -51,11 +51,18 @@ impl Default for NavigationMessageHandler {
|
|||
}
|
||||
}
|
||||
|
||||
impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHandler, Option<[DVec2; 2]>)> for NavigationMessageHandler {
|
||||
impl MessageHandler<NavigationMessage, (&Document, Option<[DVec2; 2]>, &InputPreprocessorMessageHandler, Option<[DVec2; 2]>)> for NavigationMessageHandler {
|
||||
#[remain::check]
|
||||
fn process_message(&mut self, message: NavigationMessage, responses: &mut VecDeque<Message>, (document, ipp, selection_bounds): (&Document, &InputPreprocessorMessageHandler, Option<[DVec2; 2]>)) {
|
||||
fn process_message(
|
||||
&mut self,
|
||||
message: NavigationMessage,
|
||||
responses: &mut VecDeque<Message>,
|
||||
(document, document_bounds, ipp, selection_bounds): (&Document, Option<[DVec2; 2]>, &InputPreprocessorMessageHandler, Option<[DVec2; 2]>),
|
||||
) {
|
||||
use NavigationMessage::*;
|
||||
|
||||
let old_zoom = self.zoom;
|
||||
|
||||
#[remain::sorted]
|
||||
match message {
|
||||
DecreaseCanvasZoom { center_on_mouse } => {
|
||||
|
|
@ -157,6 +164,8 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||
let amount = 1. + difference * VIEWPORT_ZOOM_MOUSE_RATE;
|
||||
|
||||
self.zoom *= amount;
|
||||
self.zoom *= Self::clamp_zoom(self.zoom, document_bounds, old_zoom, ipp);
|
||||
|
||||
if let Some(mouse) = zoom_from_viewport {
|
||||
let zoom_factor = self.snapped_scale() / zoom_start;
|
||||
|
||||
|
|
@ -192,6 +201,7 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||
}
|
||||
SetCanvasZoom { zoom_factor } => {
|
||||
self.zoom = zoom_factor.clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
||||
self.zoom *= Self::clamp_zoom(self.zoom, document_bounds, old_zoom, ipp);
|
||||
responses.add(BroadcastEvent::DocumentIsDirty);
|
||||
responses.add(DocumentMessage::DirtyRenderDocumentInOutlineView);
|
||||
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||
|
|
@ -243,7 +253,8 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||
let mut zoom_factor = 1. + scroll.abs() * VIEWPORT_ZOOM_WHEEL_RATE;
|
||||
if ipp.mouse.scroll_delta.y > 0 {
|
||||
zoom_factor = 1. / zoom_factor
|
||||
};
|
||||
}
|
||||
zoom_factor *= Self::clamp_zoom(self.zoom * zoom_factor, document_bounds, old_zoom, ipp);
|
||||
|
||||
responses.add(self.center_zoom(ipp.viewport_bounds.size(), zoom_factor, ipp.mouse.position));
|
||||
responses.add(SetCanvasZoom { zoom_factor: self.zoom * zoom_factor });
|
||||
|
|
@ -351,4 +362,15 @@ impl NavigationMessageHandler {
|
|||
|
||||
NavigationMessage::TranslateCanvas { delta }.into()
|
||||
}
|
||||
|
||||
pub fn clamp_zoom(zoom: f64, document_bounds: Option<[DVec2; 2]>, old_zoom: f64, ipp: &InputPreprocessorMessageHandler) -> f64 {
|
||||
let document_size = (document_bounds.map(|[min, max]| max - min).unwrap_or_default() / old_zoom) * zoom;
|
||||
let scale_factor = (document_size / ipp.viewport_bounds.size()).max_element();
|
||||
|
||||
if scale_factor > f64::EPSILON * 100. && scale_factor.is_finite() && scale_factor < VIEWPORT_ZOOM_MIN_FRACTION_COVER {
|
||||
VIEWPORT_ZOOM_MIN_FRACTION_COVER / scale_factor
|
||||
} else {
|
||||
1.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue