T25c Generative: canvas
InpaintCanvas lays a mask over a picture: brush strokes in shares of the picture, rastered into a 320-column grid where a later stroke wins and an erasing one clears, painted as merged rectangles snapped to device pixels. A ring follows the pointer at the brush's size; [ and ] size the brush and X swaps it when focused. MaskBrush sets paint or erase and the size, with Undo and Clear waiting for a stroke. Pointer strokes move to forms::pen, which SignaturePad and the canvas share.
This commit is contained in:
1 parent
c349a025e5
commit
02f0a8deaf
11 files changed
+853
-57
No files matched your search
@@ -0,0 +1,66 @@
|
||||
use ely_gpui_component::generative::{InpaintCanvas, MaskBrush, MaskStroke};
|
||||
use gpui::{App, IntoElement, ParentElement, Styled, Window, div, px};
|
||||
|
||||
use crate::{
|
||||
probe::probe,
|
||||
ui::{keep, section, set},
|
||||
};
|
||||
|
||||
/// A mask over the olive tree, painted before the demo opens.
|
||||
fn tree() -> Vec<MaskStroke> {
|
||||
vec![MaskStroke {
|
||||
points: vec![
|
||||
(0.07, 0.18),
|
||||
(0.12, 0.34),
|
||||
(0.09, 0.52),
|
||||
(0.13, 0.7),
|
||||
(0.1, 0.86),
|
||||
],
|
||||
radius: 0.07,
|
||||
erase: false,
|
||||
}]
|
||||
}
|
||||
|
||||
pub fn canvas(window: &mut Window, cx: &mut App) -> impl IntoElement + use<> {
|
||||
let strokes = keep("gen-mask", tree, window, cx);
|
||||
let brush = keep("gen-brush", || (0.05_f32, false), window, cx);
|
||||
let (now, (radius, erase)) = (strokes.read(cx).clone(), *brush.read(cx));
|
||||
let (painted, undone, cleared) = (strokes.clone(), strokes.clone(), strokes);
|
||||
let (keyed, set_brush) = (brush.clone(), brush);
|
||||
let count = now.len();
|
||||
section(
|
||||
"InpaintCanvas / MaskBrush",
|
||||
"A picture to repaint in part: paint a mask where it should change, erase where it went too far; the mask washes over the picture. On the canvas, [ and ] size the brush and X swaps painting for erasing. Undo takes the last stroke, Clear takes them all.",
|
||||
cx,
|
||||
)
|
||||
.child(
|
||||
div()
|
||||
.w(px(460.))
|
||||
.flex()
|
||||
.flex_col()
|
||||
.gap_3()
|
||||
.child(probe(
|
||||
"gen-canvas",
|
||||
div().w(px(460.)).child(
|
||||
InpaintCanvas::new("gen-canvas", asset!("atrium-olive.jpg"), 1.5, now)
|
||||
.brush(radius, erase)
|
||||
.on_stroke(move |stroke, _, cx| {
|
||||
let mut next = painted.read(cx).clone();
|
||||
next.push(stroke);
|
||||
set(&painted, next, cx)
|
||||
})
|
||||
.on_brush(move |radius, erase, _, cx| set(&keyed, (radius, erase), cx)),
|
||||
),
|
||||
))
|
||||
.child(
|
||||
MaskBrush::new("gen-mask-brush", radius, erase, count)
|
||||
.on_brush(move |radius, erase, _, cx| set(&set_brush, (radius, erase), cx))
|
||||
.on_undo(move |_, cx| {
|
||||
let mut next = undone.read(cx).clone();
|
||||
next.pop();
|
||||
set(&undone, next, cx)
|
||||
})
|
||||
.on_clear(move |_, cx| set(&cleared, Vec::new(), cx)),
|
||||
),
|
||||
)
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
mod canvas;
|
||||
mod panel;
|
||||
mod results;
|
||||
|
||||
@@ -28,6 +29,10 @@ const SCRIPT: &[Step] = &[
|
||||
Step::UpAt("gen-ab", 181.0, 147.0),
|
||||
Step::Wait(300),
|
||||
Step::Shot("verdict"),
|
||||
Step::DownAt("gen-canvas", 300.0, 70.0),
|
||||
Step::UpAt("gen-canvas", 390.0, 220.0),
|
||||
Step::Wait(300),
|
||||
Step::Shot("masked"),
|
||||
];
|
||||
|
||||
fn render(window: &mut Window, cx: &mut App) -> AnyElement {
|
||||
@@ -36,5 +41,6 @@ fn render(window: &mut Window, cx: &mut App) -> AnyElement {
|
||||
.child(results::queue(window, cx))
|
||||
.child(results::results(window, cx))
|
||||
.child(results::variations(window, cx))
|
||||
.child(canvas::canvas(window, cx))
|
||||
.into_any_element()
|
||||
}
|
||||
Reference in new issue
Block a user