Skip to content

Instantly share code, notes, and snippets.

@fgimian
Last active November 19, 2022 21:54
Show Gist options
  • Save fgimian/aaf3fe7c2db4e19170f581cf1378b7a8 to your computer and use it in GitHub Desktop.
Save fgimian/aaf3fe7c2db4e19170f581cf1378b7a8 to your computer and use it in GitHub Desktop.
Animations with egui
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release
use eframe::egui;
use egui::{color, pos2, Color32, Id, Rect, Rounding};
fn main() {
let options = eframe::NativeOptions::default();
eframe::run_native(
"My egui App",
options,
Box::new(|cc| {
let app = MyApp::default();
// Set the initial opacity of the rectangle to write the current value to memory in
// the animation manager.
let opacity = match app.animate_direction {
AnimateDirection::FadeIn => 1.0,
AnimateDirection::FadeOut => 0.0,
};
cc.egui_ctx
.animate_value_with_time(app.rectangle_id, opacity, 0.0);
Box::new(app)
}),
);
}
#[derive(PartialEq)]
enum AnimateDirection {
FadeIn,
FadeOut,
}
struct MyApp {
rectangle_id: Id,
current_opacity: f32,
animate_direction: AnimateDirection,
}
impl Default for MyApp {
fn default() -> Self {
Self {
rectangle_id: Id::new("rectangle"),
current_opacity: 0.0,
animate_direction: AnimateDirection::FadeOut,
}
}
}
impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
ui.painter().rect_filled(
Rect::from_min_max(pos2(0.0, 0.0), pos2(300.0, 300.0)),
Rounding::none(),
Color32::from_white_alpha(color::linear_u8_from_linear_f32(self.current_opacity)),
);
if ui.button("Animate").clicked() {
// Switch animation direction.
self.animate_direction = match self.animate_direction {
AnimateDirection::FadeIn => AnimateDirection::FadeOut,
AnimateDirection::FadeOut => AnimateDirection::FadeIn,
};
// To ensure smooth transitions with different times, we need to clear the
// animation manager and then provide it the current value so it knows where to
// animate from.
ctx.clear_animations();
ctx.animate_value_with_time(self.rectangle_id, self.current_opacity, 0.0);
ctx.request_repaint();
}
// Perform the fade in or fade out if required using different timing for each to
// demonstrate that the approach used results in a smooth transition.
if self.animate_direction == AnimateDirection::FadeIn && self.current_opacity != 1.0 {
self.current_opacity = ctx.animate_value_with_time(self.rectangle_id, 1.0, 2.0);
} else if self.animate_direction == AnimateDirection::FadeOut
&& self.current_opacity != 0.0
{
self.current_opacity = ctx.animate_value_with_time(self.rectangle_id, 0.0, 4.0);
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment