From a1c5fad6d45c24318028c9f00b0750ad2fb77b88 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 15 Jan 2025 20:02:46 +0900 Subject: [PATCH] Add curvature to new carousel implementation --- osu.Game/Screens/SelectV2/Carousel.cs | 67 +++++++++++++++------------ 1 file changed, 37 insertions(+), 30 deletions(-) diff --git a/osu.Game/Screens/SelectV2/Carousel.cs b/osu.Game/Screens/SelectV2/Carousel.cs index c8a54d4cd5..a19c86d90b 100644 --- a/osu.Game/Screens/SelectV2/Carousel.cs +++ b/osu.Game/Screens/SelectV2/Carousel.cs @@ -13,7 +13,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Pooling; -using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; using osu.Framework.Logging; @@ -21,7 +20,6 @@ using osu.Framework.Utils; using osu.Game.Graphics.Containers; using osu.Game.Input.Bindings; using osuTK; -using osuTK.Graphics; using osuTK.Input; namespace osu.Game.Screens.SelectV2 @@ -117,18 +115,10 @@ namespace osu.Game.Screens.SelectV2 protected Carousel() { - InternalChildren = new Drawable[] + InternalChild = scroll = new CarouselScrollContainer { - new Box - { - Colour = Color4.Black, - RelativeSizeAxes = Axes.Both, - }, - scroll = new CarouselScrollContainer - { - RelativeSizeAxes = Axes.Both, - Masking = false, - } + RelativeSizeAxes = Axes.Both, + Masking = false, }; Items.BindCollectionChanged((_, _) => FilterAsync()); @@ -283,6 +273,11 @@ namespace osu.Game.Screens.SelectV2 /// private float visibleUpperBound => (float)(scroll.Current - BleedTop); + /// + /// Half the height of the visible content. + /// + private float visibleHalfHeight => (DrawHeight + BleedBottom + BleedTop) / 2; + protected override void Update() { base.Update(); @@ -302,13 +297,39 @@ namespace osu.Game.Screens.SelectV2 foreach (var panel in scroll.Panels) { - var carouselPanel = (ICarouselPanel)panel; + var c = (ICarouselPanel)panel; - if (panel.Depth != carouselPanel.DrawYPosition) - scroll.Panels.ChangeChildDepth(panel, (float)carouselPanel.DrawYPosition); + if (panel.Depth != c.DrawYPosition) + scroll.Panels.ChangeChildDepth(panel, (float)c.DrawYPosition); + + Debug.Assert(c.Item != null); + + if (c.DrawYPosition != c.Item.CarouselYPosition) + c.DrawYPosition = Interpolation.DampContinuously(c.DrawYPosition, c.Item.CarouselYPosition, 50, Time.Elapsed); + + Vector2 posInScroll = scroll.ToLocalSpace(panel.ScreenSpaceDrawQuad.Centre); + float dist = Math.Abs(1f - posInScroll.Y / visibleHalfHeight); + + panel.X = offsetX(dist, visibleHalfHeight); } } + /// + /// Computes the x-offset of currently visible items. Makes the carousel appear round. + /// + /// + /// Vertical distance from the center of the carousel container + /// ranging from -1 to 1. + /// + /// Half the height of the carousel container. + private static float offsetX(float dist, float halfHeight) + { + // The radius of the circle the carousel moves on. + const float circle_radius = 3; + float discriminant = MathF.Max(0, circle_radius * circle_radius - dist * dist); + return (circle_radius - MathF.Sqrt(discriminant)) * halfHeight; + } + private DisplayRange getDisplayRange() { Debug.Assert(displayedCarouselItems != null); @@ -425,20 +446,6 @@ namespace osu.Game.Screens.SelectV2 } } - protected override void Update() - { - base.Update(); - - foreach (var panel in Panels) - { - var c = (ICarouselPanel)panel; - Debug.Assert(c.Item != null); - - if (c.DrawYPosition != c.Item.CarouselYPosition) - c.DrawYPosition = Interpolation.DampContinuously(c.DrawYPosition, c.Item.CarouselYPosition, 50, Time.Elapsed); - } - } - public override void Clear(bool disposeChildren) { Panels.Height = 0;