Bevy version
v0.15
[Optional] Relevant system information
2025-01-03T20:16:22.418810Z INFO bevy_diagnostic::system_information_diagnostics_plugin::internal: SystemInfo { os: "Linux 24.11 NixOS", kernel: "6.6.63", cpu: "Intel(R) Core(TM) i7-14700KF", core_count: "20", memory: "31.2 GiB" }
2025-01-03T20:16:22.566379Z INFO bevy_render::renderer: AdapterInfo { name: "NVIDIA GeForce RTX 4060 Ti", vendor: 4318, device: 10243, device_type: DiscreteGpu, driver: "NVIDIA", driver_info: "560.35.03", backend: Vulkan }
What you did
Created a Node with flex_direction set to RowReverse or ColumnReverse and scrolling enabled, updated the value of the offset in ScrollPosition.
What went wrong
Offsets of ScrollPosition are clamped to 0, 0 as if already scrolled to the end, when trying to scroll either way.
Additional information
use bevy::{
app::{App, Startup, Update},
color::{palettes, Color},
prelude::{
BuildChildren, Camera2d, ChildBuild, ChildBuilder, Commands, Component, Local, Query, Text,
With, Without,
},
text::TextColor,
ui::{BackgroundColor, FlexDirection, Node, Overflow, ScrollPosition, Val},
DefaultPlugins,
};
#[derive(Component)]
struct Row;
#[derive(Component)]
struct Column;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, (scroll_x, scroll_y))
.run();
}
fn setup(mut commands: Commands) {
commands.spawn(Camera2d);
let colors: &[Color] = &[
palettes::tailwind::BLUE_100.into(),
palettes::tailwind::GREEN_100.into(),
];
let row_spawner = |parent: &mut ChildBuilder, flex_direction, max_width| {
parent
.spawn((
Row,
Node {
max_width,
flex_direction,
overflow: Overflow::scroll_x(),
..Default::default()
},
))
.with_children(|parent| {
for i in 0..50 {
parent
.spawn((
Node {
min_width: Val::Px(50.),
min_height: Val::Px(50.),
justify_content: bevy::ui::JustifyContent::SpaceEvenly,
align_content: bevy::ui::AlignContent::SpaceEvenly,
..Default::default()
},
BackgroundColor(colors[i % 2]),
))
.with_child((Text::new(i.to_string()), TextColor(Color::BLACK)));
}
});
};
let col_spawner = |parent: &mut ChildBuilder, flex_direction, max_height| {
parent
.spawn((
Column,
Node {
max_height,
flex_direction,
overflow: Overflow::scroll_y(),
..Default::default()
},
))
.with_children(|parent| {
for i in 0..50 {
parent
.spawn((
Node {
min_width: Val::Px(50.),
min_height: Val::Px(50.),
justify_content: bevy::ui::JustifyContent::SpaceEvenly,
align_content: bevy::ui::AlignContent::SpaceEvenly,
..Default::default()
},
BackgroundColor(colors[i % 2]),
))
.with_child((Text::new(i.to_string()), TextColor(Color::BLACK)));
}
});
};
commands
.spawn(Node {
flex_direction: FlexDirection::Column,
..Default::default()
})
.with_children(|parent| {
row_spawner(parent, FlexDirection::Row, Val::Vw(50.));
row_spawner(parent, FlexDirection::RowReverse, Val::Vw(50.));
parent.spawn(Node::default()).with_children(|parent| {
col_spawner(parent, FlexDirection::Column, Val::Vh(50.));
col_spawner(parent, FlexDirection::ColumnReverse, Val::Vh(50.));
});
});
}
fn scroll_x(
mut rows: Query<&mut ScrollPosition, (With<Row>, Without<Column>)>,
mut local: Local<u64>,
) {
let f: fn(&mut f32) = if *local & 0x100 != 0 {
|x| *x -= 2.
} else {
|x| *x += 2.
};
for mut row in rows.iter_mut() {
f(&mut row.offset_x);
}
*local += 1;
}
fn scroll_y(
mut columns: Query<&mut ScrollPosition, (With<Column>, Without<Row>)>,
mut local: Local<u64>,
) {
let f: fn(&mut f32) = if *local & 0x100 != 0 {
|x| *x -= 2.
} else {
|x| *x += 2.
};
for mut column in columns.iter_mut() {
f(&mut column.offset_y);
}
*local += 1;
}
Bevy version
v0.15
[Optional] Relevant system information
What you did
Created a
Nodewithflex_directionset toRowReverseorColumnReverseand scrolling enabled, updated the value of the offset inScrollPosition.What went wrong
Offsets of
ScrollPositionare clamped to0, 0as if already scrolled to the end, when trying to scroll either way.Additional information