动态UI心得一(CSharp)

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/coconut9325/article/details/72628760


version :  1.1

time :  20170523 12:30

author :  秋后夜雨coconut9325的博客

虽然不是什么大工程,但是依然保留所有权


在工作了一定时间之后,你会发现静态 UI 实在是让人受不了了!!!

所以接下来,我将对动态UI进行研究,给自己的工作时间予以肯定,以及提高兴趣。


在我们平常生活接触过的软件当中,我们发现了很多动态的控件。

例如:

1.展开折叠,在展开或收起控件时的动画效果。

2.进入结束,在进入或者结束某一场景、软件时的动画效果。

3.放大缩小,在放大或缩小地图时的动画效果。

4.滑动移动,在自定义slider中,自定义控件的滑动移动。

因为快速打的第一篇原创,一下没想到更多的动态信息,待以后补充,更欢迎留言讨论。

在开始之前,我们要清楚认识到物理学的重要性,因为这可以帮助我们设计UI更加贴近生活规律,或者说更加逼真,让你的UI不再干枯无味。

环境:CSharp (.Net framework 4.0)

#region Fields & Variants & model
        // GroupBoxFilter  move distance.
        private int moveDistanceX = 705;
        // GroupBoxFilter  move distance.
        private int moveDistanceY = 165;
        // GroupBoxFilter begin move Point (X,Y). final move Distance (X,Y).
        private Point beginPoint = new Point(0, 0);
        private Point finalPoint = new Point(0, 0);
        // Simulation range.
        private const int curvesAccuracy = 3;
        private const decimal startCurves = -5.0m;  // normally not change
        // Simulation curves.
        private int moveCurves = 0;
        private const decimal curvesSpeed = 0.1m;
        private const int curvesRange = (int)((0 - startCurves * 2) / curvesSpeed) + 1;
        private double[] curvesArray = new double[curvesRange];
        #endregion

初始化:

private void Form1_Load(object sender, EventArgs e)
        {
            try
            {
                InitUI();
            }
            catch (Exception ex)
            {
#if DEBUG
                MessageBox.Show(ex.ToString());
#endif
                throw;
            }
        }

        public void InitUI()
        {
            // Init simulation curves
            for (int i = 0; i < curvesRange; i++)
            {
                if (i == 0)
                    curvesArray[i] = 0;
                else if (i + 1 >= curvesRange)
                    curvesArray[i] = 1;
                else
                    curvesArray[i] = Math.Round(((Math.Tanh((double)startCurves + (double)curvesSpeed * i) + 1) / 2), curvesAccuracy, MidpointRounding.AwayFromZero);
            }
        }
折叠展开按钮:
private void btnFold_Click(object sender, EventArgs e)
        {
            if (groupBoxFilter.Width < this.Width / 2)
            {
                // move to right.
                beginPoint = new Point(groupBoxFilter.Width, groupBoxFilter.Height);
                finalPoint = new Point(groupBoxFilter.Width + moveDistanceX, groupBoxFilter.Height + moveDistanceY);
                tmFold.Enabled = true;
            }
            else
            {
                // move to left.
                beginPoint = new Point(groupBoxFilter.Width, groupBoxFilter.Height);
                finalPoint = new Point(groupBoxFilter.Width - moveDistanceX, groupBoxFilter.Height - moveDistanceY);
                tmFold.Enabled = true;
            }
        }
定时器(100ms):

private void tmFold_Tick(object sender, EventArgs e)
        {
            string foldString = "Fold";
            double movePercent = curvesArray[moveCurves];
            Point smallChange = new Point(1, 1);
            Point finalMoveDistance = new Point(Math.Abs(finalPoint.X - beginPoint.X), Math.Abs(finalPoint.Y - beginPoint.Y));
            Point nowMoveDistance = new Point(Math.Abs(groupBoxFilter.Width - beginPoint.X), Math.Abs(groupBoxFilter.Height - beginPoint.Y));

			// calculate smallChange to prepare moving.
            if (groupBoxFilter.Width == finalPoint.X)
                smallChange.X = 0;
            else
                smallChange.X = (int)(finalMoveDistance.X * curvesArray[moveCurves] - nowMoveDistance.X);
            if (groupBoxFilter.Height == finalPoint.Y)
                smallChange.Y = 0;
            else
                smallChange.Y = (int)(finalMoveDistance.Y * curvesArray[moveCurves] - nowMoveDistance.Y);
			// begin move.
            if (beginPoint.X < this.Width / 2)
            {
                //move to right.
                groupBoxFilter.Size = new Size(groupBoxFilter.Width + smallChange.X, groupBoxFilter.Height + smallChange.Y);
                int moveBtn = (groupBoxFilter.Height - btnFold.Height) / 2 + 4;
                btnFold.Location = new Point(btnFold.Location.X, moveBtn);
                foldString = "Fold";
            }
            else
            {
                //move to left.
                groupBoxFilter.Size = new Size(groupBoxFilter.Width - smallChange.X, groupBoxFilter.Height - smallChange.Y);
                int moveBtn = (groupBoxFilter.Height - btnFold.Height) / 2 + 4;
                btnFold.Location = new Point(btnFold.Location.X, moveBtn);
                foldString = "Unfold";
            }
            // move Curves.
            if (moveCurves == curvesRange - 1)
                moveCurves = 0;
            else
                moveCurves++;
            // end move.
            if (groupBoxFilter.Width == finalPoint.X && groupBoxFilter.Height == finalPoint.Y)
            {
                moveCurves = 0;
                btnFold.Text = foldString;
                this.tmFold.Enabled = false;
            }
        }



建议定时器时间参数与CurvesSpeed参数稍稍相互调节一下,即可看到连贯的效果


动态设计:

曲线采用的是tanh函数(Time/Distance),模拟加速度的逐渐增加及减少的物理运动。



动态效果图:




version :  1.1

time :  20170523 12:30

author :  秋后夜雨coconut9325的博客



展开阅读全文

没有更多推荐了,返回首页