-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
# Objective Limited implementation of the CSS property `overflow-clip-margin` https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-clip-margin Allows you to control the visible area for clipped content when using overfllow-clip, -hidden, or -scroll and expand it with a margin. Based on #15442 Fixes #15468 ## Solution Adds a new field to Style: `overflow_clip_margin: OverflowClipMargin`. The field is ignored unless overflow-clip, -hidden or -scroll is set on at least one axis. `OverflowClipMargin` has these associated constructor functions: ``` pub const fn content_box() -> Self; pub const fn padding_box() -> Self; pub const fn border_box() -> Self; ``` You can also use the method `with_margin` to increases the size of the visible area: ``` commands .spawn(NodeBundle { style: Style { width: Val::Px(100.), height: Val::Px(100.), padding: UiRect::all(Val::Px(20.)), border: UiRect::all(Val::Px(5.)), overflow: Overflow::clip(), overflow_clip_margin: OverflowClipMargin::border_box().with_margin(25.), ..Default::default() }, border_color: Color::BLACK.into(), background_color: GRAY.into(), ..Default::default() }) ``` `with_margin` expects a length in logical pixels, negative values are clamped to zero. ## Notes * To keep this PR as simple as possible I omitted responsive margin values support. This could be added in a follow up if we want it. * CSS also supports a `margin-box` option but we don't have access to the margin values in `Node` so it's probably not feasible to implement atm. ## Testing ```cargo run --example overflow_clip_margin``` <img width="396" alt="overflow-clip-margin" src="https://github.com/user-attachments/assets/07b51cd6-a565-4451-87a0-fa079429b04b"> ## Migration Guide Style has a new field `OverflowClipMargin`. It allows users to set the visible area for clipped content when using overflow-clip, -hidden, or -scroll and expand it with a margin. There are three associated constructor functions `content_box`, `padding_box` and `border_box`: * `content_box`: elements painted outside of the content box area (the innermost part of the node excluding the padding and border) of the node are clipped. This is the new default behaviour. * `padding_box`: elements painted outside outside of the padding area of the node are clipped. * `border_box`: elements painted outside of the bounds of the node are clipped. This matches the behaviour from Bevy 0.14. There is also a `with_margin` method that increases the size of the visible area by the given number in logical pixels, negative margin values are clamped to zero. `OverflowClipMargin` is ignored unless overflow-clip, -hidden or -scroll is also set on at least one axis of the UI node. --------- Co-authored-by: UkoeHB <37489173+UkoeHB@users.noreply.github.com>
- Loading branch information
Showing
6 changed files
with
216 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
//! Simple example demonstrating the `OverflowClipMargin` style property. | ||
use bevy::{color::palettes::css::*, prelude::*, winit::WinitSettings}; | ||
|
||
fn main() { | ||
App::new() | ||
.add_plugins(DefaultPlugins) | ||
// Only run the app when there is user input. This will significantly reduce CPU/GPU use. | ||
.insert_resource(WinitSettings::desktop_app()) | ||
.add_systems(Startup, setup) | ||
.run(); | ||
} | ||
|
||
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) { | ||
commands.spawn(Camera2d); | ||
|
||
let image = asset_server.load("branding/icon.png"); | ||
|
||
commands | ||
.spawn(NodeBundle { | ||
style: Style { | ||
width: Val::Percent(100.), | ||
height: Val::Percent(100.), | ||
align_items: AlignItems::Center, | ||
justify_content: JustifyContent::Center, | ||
row_gap: Val::Px(40.), | ||
flex_direction: FlexDirection::Column, | ||
..Default::default() | ||
}, | ||
background_color: ANTIQUE_WHITE.into(), | ||
..Default::default() | ||
}) | ||
.with_children(|parent| { | ||
for overflow_clip_margin in [ | ||
OverflowClipMargin::border_box().with_margin(25.), | ||
OverflowClipMargin::border_box(), | ||
OverflowClipMargin::padding_box(), | ||
OverflowClipMargin::content_box(), | ||
] { | ||
parent | ||
.spawn(NodeBundle { | ||
style: Style { | ||
flex_direction: FlexDirection::Row, | ||
column_gap: Val::Px(20.), | ||
..Default::default() | ||
}, | ||
..Default::default() | ||
}) | ||
.with_children(|parent| { | ||
parent | ||
.spawn(NodeBundle { | ||
style: Style { | ||
padding: UiRect::all(Val::Px(10.)), | ||
margin: UiRect::bottom(Val::Px(25.)), | ||
..Default::default() | ||
}, | ||
background_color: Color::srgb(0.25, 0.25, 0.25).into(), | ||
..Default::default() | ||
}) | ||
.with_child(Text(format!("{overflow_clip_margin:#?}"))); | ||
|
||
parent | ||
.spawn(NodeBundle { | ||
style: Style { | ||
margin: UiRect::top(Val::Px(10.)), | ||
width: Val::Px(100.), | ||
height: Val::Px(100.), | ||
padding: UiRect::all(Val::Px(20.)), | ||
border: UiRect::all(Val::Px(5.)), | ||
overflow: Overflow::clip(), | ||
overflow_clip_margin, | ||
..Default::default() | ||
}, | ||
border_color: Color::BLACK.into(), | ||
background_color: GRAY.into(), | ||
..Default::default() | ||
}) | ||
.with_children(|parent| { | ||
parent | ||
.spawn(NodeBundle { | ||
style: Style { | ||
min_width: Val::Px(50.), | ||
min_height: Val::Px(50.), | ||
..Default::default() | ||
}, | ||
background_color: LIGHT_CYAN.into(), | ||
..Default::default() | ||
}) | ||
.with_child(ImageBundle { | ||
image: UiImage::new(image.clone()), | ||
style: Style { | ||
min_width: Val::Px(100.), | ||
min_height: Val::Px(100.), | ||
..Default::default() | ||
}, | ||
..Default::default() | ||
}); | ||
}); | ||
}); | ||
} | ||
}); | ||
} |