diff --git a/profile.json b/profile.json new file mode 100644 index 0000000..b878d1a --- /dev/null +++ b/profile.json @@ -0,0 +1,20 @@ +{ + "root_path": "/home/filipe/.wallpaper/active", + "panels": [ + { + "geometry": { + "pos": { + "x": 1360, + "y": 0 + }, + "size": { + "x": 1920, + "y": 1080 + } + }, + "duration": 1800, + "fade_point": 1440, + "parallax_ratio": 0.9 + } + ] +} \ No newline at end of file diff --git a/run.sh b/run.sh index c35b5ef..989e985 100755 --- a/run.sh +++ b/run.sh @@ -3,4 +3,4 @@ set -e cargo run -- \ - -p ~/.wallpaper/profiles/full.json + -p profile.json diff --git a/zsw-panels/src/panel.rs b/zsw-panels/src/panel.rs index b058373..b2858db 100644 --- a/zsw-panels/src/panel.rs +++ b/zsw-panels/src/panel.rs @@ -15,16 +15,25 @@ pub struct Panel { /// Fade point (in frames) pub fade_point: u64, + + /// Parallax scale, 0.0 .. 1.0 + #[serde(default = "default_parallax_ratio")] + pub parallax_ratio: f32, } impl Panel { /// Creates a new panel #[must_use] - pub fn new(geometry: Rect, duration: u64, fade_point: u64) -> Self { + pub fn new(geometry: Rect, duration: u64, fade_point: u64, parallax_ratio: f32) -> Self { Self { geometry, duration, fade_point, + parallax_ratio, } } } + +fn default_parallax_ratio() -> f32 { + 1.0 +} diff --git a/zsw-panels/src/state.rs b/zsw-panels/src/state.rs index 160ac54..949c5b2 100644 --- a/zsw-panels/src/state.rs +++ b/zsw-panels/src/state.rs @@ -153,28 +153,25 @@ impl PanelState { PanelStateImages::Empty => (None, None), PanelStateImages::PrimaryOnly { front, .. } => ( Some(PanelStateImageDescriptor { - image: &front.image, + image: front, alpha: 1.0, progress, - swap_dir: front.swap_dir, - panel_size: self.panel.geometry.size, + panel: &self.panel, }), None, ), PanelStateImages::Both { front, back } => ( Some(PanelStateImageDescriptor { - image: &front.image, + image: front, alpha: 1.0 - back_alpha, progress, - swap_dir: front.swap_dir, - panel_size: self.panel.geometry.size, + panel: &self.panel, }), Some(PanelStateImageDescriptor { - image: &back.image, - alpha: back_alpha, - progress: back_progress, - swap_dir: back.swap_dir, - panel_size: self.panel.geometry.size, + image: back, + alpha: back_alpha, + progress: back_progress, + panel: &self.panel, }), ), }; @@ -230,7 +227,7 @@ pub struct PanelStateImage { #[derive(Clone, Copy, Debug)] pub struct PanelStateImageDescriptor<'a> { /// Image - image: &'a PanelImage, + image: &'a PanelStateImage, /// Alpha alpha: f32, @@ -238,11 +235,8 @@ pub struct PanelStateImageDescriptor<'a> { /// Progress progress: f32, - /// Swap direction? - swap_dir: bool, - - /// Panel size - panel_size: Vector2, + /// Panel + panel: &'a Panel, } impl<'a> PanelStateImageDescriptor<'a> { @@ -250,22 +244,46 @@ impl<'a> PanelStateImageDescriptor<'a> { #[must_use] pub fn uvs_matrix(&self) -> Matrix4 { // Provides the correct ratio for the image - let ratio_uvs = self.ratio_uvs(); - let ratio_scalar = Matrix4::from_nonuniform_scale(ratio_uvs.x, ratio_uvs.y, 1.0); + let ratio = self.ratio(); + let ratio_scalar = Matrix4::from_nonuniform_scale(ratio.x, ratio.y, 1.0); // Offsets the image due to it's progress - let offset_uvs = self.offset_uvs(ratio_uvs); - let progress_offset = Matrix4::from_translation(Vector3::new(offset_uvs.x, offset_uvs.y, 0.0)); + let offset = self.offset(ratio); + let progress_offset = Matrix4::from_translation(Vector3::new(offset.x, offset.y, 0.0)); - progress_offset * ratio_scalar + // Base matrix + let base_matrix = progress_offset * ratio_scalar; + + // Calculate the parallax matrix + let parallax_matrix = self.parallax_matrix(ratio); + + // Then add it to our setup + parallax_matrix * base_matrix } - /// Calculates the offset uvs. + /// Calculates the parallax matrix /// - /// These uvs serve to scroll the image depending on our progress. - fn offset_uvs(&self, ratio_uvs: Vector2) -> Vector2 { + /// This matrix will add parallax to the existing matrix setup + fn parallax_matrix(&self, ratio: Vector2) -> Matrix4 { + // Matrices to move image center to origin, and then back + let middle_pos = Vector3::new(ratio.x / 2.0, ratio.y / 2.0, 0.0); + let move_origin = Matrix4::from_translation(-middle_pos); + let move_back = Matrix4::from_translation(middle_pos); + + // Matrix to scale the image down so we can add later movement + let scalar = Matrix4::from_nonuniform_scale(self.panel.parallax_ratio, self.panel.parallax_ratio, 1.0); + + // Center image on origin, scale it, move it by parallax and move it back + // TODO: Move parallax by mouse + move_back * scalar * move_origin + } + + /// Calculates the offset + /// + /// This offset serve to scroll the image depending on our progress. + fn offset(&self, ratio_uvs: Vector2) -> Vector2 { // If we're going backwards, invert progress - let progress = match self.swap_dir { + let progress = match self.image.swap_dir { true => 1.0 - self.progress, false => self.progress, }; @@ -274,13 +292,23 @@ impl<'a> PanelStateImageDescriptor<'a> { Vector2::new(progress * (1.0 - ratio_uvs.x), progress * (1.0 - ratio_uvs.y)) } - /// Calculates the ratio uvs. + /// Calculates the ratio /// - /// These uvs are multiplied by the base uvs to fix the stretching + /// This ratio is multiplied by the base uvs to fix the stretching /// that comes from having a square coordinate system [0.0 .. 1.0] x [0.0 .. 1.0] - fn ratio_uvs(&self) -> Vector2 { - let image_size = self.image.size().cast().expect("Image size didn't fit into an `i32`"); - let panel_size = self.panel_size.cast().expect("Panel size didn't fit into an `i32`"); + fn ratio(&self) -> Vector2 { + let image_size = self + .image + .image + .size() + .cast() + .expect("Image size didn't fit into an `i32`"); + let panel_size = self + .panel + .geometry + .size + .cast() + .expect("Panel size didn't fit into an `i32`"); // Image and panel ratios let image_ratio = Rational32::new(image_size.x, image_size.y); @@ -309,7 +337,7 @@ impl<'a> PanelStateImageDescriptor<'a> { /// Returns the image to render pub fn image(&self) -> &'a PanelImage { - self.image + &self.image.image } } diff --git a/zsw-settings-window/src/lib.rs b/zsw-settings-window/src/lib.rs index 007b279..0c9f30a 100644 --- a/zsw-settings-window/src/lib.rs +++ b/zsw-settings-window/src/lib.rs @@ -471,6 +471,7 @@ fn draw_panels<'panels>( new_panel_state.geometry, new_panel_state.duration, new_panel_state.fade_point, + 1.0, // TODO: Add to new panel state ), ); } @@ -545,6 +546,11 @@ impl<'panel> egui::Widget for PanelWidget<'panel> { egui::Slider::new(&mut self.panel.panel.duration, 0..=10800).ui(ui); }); + ui.horizontal(|ui| { + ui.label("Parallax ratio"); + egui::Slider::new(&mut self.panel.panel.parallax_ratio, 0.0..=1.0).ui(ui); + }); + ui.collapsing("Images", |ui| { match &mut self.panel.images { PanelStateImages::Empty => (),