• WPF 图片浏览 伪3D效果


    首先上效果图:

    因项目要求,需要把图片以“好看”、“炫”的效果展示出来,特地研究了一下WPF关于3D方面的制作,奈何最终成果只是能够画出一个立方体并使之旋转。

    项目时间仅剩两天,只好放弃3D另找出路,于是就想起了Flash中各种“炫丽”的动画效果,图片按椭圆排列,并且旋转。

    于是开始代码,然后发现关于椭圆啊、正玄余玄、x,y,r等等数学知识都忘得光光了,仅有思路没有进展,无奈之下开始百度恶补数学知识。图形变换、3D是很考验数学知识的,本人对于3D方面的学习就败在数学之下,高中数学学的还不错的,现在……哎,不提也罢。

    然后找到这么一篇博文——javascript-按圆形排列DIV元素(三)实例---- 图片按椭圆形转动,是js代码,在此感谢这位船长op大大的无私奉献。

    下面正式上代码:

    定义ImageInfo类,实现INotifyPropertyChanged接口,属性没有写说明,不过看名称我想各位也能知道是什么含义了。

    public class ImageInfo : INotifyPropertyChanged
        {
            private int _zIndex;
    
            public int ZIndex
            {
                get { return _zIndex; }
                set
                {
                    if (value != _zIndex)
                    {
                        _zIndex = value;
                        this.NotifyPropertyChanged("ZIndex");
                    }
                }
            }
            private double _left;
    
            public double Left
            {
                get { return _left; }
                set
                {
                    if (value != _left)
                    {
                        _left = value;
                        this.NotifyPropertyChanged("Left");
                    }
                }
            }
            private double _top;
    
            public double Top
            {
                get { return _top; }
                set
                {
                    if (value != _top)
                    {
                        _top = value;
                        this.NotifyPropertyChanged("Top");
                    }
                }
            }
            private double _width;
    
            public double Width
            {
                get { return _width; }
                set
                {
                    if (value != _width)
                    {
                        _width = value;
                        this.NotifyPropertyChanged("Width");
                    }
                }
            }
            private double _height;
    
            public double Height
            {
                get { return _height; }
                set
                {
                    if (value != _height)
                    {
                        _height = value;
                        this.NotifyPropertyChanged("Height");
                    }
                }
            }
    
            private double _opacity = 1.0;
    
            public double Opactity
            {
                get { return _opacity; }
                set 
                {
                    if (value != _opacity)
                    {
                        _opacity = value;
                        this.NotifyPropertyChanged("Opactity");
                    }
                }
            }
    
            private string _imagePath;
    
            public string ImagePath
            {
                get { return _imagePath; }
                set
                {
                    if (value != _imagePath)
                    {
                        _imagePath = value;
                        this.NotifyPropertyChanged("ImagePath");
                    }
                }
            }
    
            public ImageInfo(string path)
            {
                this.ImagePath = path;
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void NotifyPropertyChanged(String propertyName)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (null != handler)
                {
                    handler(this, new PropertyChangedEventArgs(propertyName));
                }
            }
        }
    ViewModel Code

    在xaml中binding ImageInfo 中的对应的属性,在后台代码中使用计时器来定时更改ImageInfo中的属性,当属性值发生改变时就会通知到界面,于是就实现了动画效果了。

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:local="clr-namespace:WPF_ImageShow" x:Class="WPF_ImageShow.MainWindow"
            Title="MainWindow" Height="600" Width="800" >
        <Window.Resources>
            <local:DoubleConverter x:Key="doubleConverter"/>
        </Window.Resources>
        <Grid>
            <ListView ScrollViewer.HorizontalScrollBarVisibility="Disabled" Loaded="lv_Loaded"
                ScrollViewer.VerticalScrollBarVisibility="Disabled" x:Name="lv" Background="Black">
                <!--<ListView.ItemTemplate>
                    <DataTemplate>
                        <Border>
                            <StackPanel>
                                <Image Source="{Binding ImagePath, Mode=OneWay}" x:Name="img" 
                                                Stretch="UniformToFill" Width="{Binding Width, Mode=OneWay}"
                                                Height="{Binding Height, Mode=OneWay}"/>
                                <Rectangle RenderTransformOrigin="1,0.5"  Height="{Binding Height, Converter={StaticResource doubleConverter}, Mode=OneWay}">
                                    <Rectangle.Fill>
                                        <VisualBrush Visual="{Binding ElementName=img}" />
                                    </Rectangle.Fill>
                                    <Rectangle.RenderTransform>
                                        <TransformGroup>
                                            <ScaleTransform ScaleY="-1" />
                                        </TransformGroup>
                                    </Rectangle.RenderTransform>
                                    <Rectangle.OpacityMask>
                                        <LinearGradientBrush StartPoint="0,0"   EndPoint="0,1">
                                            <GradientStop Offset="0.3"     Color="Transparent" />
                                            <GradientStop Offset="1"   Color="#44000000" />
                                        </LinearGradientBrush>
                                    </Rectangle.OpacityMask>
                                </Rectangle>
                            </StackPanel>
                        </Border>
                    </DataTemplate>
                </ListView.ItemTemplate>-->
                <ListView.Resources>
                    <Style TargetType="{x:Type ListViewItem}">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="{x:Type ListViewItem}" >
                                    <Border>
                                        <StackPanel>
                                            <Image Source="{Binding ImagePath, Mode=OneWay}" x:Name="img" 
                                                Stretch="UniformToFill" Width="{Binding Width, Mode=OneWay}"
                                                Height="{Binding Height, Mode=OneWay}"/>
                                            <Rectangle RenderTransformOrigin="1,0.5"  Height="{Binding Height, Converter={StaticResource doubleConverter}, Mode=OneWay}">
                                                <Rectangle.Fill>
                                                    <VisualBrush Visual="{Binding ElementName=img}" />
                                                </Rectangle.Fill>
                                                <Rectangle.RenderTransform>
                                                    <TransformGroup>
                                                        <ScaleTransform ScaleY="-1" />
                                                    </TransformGroup>
                                                </Rectangle.RenderTransform>
                                                <Rectangle.OpacityMask>
                                                    <LinearGradientBrush StartPoint="0,0"   EndPoint="0,1">
                                                        <GradientStop Offset="0.3"     Color="Transparent" />
                                                        <GradientStop Offset="1"   Color="#44000000" />
                                                    </LinearGradientBrush>
                                                </Rectangle.OpacityMask>
                                            </Rectangle>
                                        </StackPanel>
                                    </Border>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                        <Setter Property="Opacity" Value="{Binding Opactity, Mode=OneWay}"/>
                        <Setter Property="Canvas.Left" Value="{Binding Left, Mode=OneWay}"/>
                        <Setter Property="Canvas.Top" Value="{Binding Top, Mode=OneWay}"/>
                        <Setter Property="Panel.ZIndex" Value="{Binding ZIndex, Mode=OneWay}"/>
                    </Style>
                </ListView.Resources>
                <ListView.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas/>
                    </ItemsPanelTemplate>
                </ListView.ItemsPanel>
            </ListView>
        </Grid>
    </Window>
    XAML Code
     /// <summary>
            /// 设置动画
            /// </summary>
            void Run()
            {
                //动画速率
                double speed = 0.0;
                //定时器,定时修改ImageInfo中各属性,从而实现动画效果
                DispatcherTimer timer = new DispatcherTimer();
                //时间间隔
                timer.Interval = TimeSpan.FromMilliseconds(100);
                timer.Tick += (ss, ee) =>
                {
                    #region
                    //设置圆心x,y
                    double centerX = this.ActualWidth / 2;
                    double centerY = this.ActualHeight / 2 - 50;//减去适当的值,因为会设置最下面的图片最大,上面的图片较小
    
                    //设置图片最大的宽、高
                    double maxWidth = 300;
                    double maxHeight = 200;
    
                    //设置椭圆的长边和短边
                    double a = centerX - maxWidth / 2.0;
                    double b = centerY - maxHeight / 2.0;
    
                    //运动一周后恢复为0
                    speed = speed < 360 ? speed : 0.0;
                    //运运的速度 此“增值”和  timer.Interval对动画的流畅性有影响
                    speed += 0.5;
                    //运动距离,即运动的弧度数;
                    var ainhd = speed * Math.PI / 180;
                    //每个图片之间相隔的角度
                    var angle = (360.0 / data.Count) * Math.PI / 180.0;
                    //图片序号
                    int index = 0;
                    foreach (var img in data)
                    {
                        //最下面一张图ZIndex最大,Opacity最大,长宽最大
    
                        img.ZIndex = (int)img.Top;
                        //当前图片与最下面一张图片的Y的比值
                        var allpers = img.Top / (centerY + b);
                        //不要小于0.2,太小了就看不见了,可以适当调整
                        allpers = Math.Max(0.2, allpers);
                        //设置图片大小
                        img.Width = allpers * maxWidth;
                        img.Height = allpers * maxHeight;
                        //设置透明度
                        img.Opactity = Math.Max(allpers * 1.5, 0.4);
    
                        //公式:x=sin * a //+ centerX因为默认wpf默认左上角为坐标原点;//- img.Width / 2.0是以图片中心点作为运动轨迹
                        img.Left = Math.Sin((angle * index + ainhd)) * a + centerX - img.Width / 2.0;//x=sin * a
                        //y=cos * b
                        img.Top = Math.Cos((angle * index + ainhd)) * b + centerY - img.Height / 2.0;
    
                        index++;
                    }
                    #endregion
                };
                //启动计时器,开始动画
                timer.Start();
            }
    
            private void lv_Loaded(object sender, RoutedEventArgs e)
            {
                //准备数据源 ObservableCollection<T>
                data = new ObservableCollection<ImageInfo>();
                //获取程序所在目录中的images文件夹
                DirectoryInfo di = new DirectoryInfo(AppDomain.CurrentDomain.BaseDirectory + "images");
                //添加此目录中的图片文件到data中
                foreach (var file in di.GetFiles())
                {
                    //验证是否为图片文件 (可以写一个方法来进行验证,此处仅支持jpg和png)
                    if (file.Extension.ToLower() == ".jpg" || file.Extension.ToLower() == ".png")
                    {
                        data.Add(new ImageInfo(file.FullName));
                    }
                }
                //设置ListView的ItemsSource
                lv.ItemsSource = data;
    
                Run();
            }
    View Code

    最后上一个简单的Demo:WPF_ImageShow

  • 相关阅读:
    MapReduce之Map Join
    MapReduce之Reduce Join
    MapReduce清洗日志数据统计PV量
    Hadoop MapReduce自定义数据类型
    ES6 对象拓展方法
    ES6箭头函数与this指向
    ES6参数默认值,剩余参数及展开数组
    ES6模板字符串及字符串的扩展方法
    浅谈ES6数组及对象的解构
    ECMAScript概述及浅谈const,let与块级作用域
  • 原文地址:https://www.cnblogs.com/LCHL/p/3078785.html
Copyright © 2020-2023  润新知