Effects · Decoration
Cross-hatch
Cross-hatching whose density follows the photograph's tone, the way an engraver carries shade — ink laid down or not, never half.
Starts when it scrolls into view
NORD FROST · DARK · RADIUS 6/10 · BASE 16PX · SHADOW
Code
Cut from the gallery’s own decorations, so it is the code that drew the frame above rather than a description of it.
fn processed(treatment: Treatment, cx: &App) -> impl IntoElement {
let ground = Rgba::from(cx.theme().background);
let ink = Rgba::from(cx.theme().primary);
let key = (treatment, packed(ground), packed(ink));
let image = LAST.with(|last| {
let mut last = last.borrow_mut();
if let Some((cached_treatment, cached_ground, cached_ink, image)) = last.as_ref()
&& (*cached_treatment, *cached_ground, *cached_ink) == key
{
return Arc::clone(image);
}
let built = rasterise(
treatment,
ground,
ink,
f32::from(decoration::frame_radius(cx)),
);
*last = Some((key.0, key.1, key.2, Arc::clone(&built)));
built
});
// Exact size, no fit: the picture was rasterised for this box with the
// frame's shape already in its alpha, so nothing has to clip it.
under_content(img(image).absolute().inset_0(), cx)
}
Applying it
Every framed component takes a Decoration, and the layer decides for itself whether it belongs to the shape — either by carrying the frame’s radius, or by not reaching a corner. The two rules are the whole contract.
crates/gallery/src/decorations.rs
let card = ApprovalCard::new("decorated-gate", "Publish the launch plan?")
.description(
"The card is unchanged. Everything behind and in front of it \
is the application's.",
)
.decoration(kind.build(cx))