Skip to main content

wisp_storybook/stories/
s_solid_redaction.rs

1//! Story: solid-color redaction (M-MASK.5 / AUT-23).
2//!
3//! Two redaction variants side-by-side over the same screen-capture
4//! backdrop: a hard rectangle (left) and a rounded rectangle (right).
5//! Both are filled with opaque black — the cinematic "this content
6//! is sensitive, full stop" treatment.
7
8use glam::Vec2;
9use wisp::application::Application;
10use wisp::math::Rect;
11use wisp::render::Renderer;
12use wisp::{Color, Fill, Graphics, MaskShape, RenderTexture, Sprite, Stage, Texture};
13
14use crate::story::Story;
15
16pub fn story() -> Story {
17    Story {
18        id: "solid-redaction",
19        category: "Mask",
20        title: "Solid redaction",
21        milestone: "M-MASK.5 / AUT-23",
22        writeup: include_str!("writeups/solid_redaction.md"),
23        build,
24        tick: None,
25    }
26}
27
28fn build(app: &Application, stage: &mut Stage) {
29    let format = wgpu::TextureFormat::Rgba8Unorm;
30    let renderer = Renderer::new(app, format).expect("renderer");
31
32    // Shared screen-capture backdrop (gradient + grid lines).
33    let base_rt = render_capture(&renderer, app, format);
34
35    // Left sprite — sharp rectangle.
36    let rect_region = Rect::new(-0.5, -0.3, 1.0, 0.5);
37    let left_rt = RenderTexture::with_format(app, 192, 192, format);
38    renderer.apply_solid_redaction(
39        app,
40        MaskShape::rect(rect_region),
41        Color::rgba_u8(20, 20, 20, 255),
42        &base_rt,
43        &left_rt,
44    );
45    let left_bytes = left_rt.read_pixels(app);
46    let left_tex = Texture::from_rgba(app, 192, 192, &left_bytes);
47    let mut left = Sprite::from_texture(left_tex).with_anchor(Vec2::splat(0.5));
48    left.container.transform.position = Vec2::new(-0.46, 0.05);
49    left.container.transform.scale = Vec2::splat(0.42);
50    let _ = stage.add_child(stage.root(), left);
51
52    // Right sprite — rounded rectangle.
53    let rounded_rt = RenderTexture::with_format(app, 192, 192, format);
54    renderer.apply_solid_redaction(
55        app,
56        MaskShape::rounded_rect(rect_region, 0.12),
57        Color::rgba_u8(20, 20, 20, 255),
58        &base_rt,
59        &rounded_rt,
60    );
61    let right_bytes = rounded_rt.read_pixels(app);
62    let right_tex = Texture::from_rgba(app, 192, 192, &right_bytes);
63    let mut right = Sprite::from_texture(right_tex).with_anchor(Vec2::splat(0.5));
64    right.container.transform.position = Vec2::new(0.46, 0.05);
65    right.container.transform.scale = Vec2::splat(0.42);
66    let _ = stage.add_child(stage.root(), right);
67
68    // Captions under each variant.
69    let mut sharp_lbl = Graphics::new();
70    sharp_lbl.fill(Fill::Solid(Color::rgba_u8(220, 220, 130, 230)));
71    sharp_lbl.draw_rounded_rect(Rect::new(-0.7, -0.46, 0.48, 0.06), 0.014);
72    let _ = stage.add_child(stage.root(), sharp_lbl);
73
74    let mut rounded_lbl = Graphics::new();
75    rounded_lbl.fill(Fill::Solid(Color::rgba_u8(140, 200, 240, 230)));
76    rounded_lbl.draw_rounded_rect(Rect::new(0.22, -0.46, 0.48, 0.06), 0.014);
77    let _ = stage.add_child(stage.root(), rounded_lbl);
78}
79
80fn render_capture(
81    renderer: &Renderer,
82    app: &Application,
83    format: wgpu::TextureFormat,
84) -> RenderTexture {
85    let mut s = Stage::new();
86    let mut bg = Graphics::new();
87    bg.fill(Fill::LinearGradient {
88        start: Vec2::new(-1.0, 1.0),
89        end: Vec2::new(1.0, -1.0),
90        color_a: Color::rgba_u8(80, 130, 210, 255),
91        color_b: Color::rgba_u8(220, 110, 80, 255),
92    });
93    bg.draw_rect(Rect::new(-1.0, -1.0, 2.0, 2.0));
94    let _ = s.add_child(s.root(), bg);
95    for i in -4i16..=4 {
96        let x = f32::from(i) * 0.2;
97        let mut line = Graphics::new();
98        line.fill(Fill::Solid(Color::rgba_u8(255, 255, 255, 200)));
99        line.draw_rect(Rect::new(x - 0.005, -1.0, 0.01, 2.0));
100        let _ = s.add_child(s.root(), line);
101    }
102    for j in -4i16..=4 {
103        let y = f32::from(j) * 0.2;
104        let mut line = Graphics::new();
105        line.fill(Fill::Solid(Color::rgba_u8(255, 255, 255, 200)));
106        line.draw_rect(Rect::new(-1.0, y - 0.005, 2.0, 0.01));
107        let _ = s.add_child(s.root(), line);
108    }
109    let rt = RenderTexture::with_format(app, 192, 192, format);
110    let _ = renderer.render_stage(app, rt.view(), Color::BLACK, &s);
111    rt
112}