Open JMS55 opened 15 hours ago
I only included drop shadow support as I wanted to keep the initial PR really simple but inset shadows should be really easy to add. If there's anyone looking for an idea for a simple side project, a 3rd party inset shadow crate shouldn't take much effort. I might make one myself if I run out of bevy PR ideas.
The plugin just draws blurred rects from a list so we have support for per-side and multiple box shadows already, sort of. That requires users to write their own component and extraction function though, which isn't great.
UI clipping only supports right angled, axis-aligned rectangles. It doesn't consider border radius at all, I guess we need some of compositing to implement it properly?
Another missing feature for shadows we need is elliptical border radius support. The box shadow plugin only supports uniform scaling of node's shadows because inon-uniform scaling would require eliptical border radius support to draw distorted curved borders.
Something like this maybe:
#[derive(Component, Default, Clone, Debug, Reflect)]
#[reflect(Component, Default)]
#[cfg_attr(
feature = "serialize",
derive(serde::Serialize, serde::Deserialize),
reflect(Serialize, Deserialize)
)]
pub struct BoxShadow {
/// Shadows drawn according to their order in the vector, from back to front
shadows: Vec<ShadowStyle>,
}
// #[derive(Component, Copy, Clone, Debug, Default, PartialEq, Eq, Reflect)]
// #[reflect(Component, Default, Debug, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq, Reflect)]
pub enum ShadowStyle {
/// Shadow drawn beneath a UI node.
/// Position and size relative to the corresponding UI node.
Drop {
/// The shadow's color
color: Color,
/// Horizontal offset
x_offset: Val,
/// Vertical offset
y_offset: Val,
/// How much the shadow should spread outward.
///
/// Negative values will make the shadow shrink inwards.
/// Percentage values are based on the width of the UI node.
spread_radius: Val,
/// Blurriness of the shadow
blur_radius: Val,
},
/// Shadow drawn beneath its corresponding UI node.
/// Position is relative to its `Node` but with independent size and radius.
DropFree {
/// The shadow's color
color: Color,
/// Horizontal offset
x_offset: Val,
/// Vertical offset
y_offset: Val,
/// Shadow width,
width: Val,
/// Shadow height
height: Val,
/// radius of the corners
radius: BorderRadius,
/// Blurriness of the shadow
blur_radius: Val,
},
/// Inner shadow drawn on top of the node and inside the node's padding box, starting at the border-padding edge.
Inset {
/// Horizontal offset.
/// Negative values move the shadow to the left, positive to the right.
x_offset: Val,
/// Vertical offset.
/// Negative values move the shadow to the left, positive to the right.
y_offset: Val,
/// Controls the size of the shadow. Positive values increase the size of the shadow,
/// covering more of the padding box.
spread_radius: Val,
/// Blurriness of the shadow
blur_radius: Val,
},
}
impl Default for ShadowStyle {
fn default() -> Self {
Self::Drop {
color: Color::BLACK,
x_offset: Val::Percent(20.),
y_offset: Val::Percent(20.),
spread_radius: Val::ZERO,
blur_radius: Val::Percent(10.),
}
}
}
DropFree
very much. Alternatives I can think of like DropAbsolute
, Absolute
, DropIndependent
, CustomDrop
, don't seem much better though.Drop
variant with a ShadowSize
enum with SpreadRadius
and Independent
/Absolute
variants instead.DropShadow
and InsetShadow
components instead of one BoxShadow
component, each with their own seperate list of shadows.
What problem does this solve or what need does it fill?
Allow us to do things like https://www.tyleo.com/html-glass.html.
What solution would you like?