zoukankan      html  css  js  c++  java
  • WPF 图片轮播效果(2D轮转)

    <UserControl x:Class="CustomControl.Carousel2DView"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:CustomControl"
                 mc:Ignorable="d" Width="800" Height="200" x:Name="CarouselBanner">
        <Grid x:Name="GdRoot" Width="800" Height="200">
            <Canvas x:Name="CvMain">
            </Canvas>
        </Grid>
    </UserControl>
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Windows.Threading;
    
    namespace CustomControl
    {
        /// <summary>
        /// Carousel2DView.xaml 的交互逻辑
        /// </summary>
        public partial class Carousel2DView : UserControl,INotifyPropertyChanged
        {
            public List<string> FileItems;
            int clickIndex = 0;
            DispatcherTimer timer;
            int timeInterval = 4; 
    
            public Carousel2DView()
            {
                InitializeComponent();
    
                string sPath = AppDomain.CurrentDomain.BaseDirectory + "Resources/Banner";
                if (!Directory.Exists(sPath))
                    Directory.CreateDirectory(sPath);
    
                List<string> ltFiles = FolderHelper.GetAllFileFullName(sPath);
    
                this.FileItems = ltFiles;
    
                this.Loaded += Carousel2DView_Loaded;
                this.Unloaded += Carousel2DView_Unloaded;
    
                this.DataContext = this;
    
            }
    
            private void Carousel2DView_Unloaded(object sender, RoutedEventArgs e)
            {
                this.Unloaded -= Carousel2DView_Unloaded;
            }
    
            private void Carousel2DView_Loaded(object sender, RoutedEventArgs e)
            {
                this.Loaded -= Carousel2DView_Loaded;
    
                this.CreateElements();
    
                this.GdRoot.MouseLeftButtonDown += GdRoot_MouseLeftButtonDown;
                this.MouseMove += Carousel2DView_MouseMove;
                this.MouseUp += Carousel2DView_MouseUp;
    
                timer = new DispatcherTimer();
                timer.Interval = TimeSpan.FromSeconds(timeInterval);
                timer.Tick += new EventHandler(RefreshLocation);
                timer.Start();
            }
    
    
            public void ReStartTimer()
            {
                if (timer == null)
                {
                    timer = new DispatcherTimer();
                    timer.Interval = TimeSpan.FromSeconds(timeInterval);
                    timer.Tick += new EventHandler(RefreshLocation);
                    timer.Start();
                }
                else {
                    timer.Stop();
                    timer.Tick -= RefreshLocation;
    
                    timer = new DispatcherTimer();
                    timer.Interval = TimeSpan.FromSeconds(timeInterval);
                    timer.Tick += new EventHandler(RefreshLocation);
                    timer.Start();
                }
            }
    
            private void RefreshLocation(object sender, EventArgs e)
            {
                this.Dispatcher.Invoke(new Action(() =>
                {
                    if (clickIndex < this.ElementList.Count)
                    {
                        this.IsMouseDown = true;
                        this.CurNavItem = ElementList[clickIndex];
                        if (this.IsMouseDown && this.TotalMoveDegree < 50)
                        {
                            this.InertiaDegree = CenterDegree - this.CurNavItem.Degree;
                            this.CurNavItem = null;
                            this.IsMouseDown = false;
                            if (this.InertiaDegree != 0)
                                CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
                            clickIndex++;
                        }
                    }
                    else
                    {
                        clickIndex = 0;
                    }
    
                }));
            }
    
    
            #region Create Elements
    
            private double VisualCount = 10d;
            private List<ImageItem> ElementList;
            private double CenterDegree = 180d;
            private double TotalDegree = 0;
    
            public double GridWidth
            {
                get { return (double)GetValue(GridWidthProperty); }
                set { SetValue(GridWidthProperty, value); }
            }
    
            public static readonly DependencyProperty GridWidthProperty =
                  DependencyProperty.Register("GridWidth", typeof(double), typeof(Carousel2DView));
    
            public double GridHeight
            {
                get { return (double)GetValue(GridHeightProperty); }
                set { SetValue(GridHeightProperty, value); }
            }
    
            public static readonly DependencyProperty GridHeightProperty =
                  DependencyProperty.Register("GridHeight", typeof(double), typeof(Carousel2DView));
    
    
            public double ElementWidth
            {
                get { return (double)GetValue(ElementWidthProperty); }
                set { SetValue(ElementWidthProperty, value); }
            }
    
            public static readonly DependencyProperty ElementWidthProperty =
                  DependencyProperty.Register("ElementWidth", typeof(double), typeof(Carousel2DView));
    
            public double ElementHeight
            {
                get { return (double)GetValue(ElementHeightProperty); }
                set { SetValue(ElementHeightProperty, value); }
            }
    
            public static readonly DependencyProperty ElementHeightProperty =
                  DependencyProperty.Register("ElementHeight", typeof(double), typeof(Carousel2DView));
    
            public double Radius
            {
                get { return (double)GetValue(RadiusProperty); }
                set { SetValue(RadiusProperty, value); }
            }
    
            public static readonly DependencyProperty RadiusProperty =
                  DependencyProperty.Register("Radius", typeof(double), typeof(Carousel2DView));
    
            
    
            #region INotifyPropertyChanged
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            public void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    
            #endregion
    
            private double GetScaledSize(double degrees)
            {
                return GetCoefficient(degrees);
            }
    
            private double GetCoefficient(double degrees)
            {
                return 1.0 - Math.Cos(ConvertToRads(degrees)) / 2.0 - 0.5;
            }
    
            private double ConvertToRads(double degrees)
            {
                return degrees * Math.PI / 180.0;
            }
    
            private int GetZValue(double degrees)
            {
                return (int)((360 * GetCoefficient(degrees)) * 1000);
            }
    
            public void CreateElements()
            {
                double dAverageDegree = 360d / VisualCount;
                this.TotalDegree = this.FileItems.Count * dAverageDegree;
    
                this.ElementList = new List<ImageItem>();
                for (int i = 0; i < this.FileItems.Count; i++)
                {
                    string sFile = this.FileItems[i];
                    ImageItem oItem = new ImageItem(sFile);
                    oItem.MouseLeftButtonDown += OItem_MouseLeftButtonDown;
                    oItem.MouseLeftButtonUp += OItem_MouseLeftButtonUp;
                    oItem.Width = this.ElementWidth;
                    oItem.Height = this.ElementHeight;
                    oItem.Y = 0d;
                    oItem.Degree = i * dAverageDegree;
                    this.ElementList.Add(oItem);
                }
    
                this.UpdateLocation();
    
    
                //this.IsMouseDown = false;
                //this.CurNavItem = null;
                double dIntervalDegree = this.InertiaDegree * 0.4;
                for (int i = 0; i < this.ElementList.Count; i++)
                {
                    ImageItem oItem = this.ElementList[i];
                    oItem.Degree += dIntervalDegree;
                }
                this.UpdateLocation();
                //this.InertiaDegree -= dIntervalDegree;
    
            }
    
            private ImageItem CurNavItem;
    
            private void OItem_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
            {
    
                timer.Stop();
                timer.Tick -= RefreshLocation;
    
                if (this.IsMouseDown && CurNavItem == sender && this.TotalMoveDegree < 50)
                {
                    this.InertiaDegree = CenterDegree - this.CurNavItem.Degree;
                    this.CurNavItem = null;
                    this.IsMouseDown = false;
                    if (this.InertiaDegree != 0)
                        CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
                    e.Handled = true;
                }
            }
    
            private void OItem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                CurNavItem = sender as ImageItem;
            }
    
            private void UpdateLocation()
            {
                for (int i = 0; i < this.ElementList.Count; i++)
                {
                    ImageItem oItem = this.ElementList[i];
    
                    if (oItem.Degree - this.CenterDegree >= this.TotalDegree / 2d)
                        oItem.Degree -= this.TotalDegree;
                    else if (this.CenterDegree - oItem.Degree > this.TotalDegree / 2d)
                        oItem.Degree += this.TotalDegree;
    
                    if (oItem.Degree >= 90d && oItem.Degree < 270d) // Degree 在90-270之间的显示
                        this.SetElementVisiable(oItem);
                    else
                        this.SetElementInvisiable(oItem);
                }
            }
    
            private void SetElementVisiable(ImageItem oItem)
            {
                if (oItem == null)
                    return;
    
                if (!oItem.IsVisible)
                {
                    if (!this.CvMain.Children.Contains(oItem))
                    {
                        oItem.IsVisible = true;
                        this.CvMain.Children.Add(oItem);
                    }
                }
    
                this.DoUpdateElementLocation(oItem);
            }
    
            private void SetElementInvisiable(ImageItem oItem)
            {
                if (oItem.IsVisible)
                {
                    if (this.CvMain.Children.Contains(oItem))
                    {
                        this.CvMain.Children.Remove(oItem);
                        oItem.IsVisible = false;
                    }
                }
            }
    
            public void DoUpdateElementLocation(ImageItem oItem)
            {
                double CenterX = this.GdRoot.Width / 2.0;
                double dX = -Radius * Math.Sin(ConvertToRads(oItem.Degree));
                oItem.X = (dX + CenterX - this.ElementWidth / 2d);
                double dScale = GetScaledSize(oItem.Degree);
                oItem.ScaleX = dScale;
                oItem.ScaleY = dScale;
                //oItem.Opacity = dScale;
                int nZIndex = GetZValue(oItem.Degree);
                Canvas.SetZIndex(oItem, nZIndex);
            }
    
            #endregion
    
    
            #region Drag And Move
    
            private bool IsMouseDown = false;
            private double PreviousX = 0;
            private double CurrentX = 0;
            private double IntervalDegree = 0;
            private double InertiaDegree = 0;
            private double TotalMoveDegree = 0;
    
            private void GdRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                this.IsMouseDown = true;
                this.IntervalDegree = 0;
                this.PreviousX = e.GetPosition(this).X;
                this.TotalMoveDegree = 0;
                CompositionTarget.Rendering -= new EventHandler(CompositionTarget_Rendering);
            }
    
            private void Carousel2DView_MouseMove(object sender, MouseEventArgs e)
            {
                if (this.IsMouseDown)
                {
                    this.CurrentX = e.GetPosition(this).X;
                    this.IntervalDegree = this.CurrentX - this.PreviousX;
                    this.TotalMoveDegree += Math.Abs(this.IntervalDegree * 0.5d);
                    this.InertiaDegree = this.IntervalDegree * 5d;
    
                    for (int i = 0; i < this.ElementList.Count; i++)
                    {
                        ImageItem oItem = this.ElementList[i];
                        oItem.Degree += this.IntervalDegree;
                    }
                    this.UpdateLocation();
                    this.PreviousX = this.CurrentX;
                }
            }
    
            private void Carousel2DView_MouseUp(object sender, MouseButtonEventArgs e)
            {
                if (this.IsMouseDown)
                {
                    this.IsMouseDown = false;
                    this.CurNavItem = null;
                    if (this.InertiaDegree != 0)
                        CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
                }
            }
    
            private void CompositionTarget_Rendering(object sender, EventArgs e)
            {
                double dIntervalDegree = this.InertiaDegree * 0.4;
                for (int i = 0; i < this.ElementList.Count; i++)
                {
                    ImageItem oItem = this.ElementList[i];
                    oItem.Degree += dIntervalDegree;
                }
                this.UpdateLocation();
    
                this.InertiaDegree -= dIntervalDegree;
                if (Math.Abs(this.InertiaDegree) < 0.1)
                    CompositionTarget.Rendering -= new EventHandler(CompositionTarget_Rendering);
            }
    
    
            public void RefreshBanner()
            {
                this.CvMain.Children.Clear();
                CreateElements();
    
                ReStartTimer();
            }
    
            #endregion
    
            public event Action OnReturn;
    
            //private void BdrReturn_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            //{
            //    this.BdrReturn.MouseLeftButtonDown -= BdrReturn_MouseLeftButtonDown;
            //    CompositionTarget.Rendering -= new EventHandler(CompositionTarget_Rendering);
            //    this.IsEnabled = false;
    
            //    //CvUtils.EffectAnimation(this, new FadeTransitionEffect(), false, null, null, 0.5d, 0d, 
            //    //    () => {
            //            if (this.OnReturn != null)
            //                this.OnReturn();
            //        //});
            //}
        }
    }
    

      ImageItem

    <UserControl x:Class="CustomControl.ImageItem"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
                 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                 xmlns:local="clr-namespace:CustomControl"
                 mc:Ignorable="d" Width="230" Height="200" RenderTransformOrigin="0.5 0.5"
                 d:DesignHeight="300" d:DesignWidth="300">
        <UserControl.RenderTransform>
            <TransformGroup>
                <ScaleTransform ScaleX="{Binding Path=ScaleX}" ScaleY="{Binding Path=ScaleY}"/>
                <TranslateTransform X="{Binding Path=X}" Y="{Binding Path=Y}"/>
            </TransformGroup>
        </UserControl.RenderTransform>
        <Grid>
            <Border  CornerRadius="0" Margin="0,0,0,0" BorderThickness="0" BorderBrush="White">
                <!--<Border.Background>
                    <SolidColorBrush Color="White" Opacity="0.5"/>
                </Border.Background>-->
            </Border>
            <Image Margin="0,0" Stretch="Fill" x:Name="ImgMain"/>
            <!--<TextBlock VerticalAlignment="Bottom" Margin="30,30" Foreground="White"
                       TextWrapping="Wrap" x:Name="TbkTitle" TextAlignment="Center" 
                       FontSize="20"/>-->
        </Grid>
    </UserControl>
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace CustomControl
    {
        /// <summary>
        /// ImageItem.xaml 的交互逻辑
        /// </summary>
        public partial class ImageItem : UserControl
        {
            public double X
            {
                get { return (double)GetValue(XProperty); }
                set { SetValue(XProperty, value); }
            }
            public static readonly DependencyProperty XProperty =
                DependencyProperty.Register("X", typeof(double), typeof(ImageItem), new UIPropertyMetadata(0.0));
    
            public double Y
            {
                get { return (double)GetValue(YProperty); }
                set { SetValue(YProperty, value); }
            }
            public static readonly DependencyProperty YProperty =
                DependencyProperty.Register("Y", typeof(double), typeof(ImageItem), new UIPropertyMetadata(0.0));
    
            public double ScaleX
            {
                get { return (double)GetValue(ScaleXProperty); }
                set { SetValue(ScaleXProperty, value); }
            }
            public static readonly DependencyProperty ScaleXProperty =
                DependencyProperty.Register("ScaleX", typeof(double), typeof(ImageItem), new UIPropertyMetadata(1.0));
    
            public double ScaleY
            {
                get { return (double)GetValue(ScaleYProperty); }
                set { SetValue(ScaleYProperty, value); }
            }
            public static readonly DependencyProperty ScaleYProperty =
                DependencyProperty.Register("ScaleY", typeof(double), typeof(ImageItem), new UIPropertyMetadata(1.0));
    
            public double Degree;
            private string FileSrc="";
    
            private bool _IsVisible = false;
            public new bool IsVisible
            {
                get { return _IsVisible; }
                set
                {
                    _IsVisible = value;
                    if (value)
                        this.LoadUiImmediate();
                }
            }
    
            private bool IsUiLoaded = false;
    
            public void LoadUiImmediate()
            {
                if (!IsUiLoaded)
                {
                    IsUiLoaded = true;
                    try {
                        if (File.Exists(FileSrc))
                            this.ImgMain.Source = new BitmapImage(new Uri(FileSrc));
                    }
                    catch { }
                }
            }
    
            public ImageItem(string sFile)
            {
                InitializeComponent();
                this.FileSrc = sFile;
                //string sFileName = System.IO.Path.GetFileNameWithoutExtension(sFile);
                //this.TbkTitle.Text = sFileName;
                this.Loaded += ImageItem_Loaded;
                this.DataContext = this;
            }
    
            private void ImageItem_Loaded(object sender, RoutedEventArgs e)
            {
                this.Loaded -= ImageItem_Loaded;
                AsynchUtils.AsynchSleepExecuteFunc(this.Dispatcher, LoadUiImmediate, 0.5);
            }
    
            public void Dispose()
            {
                this.ImgMain.Source = null;
            }
        }
    }
    

    引用: 

     <local:Carousel2DView x:Name="MainBanner"  GridWidth="800" GridHeight="200" ElementWidth="280" ElementHeight="200" Radius="420" Visibility="Collapsed"/>

    MainBanner.GridWidth = 850;
    MainBanner.GridHeight = 200;
    MainBanner.ElementWidth = 280;
    MainBanner.ElementHeight = 180;
    MainBanner.Radius = 420;

    MainBanner.RefreshBanner();

  • 相关阅读:
    【WPF学习】第四十八章 理解WPF动画
    【WPF学习】第四十七章 WriteableBitmap类
    【WPF学习】第四十六章 效果
    【WPF学习】第四十五章 可视化对象
    【WPF学习】第四十四章 图画
    【WPF学习】第四十三章 路径和几何图形
    【WPF学习】第四十二章 透明
    【WPF学习】第四十一章 变换
    【WPF学习】第四十章 画刷
    【WPF学习】第三十九章 理解形状
  • 原文地址:https://www.cnblogs.com/candyzhmm/p/12713762.html
Copyright © 2011-2022 走看看