mirror of
https://github.com/emilk/egui.git
synced 2026-06-26 14:49:06 -04:00
Fix: ScrollArea layout jitter with floating bars and zoom levels (#7944)
Fix: ScrollArea layout jitter with floating bars and zoom levels * Closes #7937 * Closes #7942 This PR improves the stability of `ScrollArea` by addressing two layout issues: 1. **Discrete Layout for Floating Bars:** Fixed content "shaking" in `floating` mode when a non-zero `allocated_width` is used. By using discrete visibility (`show_bars`) instead of the animated factor for space allocation, we ensure the layout remains stable during scrollbar animations. 2. **Zoom-level Stability:** Introduced a small epsilon (0.1) when checking if content exceeds the viewport. This prevents scrollbars from flickering on and off due to floating-point rounding errors at specific zoom factors (e.g., 1.01 or 0.95).
This commit is contained in:
@@ -753,7 +753,12 @@ impl ScrollArea {
|
||||
ctx.animate_bool_responsive(id.with("v"), show_bars[1]),
|
||||
);
|
||||
|
||||
let current_bar_use = show_bars_factor.yx() * ui.spacing().scroll.allocated_width();
|
||||
let scroll_style = ui.spacing().scroll;
|
||||
let current_bar_use = if scroll_style.floating {
|
||||
show_bars.to_vec2().yx() * scroll_style.allocated_width()
|
||||
} else {
|
||||
show_bars_factor.yx() * scroll_style.allocated_width()
|
||||
};
|
||||
|
||||
let available_outer = ui.available_rect_before_wrap();
|
||||
|
||||
@@ -1187,9 +1192,15 @@ impl Prepared {
|
||||
|
||||
let outer_rect = Rect::from_min_size(inner_rect.min, inner_rect.size() + current_bar_use);
|
||||
|
||||
let limit_rect = if ui.spacing().scroll.floating {
|
||||
outer_rect
|
||||
} else {
|
||||
inner_rect
|
||||
};
|
||||
|
||||
let content_is_too_large = Vec2b::new(
|
||||
direction_enabled[0] && inner_rect.width() < content_size.x,
|
||||
direction_enabled[1] && inner_rect.height() < content_size.y,
|
||||
direction_enabled[0] && (limit_rect.width().ceil() < content_size.x),
|
||||
direction_enabled[1] && (limit_rect.height().ceil() < content_size.y),
|
||||
);
|
||||
|
||||
let max_offset = content_size - inner_rect.size();
|
||||
|
||||
Reference in New Issue
Block a user