From a506a9e8c3462cfd8e6384386285c07f8f9a96a0 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Thu, 10 Jan 2019 11:06:50 +0100 Subject: Add pan and partial zoom implementation The zoom currently works only by zooming towards the center of the window, when instead it should zoom under the cursor. --- src/graphics.rs | 61 +++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 8 deletions(-) diff --git a/src/graphics.rs b/src/graphics.rs index 18ccfec..d50562d 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -1,8 +1,11 @@ use std::collections::HashMap; -use sfml::system::Vector2f; use sfml::window::mouse::Button; +use sfml::system::{ + Vector2f, +}; + use sfml::window::{ ContextSettings, Event, @@ -19,12 +22,12 @@ use sfml::graphics::{ Texture, Image, Color, - Rect, }; use sfml::graphics::{ RectangleShape, Transformable, + Rect, }; @@ -39,11 +42,18 @@ pub struct Graphics { view: View, // status running: bool, + panning: bool, + // pan + pan_start: Vector2f, + pan_start_center: Vector2f, + // absolute zoom + zoom: f32, // loaded resources tilesets: HashMap, textures: HashMap, } + impl Graphics { pub fn new() -> Graphics { let default_window_size = (1280, 720); @@ -80,6 +90,14 @@ impl Graphics { ), // status running: true, + panning: false, + // zoom and pan + pan_start: Vector2f::new(0.0, 0.0), + pan_start_center: Vector2f::new( + default_window_size.0 as f32 / 2.0, + default_window_size.1 as f32 / 2.0 + ), + zoom: 1.0, // resources tilesets: HashMap::new(), textures: HashMap::new(), @@ -141,6 +159,7 @@ impl Graphics { } }; + let image = match Image::from_memory(asset.as_ref()) { Some(image) => image, None => { @@ -205,23 +224,49 @@ impl Graphics { self.window.close(); self.running = false; }, - Event::MouseWheelScrolled { wheel: _, delta, x, y } => { + Event::MouseWheelScrolled { wheel: _, delta, x: _, y: _ } => { + // TODO: zoom towards (x, y) + + // delta is probalby a value between -1 and 1 + let local_zoom = 1.0 + delta * 0.1; + // update absolute zoom + self.zoom *= local_zoom; + self.view.zoom(local_zoom); + self.window.set_view(&self.view); }, - Event::MouseButtonPressed { button, x: _, y: _ } => { + Event::MouseButtonPressed { button, x, y} => { match button { - Button::Left => {}, - Button::Right => {} + Button::Right => {}, + Button::Left => { + // set pan start position + self.panning = true; + self.pan_start = Vector2f::new(x as f32, y as f32); + } _ => {}, } }, Event::MouseButtonReleased { button, x: _, y: _ } => { match button { - Button::Left => {} - Button::Right => {}, + Button::Right => {} + Button::Left => { + self.panning = false; + self.pan_start_center = self.view.center(); + }, _ => {}, } }, + Event::MouseMoved { x, y } => { + if self.panning { + // get delta of vectors + // (pan_start_pos - current_mouse_pos) * zoom + let delta = (self.pan_start - Vector2f::new(x as f32, y as f32)) * self.zoom; + + // move view by moving the center by delta + self.view.set_center(self.pan_start_center + delta); + self.window.set_view(&self.view); + } + } _ => {}, } } -- cgit v1.2.1