💄 CarouselBanner

This commit is contained in:
RMBGAME
2023-06-03 05:41:44 +08:00
parent 33ca8475dd
commit 4e55e8b150
5 changed files with 281 additions and 20 deletions
@@ -0,0 +1,69 @@
<UserControl
x:Class="BD.WTTS.UI.Views.Controls.CarouselBanner"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:spp="https://steampp.net/ui"
xmlns:ui="using:FluentAvalonia.UI.Controls"
d:DesignHeight="200"
d:DesignWidth="800"
mc:Ignorable="d">
<UserControl.Styles>
<Style Selector="Button">
<Setter Property="Margin" Value="4" />
<Setter Property="Padding" Value="5,10" />
<Setter Property="VerticalAlignment" Value="Center" />
</Style>
</UserControl.Styles>
<Panel>
<Carousel Name="Carousel" Grid.Column="1">
<Carousel.PageTransition>
<PageSlide Orientation="Horizontal" Duration="0.25" />
</Carousel.PageTransition>
</Carousel>
<Button
Name="Left"
HorizontalAlignment="Left"
IsVisible="False"
Theme="{StaticResource TransparentButton}">
<ui:SymbolIcon FontSize="20" Symbol="ChevronLeft" />
</Button>
<Button
Name="Right"
HorizontalAlignment="Right"
IsVisible="False"
Theme="{StaticResource TransparentButton}">
<ui:SymbolIcon FontSize="20" Symbol="ChevronRight" />
</Button>
<Panel
Height="10"
Margin="0,0,0,5"
HorizontalAlignment="Center"
VerticalAlignment="Bottom">
<ItemsRepeater Name="Swiper" IsVisible="False">
<ItemsRepeater.Layout>
<StackLayout
DisableVirtualization="True"
Orientation="Horizontal"
Spacing="8" />
</ItemsRepeater.Layout>
<ItemsRepeater.ItemTemplate>
<DataTemplate>
<Panel>
<Ellipse
Width="10"
Height="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="{Binding}"
Opacity="0.6"
StrokeThickness="0" />
</Panel>
</DataTemplate>
</ItemsRepeater.ItemTemplate>
</ItemsRepeater>
</Panel>
</Panel>
</UserControl>
@@ -0,0 +1,159 @@
using FluentAvalonia.Core;
namespace BD.WTTS.UI.Views.Controls
{
public partial class CarouselBanner : UserControl
{
/// <summary>
/// Defines the <see cref="AutoScroll"/> property.
/// </summary>
public static readonly StyledProperty<bool> AutoScrollProperty =
AvaloniaProperty.Register<CarouselBanner, bool>(nameof(AutoScroll), true);
/// <summary>
/// Defines the <see cref="AutoScrollInterval"/> property.
/// </summary>
public static readonly StyledProperty<int> AutoScrollIntervalProperty =
AvaloniaProperty.Register<CarouselBanner, int>(nameof(AutoScrollInterval), 8000);
/// <summary>
/// Defines the Avalonia.Controls.ItemsControl.Items property.
/// </summary>
public static readonly StyledProperty<IEnumerable?> ItemsSourceProperty =
Carousel.ItemsSourceProperty.AddOwner<CarouselBanner>();
/// <summary>
/// Defines the Avalonia.Controls.ItemsControl.ItemTemplate property.
/// </summary>
public static readonly StyledProperty<IDataTemplate?> ItemTemplateProperty =
Carousel.ItemTemplateProperty.AddOwner<CarouselBanner>();
/// <summary>
/// Gets or sets the items to display.
/// </summary>
public IEnumerable? ItemsSource
{
get => GetValue(ItemsSourceProperty);
set => SetValue(ItemsSourceProperty, value);
}
/// <summary>
/// Gets or sets the data template used to display the items in the control.
/// </summary>
public IDataTemplate? ItemTemplate
{
get => GetValue(ItemTemplateProperty);
set => SetValue(ItemTemplateProperty, value);
}
/// <summary>
/// AutoScroll
/// </summary>
public bool AutoScroll
{
get => GetValue(AutoScrollProperty);
set => SetValue(AutoScrollProperty, value);
}
/// <summary>
/// 自动播放间隔时间(单位毫秒)
/// </summary>
public int AutoScrollInterval
{
get => GetValue(AutoScrollIntervalProperty);
set => SetValue(AutoScrollIntervalProperty, value);
}
private Timer? _timer;
public CarouselBanner()
{
InitializeComponent();
Left.Click += (s, e) => SwiperPrevious();
Right.Click += (s, e) => SwiperNext();
Carousel[!Carousel.ItemsSourceProperty] = this[!ItemsSourceProperty];
Carousel[!Carousel.ItemTemplateProperty] = this[!ItemTemplateProperty];
Carousel.GetObservable(Carousel.ItemsSourceProperty)
.Subscribe(_ => SwipersLoad());
Carousel.GetObservable(Carousel.SelectedIndexProperty)
.Subscribe(x => SwipersLoad());
this.GetObservable(AutoScrollProperty)
.Subscribe(x =>
{
if (x && _timer == null)
{
_timer = new Timer(_ =>
{
if (!this.IsPointerOver)
{
Dispatcher.UIThread.Post(SwiperNext, DispatcherPriority.Background);
}
}, nameof(AutoScroll), AutoScrollInterval, AutoScrollInterval);
}
else
{
if (_timer != null)
{
_timer.Dispose();
_timer = null;
}
}
});
}
private void SwipersLoad()
{
if (Carousel.ItemCount <= 0)
return;
if (Carousel.ItemCount == 1)
{
Left.IsVisible = Right.IsVisible = Swiper.IsVisible = false;
return;
}
else
{
Left.IsVisible = Right.IsVisible = Swiper.IsVisible = true;
var arr = new string[Carousel.ItemCount];
for (var i = 0; i < arr.Length; i++)
{
arr[i] = "#ADADAD";
}
var index = Carousel.SelectedIndex < 0 ? 0 : Carousel.SelectedIndex;
arr[index] = "#FFFFFF";
Swiper.ItemsSource = arr;
}
}
private void SwiperNext()
{
if (Carousel.ItemCount < 1)
return;
if (Carousel.SelectedIndex < Carousel.ItemCount - 1)
{
Carousel.Next();
}
else
{
Carousel.SelectedIndex = 0;
}
}
private void SwiperPrevious()
{
if (Carousel.ItemCount < 1)
return;
if (Carousel.SelectedIndex > 0)
{
Carousel.Previous();
}
else
{
Carousel.SelectedIndex = Carousel.ItemCount - 1;
}
}
}
}
@@ -8,10 +8,34 @@
xmlns:ui="using:FluentAvalonia.UI.Controls"
d:DesignHeight="450"
d:DesignWidth="800"
x:CompileBindings="True"
x:DataType="spp:HomePageViewModel"
mc:Ignorable="d">
<Panel>
<spp:ContentLoader IsLoading="True">
<spp:Image2 RenderOptions.BitmapInterpolationMode="HighQuality" Source="https://media.st.dl.eccdnx.com/steamcommunity/public/images/items/1629910/045c57ebb6946fdf7e57a53d5768117dd8543862.gif" />
</spp:ContentLoader>
</Panel>
<spp:ContentLoader IsLoading="True">
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,*">
<spp:CarouselBanner
Width="616"
Height="353"
VerticalAlignment="Top"
ItemsSource="{Binding Navigations}">
<spp:CarouselBanner.ItemTemplate>
<DataTemplate DataType="x:String">
<spp:RippleEffect>
<Border ToolTip.Tip="{Binding}">
<spp:Image2 Source="{Binding}" Stretch="UniformToFill" />
</Border>
</spp:RippleEffect>
</DataTemplate>
</spp:CarouselBanner.ItemTemplate>
</spp:CarouselBanner>
<StackPanel
Grid.Row="1"
Grid.ColumnSpan="2"
Margin="10"
Spacing="10">
<spp:Image2 RenderOptions.BitmapInterpolationMode="HighQuality" Source="https://media.st.dl.eccdnx.com/steamcommunity/public/images/items/1629910/045c57ebb6946fdf7e57a53d5768117dd8543862.gif" />
</StackPanel>
</Grid>
</spp:ContentLoader>
</UserControl>
@@ -1,15 +1,14 @@
<UserControl
x:Class="BD.WTTS.UI.Views.Pages.AcceleratorPage"
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:spp="https://steampp.net/ui"
xmlns:ui="using:FluentAvalonia.UI.Controls"
d:DesignHeight="450"
d:DesignWidth="800"
x:CompileBindings="True"
x:DataType="spp:AcceleratorPageViewModel"
mc:Ignorable="d">
<Grid />
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:spp="https://steampp.net/ui"
xmlns:ui="using:FluentAvalonia.UI.Controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:CompileBindings="True"
x:DataType="spp:AcceleratorPageViewModel"
x:Class="BD.WTTS.UI.Views.Pages.AcceleratorPage">
<Grid>
</Grid>
</UserControl>
@@ -6,8 +6,18 @@ public sealed class HomePageViewModel : TabItemViewModel
{
public override string Name => Strings.Welcome;
[Reactive]
public ObservableCollection<string> Navigations { get; set; }
public HomePageViewModel()
{
Navigations = new ObservableCollection<string>()
{
"https://media.st.dl.eccdnx.com/steam/apps/2239550/capsule_616x353.jpg?t=1674755684",
"https://media.st.dl.eccdnx.com/steam/apps/1938090/capsule_616x353_alt_assets_3_schinese.jpg?t=1684446457",
"https://media.st.dl.eccdnx.com/steam/apps/1868180/capsule_616x353_schinese.jpg?t=1685635527",
"https://media.st.dl.eccdnx.com/steam/apps/271590/capsule_616x353.jpg?t=1678296348",
"https://media.st.dl.eccdnx.com/steam/apps/1865680/capsule_616x353_schinese.jpg?t=1643602186",
};
}
}