gpui: Add support for animated images (#13809)

This PR adds support for animated images. The image requires a id for it
to actually animate across frames.

Currently it only has support for `GIF`, I tried adding decoding a
animated `WebP` into frames but it seems to error. This issue in the
image crate seems to document this
https://github.com/image-rs/image/issues/2263.

Not sure if this is the best way or the desired way for animated images
to work in GPUI but I would really like support for animated images.
Open to feedback.

Example Video:


https://github.com/zed-industries/zed/assets/76515905/011f790f-d070-499b-96c9-bbff141fb002



Closes https://github.com/zed-industries/zed/issues/9993

Release Notes:

- N/A

---------

Co-authored-by: Antonio Scandurra <me@as-cii.com>
Co-authored-by: Nathan <nathan@zed.dev>
This commit is contained in:
Matin Aniss 2024-07-27 22:05:37 +10:00 committed by GitHub
parent c0df1e1846
commit 4bd935b409
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 212 additions and 51 deletions

View file

@ -0,0 +1,50 @@
use gpui::{
div, img, prelude::*, App, AppContext, ImageSource, Render, ViewContext, WindowOptions,
};
use std::path::PathBuf;
struct GifViewer {
gif_path: PathBuf,
}
impl GifViewer {
fn new(gif_path: PathBuf) -> Self {
Self { gif_path }
}
}
impl Render for GifViewer {
fn render(&mut self, _cx: &mut ViewContext<Self>) -> impl IntoElement {
div().size_full().child(
img(ImageSource::File(self.gif_path.clone().into()))
.size_full()
.object_fit(gpui::ObjectFit::Contain)
.id("gif"),
)
}
}
fn main() {
env_logger::init();
App::new().run(|cx: &mut AppContext| {
let cwd = std::env::current_dir().expect("Failed to get current working directory");
let gif_path = cwd.join("crates/gpui/examples/image/black-cat-typing.gif");
if !gif_path.exists() {
eprintln!("Image file not found at {:?}", gif_path);
eprintln!("Make sure you're running this example from the root of the gpui crate");
cx.quit();
return;
}
cx.open_window(
WindowOptions {
focus: true,
..Default::default()
},
|cx| cx.new_view(|_cx| GifViewer::new(gif_path)),
)
.unwrap();
cx.activate(true);
});
}