research api next up is starting to write it
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
# Animated Icon Plan
|
||||
|
||||
Animate a Discord emote (GIF) as the app's window/taskbar icon using eframe/egui.
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Add the `image` crate
|
||||
|
||||
```bash
|
||||
cargo add image
|
||||
```
|
||||
|
||||
### 2. Place your GIF
|
||||
|
||||
Save your Discord emote as `assets/emote.gif` in the project root.
|
||||
|
||||
### 3. Load GIF frames
|
||||
|
||||
```rust
|
||||
use eframe::egui::{ViewportCommand, IconData};
|
||||
use image::codecs::gif::GifDecoder;
|
||||
use image::AnimationDecoder;
|
||||
use std::time::Instant;
|
||||
|
||||
fn load_gif_frames(gif_bytes: &[u8]) -> Vec<IconData> {
|
||||
let decoder = GifDecoder::new(gif_bytes).unwrap();
|
||||
decoder.into_frames()
|
||||
.collect_frames()
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|f| {
|
||||
let rgba = f.into_buffer();
|
||||
let (w, h) = (rgba.width(), rgba.height());
|
||||
IconData { rgba: rgba.into_raw(), width: w, height: h }
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
```
|
||||
|
||||
Embed the GIF at compile time:
|
||||
|
||||
```rust
|
||||
let gif_bytes = include_bytes!("../assets/emote.gif");
|
||||
let icon_frames = load_gif_frames(gif_bytes);
|
||||
```
|
||||
|
||||
### 4. Add fields to the app struct
|
||||
|
||||
```rust
|
||||
icon_frames: Vec<IconData>,
|
||||
current_frame: usize,
|
||||
last_icon_swap: Instant,
|
||||
```
|
||||
|
||||
### 5. Cycle the icon in `update()`
|
||||
|
||||
```rust
|
||||
if !self.icon_frames.is_empty() {
|
||||
let elapsed = self.last_icon_swap.elapsed().as_millis();
|
||||
if elapsed > 100 { // ~10 FPS
|
||||
self.current_frame = (self.current_frame + 1) % self.icon_frames.len();
|
||||
let icon = self.icon_frames[self.current_frame].clone();
|
||||
ctx.send_viewport_cmd(ViewportCommand::Icon(Some(std::sync::Arc::new(icon))));
|
||||
self.last_icon_swap = Instant::now();
|
||||
ctx.request_repaint();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- The icon animates in both the taskbar and the window title bar on Windows.
|
||||
- Adjust the `100`ms interval to control animation speed.
|
||||
- Discord emotes are typically small (48x48 or 128x128) which works fine for icons.
|
||||
Reference in New Issue
Block a user