mirror of
https://github.com/emilk/egui.git
synced 2026-09-02 06:40:06 -04:00
Add screenshot support for eframe web (#5438)
This implements web support for taking screenshots in an eframe app (and adds a nice demo). It also updates the native screenshot implementation to work with the wgpu gl backend. The wgpu implementation is quite different than the native one because we can't block to wait for the screenshot result, so instead I use a channel to pass the result to a future frame asynchronously. * Closes <https://github.com/emilk/egui/issues/5425> * [x] I have followed the instructions in the PR template https://github.com/user-attachments/assets/67cad40b-0384-431d-96a3-075cc3cb98fb
This commit is contained in:
@@ -38,6 +38,7 @@ impl Default for Demos {
|
||||
Box::<super::painting::Painting>::default(),
|
||||
Box::<super::pan_zoom::PanZoom>::default(),
|
||||
Box::<super::panels::Panels>::default(),
|
||||
Box::<super::screenshot::Screenshot>::default(),
|
||||
Box::<super::scrolling::Scrolling>::default(),
|
||||
Box::<super::sliders::Sliders>::default(),
|
||||
Box::<super::strip_demo::StripDemo>::default(),
|
||||
|
||||
@@ -24,6 +24,7 @@ pub mod painting;
|
||||
pub mod pan_zoom;
|
||||
pub mod panels;
|
||||
pub mod password;
|
||||
pub mod screenshot;
|
||||
pub mod scrolling;
|
||||
pub mod sliders;
|
||||
pub mod strip_demo;
|
||||
|
||||
84
crates/egui_demo_lib/src/demo/screenshot.rs
Normal file
84
crates/egui_demo_lib/src/demo/screenshot.rs
Normal file
@@ -0,0 +1,84 @@
|
||||
use egui::{Image, UserData, ViewportCommand, Widget};
|
||||
use std::sync::Arc;
|
||||
|
||||
/// Showcase [`ViewportCommand::Screenshot`].
|
||||
#[derive(PartialEq, Eq, Default)]
|
||||
pub struct Screenshot {
|
||||
image: Option<(Arc<egui::ColorImage>, egui::TextureHandle)>,
|
||||
continuous: bool,
|
||||
}
|
||||
|
||||
impl crate::Demo for Screenshot {
|
||||
fn name(&self) -> &'static str {
|
||||
"📷 Screenshot"
|
||||
}
|
||||
|
||||
fn show(&mut self, ctx: &egui::Context, open: &mut bool) {
|
||||
egui::Window::new(self.name())
|
||||
.open(open)
|
||||
.resizable(false)
|
||||
.default_width(250.0)
|
||||
.show(ctx, |ui| {
|
||||
use crate::View as _;
|
||||
self.ui(ui);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::View for Screenshot {
|
||||
fn ui(&mut self, ui: &mut egui::Ui) {
|
||||
ui.set_width(300.0);
|
||||
ui.vertical_centered(|ui| {
|
||||
ui.add(crate::egui_github_link_file!());
|
||||
});
|
||||
|
||||
ui.horizontal_wrapped(|ui| {
|
||||
ui.spacing_mut().item_spacing.x = 0.0;
|
||||
ui.label("This demo showcases how to take screenshots via ");
|
||||
ui.code("ViewportCommand::Screenshot");
|
||||
ui.label(".");
|
||||
});
|
||||
|
||||
ui.horizontal_top(|ui| {
|
||||
let capture = ui.button("📷 Take Screenshot").clicked();
|
||||
ui.checkbox(&mut self.continuous, "Capture continuously");
|
||||
if capture || self.continuous {
|
||||
ui.ctx()
|
||||
.send_viewport_cmd(ViewportCommand::Screenshot(UserData::default()));
|
||||
}
|
||||
});
|
||||
|
||||
let image = ui.ctx().input(|i| {
|
||||
i.events
|
||||
.iter()
|
||||
.filter_map(|e| {
|
||||
if let egui::Event::Screenshot { image, .. } = e {
|
||||
Some(image.clone())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.last()
|
||||
});
|
||||
|
||||
if let Some(image) = image {
|
||||
self.image = Some((
|
||||
image.clone(),
|
||||
ui.ctx()
|
||||
.load_texture("screenshot_demo", image, Default::default()),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some((_, texture)) = &self.image {
|
||||
Image::new(texture).shrink_to_fit().ui(ui);
|
||||
} else {
|
||||
ui.group(|ui| {
|
||||
ui.set_width(ui.available_width());
|
||||
ui.set_height(100.0);
|
||||
ui.centered_and_justified(|ui| {
|
||||
ui.label("No screenshot taken yet.");
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user