且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

WPF特效-实现弧形旋转轮播图

更新时间:2022-09-18 13:26:50

原文:WPF特效-实现弧形旋转轮播图

       项目遇到,琢磨并实现了循环算法,主要处理循环替换显示问题

      (如:12张图组成一个圆弧,但总共有120张图需要呈现,如何在滑动中进行显示块的替换,并毫无卡顿)

       处理的自己感觉比较满意,记录一下。

      2D效果图:


                                         WPF特效-实现弧形旋转轮播图

    

     2D动态Gif效果:

                                                        WPF特效-实现弧形旋转轮播图


       2D思路: Canvas作为承载控件,控制显示个数,以角度作为判断是否显示的标准。 同时图片以线程池或者延时加载的方式实现加载性能的优化。

       2D循环关键:

        private void UpdateLocation()
        {
            for (int i = 0; i < this.ElementList.Count; i++)
            {
                NavItem 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);
            }
        }


      3D效果图:

        WPF特效-实现弧形旋转轮播图


      3D动态Gif效果:

  

                     WPF特效-实现弧形旋转轮播图


      3D思路:以Viewport3D 作为容器,ModelVisual3D 实现元素块的承载,转动效果通过控制Camera的Angle角度实现。 

                      以显示块构成圆弧的角度以及Camera的旋转角度为依据控制元素块是否呈现或隐藏。


      3D循环替换关键

        private void DoUpdateLayout()
        {
            for (int i = 0; i < this.ElementList.Count; i++)
            {
                InteractivePanel3D oVisualItem = this.ElementList[i];
                
                if (oVisualItem.Degree + this.CameraAngleYZm.Angle >= this.TotalDegree / 2d)
                    oVisualItem.Degree -= this.TotalDegree;
                else if (oVisualItem.Degree + this.CameraAngleYZm.Angle <= -this.TotalDegree / 2d)
                    oVisualItem.Degree += this.TotalDegree;


                //元素块角度与3D场景旋转角度的角度差; 角度差在定义的范围内则元素块显示,否则隐藏
                double dDistanceToCenter = Math.Abs(oVisualItem.Degree + this.CameraAngleY.Angle - COriginViewprotAngel);
                if (dDistanceToCenter <= CBoundDegree)
                    this.SetVisualItemVisible(oVisualItem);
                else
                    this.SetVisualItemInvisible(oVisualItem);
            }
        }