mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-03 00:48:12 +08:00
Minimum viewport scale cover when zooming (#1282)
* Minimum viewport scale cover * Update const name
This commit is contained in:
@@ -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_MOUSE_RATE: f64 = 1. / 400.;
|
||||||
pub const VIEWPORT_ZOOM_SCALE_MIN: f64 = 0.000_000_1;
|
pub const VIEWPORT_ZOOM_SCALE_MIN: f64 = 0.000_000_1;
|
||||||
pub const VIEWPORT_ZOOM_SCALE_MAX: f64 = 10_000.;
|
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] = [
|
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.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.,
|
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]
|
#[remain::unsorted]
|
||||||
Navigation(message) => {
|
Navigation(message) => {
|
||||||
self.navigation_handler
|
let document_bounds = self.document_bounds(&render_data);
|
||||||
.process_message(message, responses, (&self.document_legacy, ipp, self.selected_visible_layers_bounding_box(&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]
|
#[remain::unsorted]
|
||||||
Overlays(message) => {
|
Overlays(message) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::consts::{
|
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_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_WHEEL_RATE,
|
VIEWPORT_ZOOM_TO_FIT_PADDING_SCALE_FACTOR, VIEWPORT_ZOOM_WHEEL_RATE,
|
||||||
};
|
};
|
||||||
use crate::messages::frontend::utility_types::MouseCursorIcon;
|
use crate::messages::frontend::utility_types::MouseCursorIcon;
|
||||||
use crate::messages::input_mapper::utility_types::input_keyboard::{Key, KeysGroup};
|
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]
|
#[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::*;
|
use NavigationMessage::*;
|
||||||
|
|
||||||
|
let old_zoom = self.zoom;
|
||||||
|
|
||||||
#[remain::sorted]
|
#[remain::sorted]
|
||||||
match message {
|
match message {
|
||||||
DecreaseCanvasZoom { center_on_mouse } => {
|
DecreaseCanvasZoom { center_on_mouse } => {
|
||||||
@@ -157,6 +164,8 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
let amount = 1. + difference * VIEWPORT_ZOOM_MOUSE_RATE;
|
let amount = 1. + difference * VIEWPORT_ZOOM_MOUSE_RATE;
|
||||||
|
|
||||||
self.zoom *= amount;
|
self.zoom *= amount;
|
||||||
|
self.zoom *= Self::clamp_zoom(self.zoom, document_bounds, old_zoom, ipp);
|
||||||
|
|
||||||
if let Some(mouse) = zoom_from_viewport {
|
if let Some(mouse) = zoom_from_viewport {
|
||||||
let zoom_factor = self.snapped_scale() / zoom_start;
|
let zoom_factor = self.snapped_scale() / zoom_start;
|
||||||
|
|
||||||
@@ -192,6 +201,7 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
}
|
}
|
||||||
SetCanvasZoom { zoom_factor } => {
|
SetCanvasZoom { zoom_factor } => {
|
||||||
self.zoom = zoom_factor.clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX);
|
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(BroadcastEvent::DocumentIsDirty);
|
||||||
responses.add(DocumentMessage::DirtyRenderDocumentInOutlineView);
|
responses.add(DocumentMessage::DirtyRenderDocumentInOutlineView);
|
||||||
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
responses.add(PortfolioMessage::UpdateDocumentWidgets);
|
||||||
@@ -243,7 +253,8 @@ impl MessageHandler<NavigationMessage, (&Document, &InputPreprocessorMessageHand
|
|||||||
let mut zoom_factor = 1. + scroll.abs() * VIEWPORT_ZOOM_WHEEL_RATE;
|
let mut zoom_factor = 1. + scroll.abs() * VIEWPORT_ZOOM_WHEEL_RATE;
|
||||||
if ipp.mouse.scroll_delta.y > 0 {
|
if ipp.mouse.scroll_delta.y > 0 {
|
||||||
zoom_factor = 1. / zoom_factor
|
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(self.center_zoom(ipp.viewport_bounds.size(), zoom_factor, ipp.mouse.position));
|
||||||
responses.add(SetCanvasZoom { zoom_factor: self.zoom * zoom_factor });
|
responses.add(SetCanvasZoom { zoom_factor: self.zoom * zoom_factor });
|
||||||
@@ -351,4 +362,15 @@ impl NavigationMessageHandler {
|
|||||||
|
|
||||||
NavigationMessage::TranslateCanvas { delta }.into()
|
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.
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user