1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-29 23:22:55 +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.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
/// </summary>
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()
{
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);
}
}
/// <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()
{
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;