wisp_storybook/stories/
s_graphics_ellipse.rs1use glam::Vec2;
4use wisp::application::Application;
5use wisp::{Color, Fill, Graphics, Stage, Stroke};
6
7use crate::story::Story;
8
9pub fn story() -> Story {
10 Story {
11 id: "graphics-ellipse",
12 category: "Graphics",
13 title: "Animated click ripple",
14 milestone: "M0.13",
15 writeup: include_str!("writeups/graphics_ellipse.md"),
16 build,
17 tick: Some(tick),
18 }
19}
20
21fn build(_app: &Application, stage: &mut Stage) {
22 let g = Graphics::new();
23 let _ = stage.add_child(stage.root(), g);
24}
25
26fn tick(stage: &mut Stage, t: f32) {
27 let root_id = stage.root();
28 let child_ids: Vec<_> = stage
29 .get(root_id)
30 .map(|n| n.container().children().collect())
31 .unwrap_or_default();
32 let Some(graphics_id) = child_ids.first().copied() else {
33 return;
34 };
35 let Some(node) = stage.get_mut(graphics_id) else {
36 return;
37 };
38 let wisp::Node::Graphics(g) = node else {
39 return;
40 };
41
42 *g = Graphics::new();
43
44 for i in 0u8..3 {
46 let i_f = f32::from(i);
47 let offset = i_f * 0.6;
48 let phase = (t - offset).max(0.0) % 2.5;
49 let progress = (phase / 2.0).min(1.0);
50 let alpha = (1.0 - progress).max(0.0);
51 let radius = 0.15 + progress * 0.6;
52 let x = -0.6 + i_f * 0.6;
53
54 g.fill(Fill::Solid(Color::rgba(1.0, 1.0, 1.0, alpha * 0.25)));
55 g.stroke(Some(Stroke::new(
56 0.025,
57 Color::rgba(1.0, 1.0, 1.0, alpha * 0.9),
58 )));
59 g.draw_ellipse(Vec2::new(x, 0.0), Vec2::splat(radius));
60 }
61}