Add image zooming
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Isaac Mills 2024-03-18 23:25:49 -04:00
parent cef51159bd
commit bfbe387afa
Signed by: fnmain
GPG key ID: B67D7410F33A0F61

View file

@ -7,8 +7,8 @@ use cosmic_jotdown::jotdown::{self, Event, ListKind};
use cosmic_jotdown::{Indent, INDENT_AMOUNT};
use eframe::egui::mutex::{Mutex, RwLock};
use eframe::egui::{
self, lerp, Align2, Image, ImageSize, ImageSource, OpenUrl, Pos2, Rect, Rounding, Sense,
Stroke, Vec2,
self, lerp, Align2, Id, Image, ImageSize, ImageSource, LayerId, OpenUrl, Pos2, Rect, Rounding,
Sense, Stroke, Vec2,
};
use eframe::egui_wgpu::{self, wgpu};
use egui::{Color32, Frame};
@ -26,6 +26,8 @@ use wgpu::util::DeviceExt;
pub struct Portfolio {
custom: Custom3d,
zoomed: bool,
image_zoomed: bool,
last_image_zoomed: Id,
hovered: bool,
click_time_offset: f64,
hover_time_offset: f64,
@ -284,7 +286,7 @@ impl ContextWindow {
);
self.size.y += new_size.y + paragraph_height;
} else {
last_image_size = Some(size);
last_image_size = Some(size + Vec2::new(IMAGE_PADDING, 0.0));
}
}
res
@ -405,6 +407,8 @@ impl Portfolio {
Self {
custom: Custom3d::new(cc).unwrap(),
zoomed: false,
image_zoomed: false,
last_image_zoomed: Id::NULL,
hovered: false,
click_time_offset: 0.0,
hover_time_offset: 0.0,
@ -437,7 +441,6 @@ impl Portfolio {
self.to_pos = point.into();
}
self.zoomed = true;
log::info!("{:?}", (self.from_size, self.from_pos));
}
}
@ -541,6 +544,7 @@ impl eframe::App for Portfolio {
self.name_buffers = name_buffers;
}
self.max_size = ui.max_rect();
let time = ui.input(|i| i.time);
let mut scroll_area = egui::ScrollArea::vertical().show_viewport(ui, |ui, rect| {
let max_rect = ui.max_rect();
ui.allocate_exact_size(
@ -558,16 +562,14 @@ impl eframe::App for Portfolio {
functions::EaseOutCubic,
if self.zoomed { 1.0 } else { 0.0 },
if self.zoomed { 0.0 } else { 1.0 },
ui.input(|i| i.time)
- self.click_time_offset
- if self.zoomed { 0.0 } else { 0.5 },
time - self.click_time_offset - if self.zoomed { 0.0 } else { 0.5 },
1.0,
);
let zoom_view_opacity = keyframe::ease_with_scaled_time(
functions::EaseOutCubic,
if self.zoomed { 0.0 } else { 1.0 },
if self.zoomed { 1.0 } else { 0.0 },
ui.input(|i| i.time) - self.click_time_offset,
time - self.click_time_offset,
1.0,
);
let mut buffer_offset = 0.0;
@ -684,17 +686,112 @@ impl eframe::App for Portfolio {
}
}
ContextBlock::Image { image, .. } => {
image
.clone()
.tint(Color32::WHITE.gamma_multiply(zoom_view_opacity))
.paint_at(ui, context_block.0.translate(rect.min.to_vec2()));
let image_rect = context_block.0.translate(rect.min.to_vec2());
let image_response = ui.allocate_rect(image_rect, Sense::click());
let time_offset = ui.memory_mut(|m| {
let time_offset =
m.data.get_temp_mut_or_default::<f64>(image_response.id);
if image_response.clicked() && !self.image_zoomed {
link_clicked = true;
*time_offset = time;
self.last_image_zoomed = image_response.id;
self.image_zoomed = true;
}
*time_offset
});
if image_response.hovered() && !self.image_zoomed {
ui.ctx().set_cursor_icon(egui::CursorIcon::ZoomIn);
}
let fs_rect = Align2::CENTER_CENTER.align_size_within_rect(
{
let max_size = self.max_size.shrink(32.0).size();
ImageSize {
max_size,
..Default::default()
}
.calc_size(max_size, image_rect.size())
},
self.max_size,
);
if self.last_image_zoomed == image_response.id {
let ui = egui::Ui::new(
ui.ctx().clone(),
LayerId::debug(),
Id::new("image_zoom"),
self.max_size,
self.max_size,
);
let t = keyframe::ease_with_scaled_time(
functions::EaseInOutCubic,
if self.image_zoomed { 0.0 } else { 1.0 },
if self.image_zoomed { 1.0 } else { 0.0 },
time - time_offset,
0.5,
);
ui.painter().rect_filled(
ui.max_rect(),
Rounding::default(),
Color32::BLACK.gamma_multiply(
keyframe::ease_with_scaled_time(
functions::EaseInOutCubic,
if self.image_zoomed { 0.0 } else { 0.6 },
if self.image_zoomed { 0.6 } else { 0.0 },
time - time_offset,
0.5,
),
),
);
image
.clone()
.tint(Color32::WHITE.gamma_multiply(zoom_view_opacity))
.paint_at(&ui, image_rect.lerp_towards(&fs_rect, t));
} else {
image
.clone()
.tint(Color32::WHITE.gamma_multiply(zoom_view_opacity))
.paint_at(
ui,
image_rect.lerp_towards(
&fs_rect,
keyframe::ease_with_scaled_time(
functions::EaseInOutCubic,
1.0,
0.0,
time - time_offset,
0.5,
),
),
);
}
}
});
}
let mut hovered = false;
if self.zoomed {
if ui.input(|i| i.pointer.any_click()) && icon_link.is_none() && !link_clicked {
self.click(ui, None);
if ui.input(|i| i.pointer.any_click()) && !link_clicked {
if self.image_zoomed {
ui.memory_mut(|m| {
let time_offset = m
.data
.get_temp_mut_or_default::<f64>(self.last_image_zoomed);
link_clicked = true;
*time_offset = time;
self.image_zoomed = false;
});
} else if icon_link.is_none() {
self.click(ui, None);
}
}
} else {
if ui.input(|i| i.pointer.secondary_clicked()) {
@ -734,7 +831,6 @@ impl eframe::App for Portfolio {
let response = ui.allocate_rect(rect, Sense::click());
let response_hovered = response.hovered();
let time = ui.input(|i| i.time);
let opacity = ui.memory_mut(|m| {
let icon_state =
m.data.get_temp_mut_or_insert_with(response.id, || {