diff --git a/crates/egui/src/containers/scroll_area.rs b/crates/egui/src/containers/scroll_area.rs index b99bcf5da..648c83ee6 100644 --- a/crates/egui/src/containers/scroll_area.rs +++ b/crates/egui/src/containers/scroll_area.rs @@ -1006,6 +1006,7 @@ impl ScrollArea { let margin = self .content_margin .unwrap_or_else(|| ui.spacing().scroll.content_margin); + let direction_enabled = self.direction_enabled; let mut prepared = self.begin(ui); let id = prepared.id; @@ -1027,7 +1028,7 @@ impl ScrollArea { inner_rect, }; - paint_fade_areas(ui, &output); + paint_fade_areas(ui, &output, direction_enabled); output } @@ -1509,9 +1510,13 @@ impl Prepared { } } -/// Paint fade-out gradients at the top and/or bottom of a scroll area to +/// Paint fade-out gradients at the edges of a scroll area to /// indicate that more content is available beyond the visible region. -fn paint_fade_areas(ui: &Ui, scroll_output: &ScrollAreaOutput) { +/// +/// Only fades for axes where scrolling is enabled — otherwise stray overflow +/// in a non-scrollable axis would draw a permanent fade with nothing to scroll +/// away to. +fn paint_fade_areas(ui: &Ui, scroll_output: &ScrollAreaOutput, direction_enabled: Vec2b) { let crate::style::ScrollFadeStyle { strength, size: fade_size, @@ -1531,65 +1536,69 @@ fn paint_fade_areas(ui: &Ui, scroll_output: &ScrollAreaOutput) { .intersect(ui.min_rect()) .expand(ui.visuals().clip_rect_margin); - // Top fade: animate opacity based on how far we've scrolled down. - if 0.0 < offset.y { - let t = (offset.y / fade_size).clamp(0.0, 1.0) * strength; - let bg_faded = bg.gamma_multiply(t); - let rect = Rect::from_min_max( - paint_rect.left_top(), - pos2(paint_rect.right(), paint_rect.top() + fade_size), - ); - ui.painter().add(Shape::gradient_rect( - rect, - Direction::TopDown, - [bg_faded, Color32::TRANSPARENT], - )); + if direction_enabled.y { + // Top fade: animate opacity based on how far we've scrolled down. + if 0.0 < offset.y { + let t = (offset.y / fade_size).clamp(0.0, 1.0) * strength; + let bg_faded = bg.gamma_multiply(t); + let rect = Rect::from_min_max( + paint_rect.left_top(), + pos2(paint_rect.right(), paint_rect.top() + fade_size), + ); + ui.painter().add(Shape::gradient_rect( + rect, + Direction::TopDown, + [bg_faded, Color32::TRANSPARENT], + )); + } + + // Bottom fade: animate opacity based on distance from the bottom. + let distance_from_bottom = overflow.y - offset.y; + if 0.0 < distance_from_bottom { + let t = (distance_from_bottom / fade_size).clamp(0.0, 1.0) * strength; + let bg_faded = bg.gamma_multiply(t); + let rect = Rect::from_min_max( + pos2(paint_rect.left(), paint_rect.bottom() - fade_size), + paint_rect.right_bottom(), + ); + ui.painter().add(Shape::gradient_rect( + rect, + Direction::BottomUp, + [bg_faded, Color32::TRANSPARENT], + )); + } } - // Bottom fade: animate opacity based on distance from the bottom. - let distance_from_bottom = overflow.y - offset.y; - if 0.0 < distance_from_bottom { - let t = (distance_from_bottom / fade_size).clamp(0.0, 1.0) * strength; - let bg_faded = bg.gamma_multiply(t); - let rect = Rect::from_min_max( - pos2(paint_rect.left(), paint_rect.bottom() - fade_size), - paint_rect.right_bottom(), - ); - ui.painter().add(Shape::gradient_rect( - rect, - Direction::BottomUp, - [bg_faded, Color32::TRANSPARENT], - )); - } + if direction_enabled.x { + // Left fade: animate opacity based on how far we've scrolled right. + if 0.0 < offset.x { + let t = (offset.x / fade_size).clamp(0.0, 1.0) * strength; + let bg_faded = bg.gamma_multiply(t); + let rect = Rect::from_min_max( + paint_rect.left_top(), + pos2(paint_rect.left() + fade_size, paint_rect.bottom()), + ); + ui.painter().add(Shape::gradient_rect( + rect, + Direction::LeftToRight, + [bg_faded, Color32::TRANSPARENT], + )); + } - // Left fade: animate opacity based on how far we've scrolled right. - if 0.0 < offset.x { - let t = (offset.x / fade_size).clamp(0.0, 1.0) * strength; - let bg_faded = bg.gamma_multiply(t); - let rect = Rect::from_min_max( - paint_rect.left_top(), - pos2(paint_rect.left() + fade_size, paint_rect.bottom()), - ); - ui.painter().add(Shape::gradient_rect( - rect, - Direction::LeftToRight, - [bg_faded, Color32::TRANSPARENT], - )); - } - - // Right fade: animate opacity based on distance from the right edge. - let distance_from_right = overflow.x - offset.x; - if 0.0 < distance_from_right { - let t = (distance_from_right / fade_size).clamp(0.0, 1.0) * strength; - let bg_faded = bg.gamma_multiply(t); - let rect = Rect::from_min_max( - pos2(paint_rect.right() - fade_size, paint_rect.top()), - paint_rect.right_bottom(), - ); - ui.painter().add(Shape::gradient_rect( - rect, - Direction::RightToLeft, - [bg_faded, Color32::TRANSPARENT], - )); + // Right fade: animate opacity based on distance from the right edge. + let distance_from_right = overflow.x - offset.x; + if 0.0 < distance_from_right { + let t = (distance_from_right / fade_size).clamp(0.0, 1.0) * strength; + let bg_faded = bg.gamma_multiply(t); + let rect = Rect::from_min_max( + pos2(paint_rect.right() - fade_size, paint_rect.top()), + paint_rect.right_bottom(), + ); + ui.painter().add(Shape::gradient_rect( + rect, + Direction::RightToLeft, + [bg_faded, Color32::TRANSPARENT], + )); + } } }