1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-06 20:22:56 +08:00

Add curvature to new carousel implementation

This commit is contained in:
Dean Herbert 2025-01-15 20:02:46 +09:00
parent a8456ce9ac
commit a1c5fad6d4
No known key found for this signature in database

View File

@ -13,7 +13,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Pooling; using osu.Framework.Graphics.Pooling;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Bindings; using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Framework.Logging; using osu.Framework.Logging;
@ -21,7 +20,6 @@ using osu.Framework.Utils;
using osu.Game.Graphics.Containers; using osu.Game.Graphics.Containers;
using osu.Game.Input.Bindings; using osu.Game.Input.Bindings;
using osuTK; using osuTK;
using osuTK.Graphics;
using osuTK.Input; using osuTK.Input;
namespace osu.Game.Screens.SelectV2 namespace osu.Game.Screens.SelectV2
@ -117,18 +115,10 @@ namespace osu.Game.Screens.SelectV2
protected Carousel() protected Carousel()
{ {
InternalChildren = new Drawable[] InternalChild = scroll = new CarouselScrollContainer
{ {
new Box RelativeSizeAxes = Axes.Both,
{ Masking = false,
Colour = Color4.Black,
RelativeSizeAxes = Axes.Both,
},
scroll = new CarouselScrollContainer
{
RelativeSizeAxes = Axes.Both,
Masking = false,
}
}; };
Items.BindCollectionChanged((_, _) => FilterAsync()); Items.BindCollectionChanged((_, _) => FilterAsync());
@ -283,6 +273,11 @@ namespace osu.Game.Screens.SelectV2
/// </summary> /// </summary>
private float visibleUpperBound => (float)(scroll.Current - BleedTop); private float visibleUpperBound => (float)(scroll.Current - BleedTop);
/// <summary>
/// Half the height of the visible content.
/// </summary>
private float visibleHalfHeight => (DrawHeight + BleedBottom + BleedTop) / 2;
protected override void Update() protected override void Update()
{ {
base.Update(); base.Update();
@ -302,13 +297,39 @@ namespace osu.Game.Screens.SelectV2
foreach (var panel in scroll.Panels) foreach (var panel in scroll.Panels)
{ {
var carouselPanel = (ICarouselPanel)panel; var c = (ICarouselPanel)panel;
if (panel.Depth != carouselPanel.DrawYPosition) if (panel.Depth != c.DrawYPosition)
scroll.Panels.ChangeChildDepth(panel, (float)carouselPanel.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);
} }
} }
/// <summary>
/// Computes the x-offset of currently visible items. Makes the carousel appear round.
/// </summary>
/// <param name="dist">
/// Vertical distance from the center of the carousel container
/// ranging from -1 to 1.
/// </param>
/// <param name="halfHeight">Half the height of the carousel container.</param>
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() private DisplayRange getDisplayRange()
{ {
Debug.Assert(displayedCarouselItems != null); 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) public override void Clear(bool disposeChildren)
{ {
Panels.Height = 0; Panels.Height = 0;