diff --git a/core/editor/src/consts.rs b/core/editor/src/consts.rs index acd0f5d8..ce92ef40 100644 --- a/core/editor/src/consts.rs +++ b/core/editor/src/consts.rs @@ -1,10 +1,12 @@ -pub const PLUS_KEY_ZOOM_MULTIPLIER: f64 = 1.25; -pub const MINUS_KEY_ZOOM_MULTIPLIER: f64 = 0.8; +pub const PLUS_KEY_ZOOM_RATE: f64 = 1.25; +pub const MINUS_KEY_ZOOM_RATE: f64 = 0.8; pub const VIEWPORT_ZOOM_SCALE_MIN: f64 = 0.000_001; pub const VIEWPORT_ZOOM_SCALE_MAX: f64 = 1_000_000.; -pub const WHEEL_ZOOM_DIVISOR: f64 = 500.; -pub const MOUSE_ZOOM_DIVISOR: f64 = 400.; +pub const VIEWPORT_SCROLL_RATE: f64 = 0.6; + +pub const WHEEL_ZOOM_RATE: f64 = 1. / 600.; +pub const MOUSE_ZOOM_RATE: f64 = 1. / 400.; pub const ROTATE_SNAP_INTERVAL: f64 = 15.; diff --git a/core/editor/src/document/document_message_handler.rs b/core/editor/src/document/document_message_handler.rs index 415d4333..594f628b 100644 --- a/core/editor/src/document/document_message_handler.rs +++ b/core/editor/src/document/document_message_handler.rs @@ -1,6 +1,6 @@ use crate::message_prelude::*; use crate::{ - consts::{MOUSE_ZOOM_DIVISOR, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN, WHEEL_ZOOM_DIVISOR}, + consts::{MOUSE_ZOOM_RATE, VIEWPORT_SCROLL_RATE, VIEWPORT_ZOOM_SCALE_MAX, VIEWPORT_ZOOM_SCALE_MIN, WHEEL_ZOOM_RATE}, input::{mouse::ViewportPosition, InputPreprocessor}, }; use document_core::layers::Layer; @@ -40,7 +40,7 @@ pub enum DocumentMessage { Undo, MouseMove, TranslateCanvasBegin, - WheelCanvasTranslate, + WheelCanvasTranslate { use_y_as_x: bool }, RotateCanvasBegin { snap: bool }, ZoomCanvasBegin, TranslateCanvasEnd, @@ -111,7 +111,7 @@ impl DocumentMessageHandler { let layerdata = self.layerdata(&path); responses.push_back( DocumentOperation::SetLayerTransform { - path: path, + path, transform: layerdata.calculate_transform().to_cols_array(), } .into(), @@ -431,7 +431,7 @@ impl MessageHandler for DocumentMessageHand } if self.zooming { let difference = self.mouse_pos.y as f64 - ipp.mouse.position.y as f64; - let amount = 1. + difference / MOUSE_ZOOM_DIVISOR; + let amount = 1. + difference * MOUSE_ZOOM_RATE; let layerdata = self.layerdata_mut(&vec![]); let new = (layerdata.scale * amount).clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX); layerdata.scale = new; @@ -454,20 +454,31 @@ impl MessageHandler for DocumentMessageHand self.create_document_transform_from_layerdata(&ipp.viewport_size, responses); } WheelCanvasZoom => { - let scroll = ipp.mouse.scroll_delta.y as f64; - let amount = if ipp.mouse.scroll_delta.y > 0 { - 1. + scroll / -WHEEL_ZOOM_DIVISOR - } else { - 1. / (1. + scroll / WHEEL_ZOOM_DIVISOR) + let scroll = ipp.mouse.scroll_delta.scroll_delta(); + let mouse = ipp.mouse.position.to_dvec2(); + let viewport_size = ipp.viewport_size.to_dvec2(); + let mut zoom_factor = 1. + scroll.abs() * WHEEL_ZOOM_RATE; + if ipp.mouse.scroll_delta.y > 0 { + zoom_factor = 1. / zoom_factor }; + let new_viewport_size = viewport_size * (1. / zoom_factor); + let delta_size = viewport_size - new_viewport_size; + let mouse_percent = mouse / viewport_size; + let delta = delta_size * -2. * (mouse_percent - (0.5, 0.5).into()); + + let transformed_delta = self.active_document().document.root.transform.inverse().transform_vector2(delta); let layerdata = self.layerdata_mut(&vec![]); - let new = (layerdata.scale * amount).clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX); + let new = (layerdata.scale * zoom_factor).clamp(VIEWPORT_ZOOM_SCALE_MIN, VIEWPORT_ZOOM_SCALE_MAX); layerdata.scale = new; + layerdata.translation += transformed_delta; responses.push_back(FrontendMessage::SetCanvasZoom { new_zoom: layerdata.scale }.into()); self.create_document_transform_from_layerdata(&ipp.viewport_size, responses); } - WheelCanvasTranslate => { - let delta = -ipp.mouse.scroll_delta.to_dvec2(); + WheelCanvasTranslate { use_y_as_x } => { + let delta = match use_y_as_x { + false => -ipp.mouse.scroll_delta.to_dvec2(), + true => (-ipp.mouse.scroll_delta.y as f64, 0.).into(), + } * VIEWPORT_SCROLL_RATE; let transformed_delta = self.active_document().document.root.transform.inverse().transform_vector2(delta); let layerdata = self.layerdata_mut(&vec![]); layerdata.translation += transformed_delta; diff --git a/core/editor/src/input/input_mapper.rs b/core/editor/src/input/input_mapper.rs index 31be82e5..ed885e18 100644 --- a/core/editor/src/input/input_mapper.rs +++ b/core/editor/src/input/input_mapper.rs @@ -1,4 +1,4 @@ -use crate::consts::{MINUS_KEY_ZOOM_MULTIPLIER, PLUS_KEY_ZOOM_MULTIPLIER}; +use crate::consts::{MINUS_KEY_ZOOM_RATE, PLUS_KEY_ZOOM_RATE}; use crate::message_prelude::*; use crate::tool::ToolType; @@ -191,13 +191,14 @@ impl Default for Mapping { entry! {action=DocumentMessage::ZoomCanvasBegin, key_down=Mmb, modifiers=[KeyShift]}, entry! {action=DocumentMessage::TranslateCanvasBegin, key_down=Mmb}, entry! {action=DocumentMessage::TranslateCanvasEnd, key_up=Mmb}, - entry! {action=DocumentMessage::MultiplyCanvasZoom(PLUS_KEY_ZOOM_MULTIPLIER), key_down=KeyPlus, modifiers=[KeyControl]}, - entry! {action=DocumentMessage::MultiplyCanvasZoom(PLUS_KEY_ZOOM_MULTIPLIER), key_down=KeyEquals, modifiers=[KeyControl]}, - entry! {action=DocumentMessage::MultiplyCanvasZoom(MINUS_KEY_ZOOM_MULTIPLIER), key_down=KeyMinus, modifiers=[KeyControl]}, + entry! {action=DocumentMessage::MultiplyCanvasZoom(PLUS_KEY_ZOOM_RATE), key_down=KeyPlus, modifiers=[KeyControl]}, + entry! {action=DocumentMessage::MultiplyCanvasZoom(PLUS_KEY_ZOOM_RATE), key_down=KeyEquals, modifiers=[KeyControl]}, + entry! {action=DocumentMessage::MultiplyCanvasZoom(MINUS_KEY_ZOOM_RATE), key_down=KeyMinus, modifiers=[KeyControl]}, entry! {action=DocumentMessage::SetCanvasZoom(1.), key_down=Key1, modifiers=[KeyControl]}, entry! {action=DocumentMessage::SetCanvasZoom(2.), key_down=Key2, modifiers=[KeyControl]}, entry! {action=DocumentMessage::WheelCanvasZoom, message=InputMapperMessage::MouseScroll, modifiers=[KeyControl]}, - entry! {action=DocumentMessage::WheelCanvasTranslate, message=InputMapperMessage::MouseScroll}, + entry! {action=DocumentMessage::WheelCanvasTranslate{use_y_as_x: true}, message=InputMapperMessage::MouseScroll, modifiers=[KeyShift]}, + entry! {action=DocumentMessage::WheelCanvasTranslate{use_y_as_x: false}, message=InputMapperMessage::MouseScroll}, entry! {action=DocumentMessage::NewDocument, key_down=KeyN, modifiers=[KeyShift]}, entry! {action=DocumentMessage::NextDocument, key_down=KeyTab, modifiers=[KeyShift]}, entry! {action=DocumentMessage::CloseActiveDocument, key_down=KeyW, modifiers=[KeyShift]}, diff --git a/core/editor/src/input/mouse.rs b/core/editor/src/input/mouse.rs index c39785c2..35d3c68f 100644 --- a/core/editor/src/input/mouse.rs +++ b/core/editor/src/input/mouse.rs @@ -32,6 +32,10 @@ impl ScrollDelta { pub fn to_dvec2(&self) -> DVec2 { DVec2::new(self.x as f64, self.y as f64) } + pub fn scroll_delta(&self) -> f64 { + let (dx, dy) = (self.x, self.y); + dy.signum() as f64 * ((dy * dy + i32::min(dy.abs(), dx.abs()).pow(2)) as f64).sqrt() + } } #[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]