Files
Marcos Paulo cd43ea488e
ci / ci (macos-latest) (push) Has been cancelled
ci / ci (ubuntu-latest) (push) Has been cancelled
ci / ci (windows-latest) (push) Has been cancelled
feat: notescraft-lottie player crate, egui lottie_icon painter, icon_sheet review example, first icon animation set
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-16 19:42:57 -03:00

47 lines
2.4 KiB
Rust

//! Renders animated icons as contact sheets for visual review:
//! `icon_sheet out.png [--frames 9] [--cell 72] name...` draws one row of frames per icon (toggles run
//! `off` -> `on`, one-shots run their whole length).
use egui::{Color32, Rect, Vec2};
fn main() {
let mut args = std::env::args().skip(1);
let output = args.next().unwrap_or_else(|| "/tmp/icon-sheet.png".to_owned());
let (mut frames, mut cell) = (9_u16, 72.0_f32);
let mut names = Vec::new();
while let Some(arg) = args.next() {
match arg.as_str() {
"--frames" => frames = args.next().and_then(|v| v.parse().ok()).unwrap_or(frames),
"--cell" => cell = args.next().and_then(|v| v.parse().ok()).unwrap_or(cell),
name => names.push(name.to_owned()),
}
}
let rows = u16::try_from(names.len()).unwrap_or(u16::MAX);
let size = Vec2::new(cell * f32::from(frames) + 100.0, cell * f32::from(rows) + 8.0);
let mut harness = egui_kittest::Harness::builder().with_size(size).with_pixels_per_point(2.0).wgpu().build_ui_state(
|ui, state: &mut (Vec<String>, u16)| {
egui_extras::install_image_loaders(ui.ctx());
ui.painter().rect_filled(ui.max_rect(), 0.0, Color32::from_rgb(24, 24, 37));
for (row, name) in state.0.iter().enumerate() {
let top = 4.0 + cell * f32::from(u16::try_from(row).unwrap_or(0));
ui.painter().text(egui::pos2(6.0, top + cell / 2.0), egui::Align2::LEFT_CENTER, name, egui::FontId::proportional(11.0), Color32::GRAY);
let Some((first, last)) = notescraft_ui_egui::lottie_icon::range(name) else { continue };
for column in 0..state.1 {
let t = if state.1 > 1 { f32::from(column) / f32::from(state.1 - 1) } else { 0.0 };
let rect = Rect::from_min_size(egui::pos2(100.0 + cell * f32::from(column), top), Vec2::splat(cell)).shrink(cell * 0.22);
notescraft_ui_egui::lottie_icon::paint_frame(ui, name, rect, Color32::from_rgb(205, 214, 244), first + (last - first) * t);
}
}
},
(names, frames),
);
harness.run();
match harness.render() {
Ok(image) => match image.save(&output) {
Ok(()) => println!("wrote {output}"),
Err(error) => eprintln!("could not save {output}: {error}"),
},
Err(error) => eprintln!("render failed: {error}"),
}
}