渐变动画生成

    /// <summary>
    /// 修改了一下,加了一个回调函数,并且代码加了些注释
    /// </summary>
    public class AnimatorEffect
    {
        //保存对控件操作的特性list
        Dictionary<Object, List<AnimJob>> objects;
        Timer tmrAnim = new Timer();

        //回调函数
        public delegate void FunctionDelegate(bool isSuccess, string msg = "");

        private int fps = 25;
        /// <summary>
        /// fps越小越快,最小1,单位毫秒,默认25
        /// </summary>
        public int FPS
        {
            get
            {
                return fps;
            }
            set
            {
                fps = value;
                tmrAnim.Interval = fps;
            }
        }
        private class AnimJob
        {
            //特性
            public string Property;
            //
            public Object Value;
            //是否执行完毕
            public FunctionDelegate CallBack;
        }
        public AnimatorEffect()
        {
            objects = new Dictionary<object, List<AnimJob>>();
            tmrAnim.Interval = 25;
            tmrAnim.Enabled = true;
            tmrAnim.Tick += tmrAnim_Tick;
        }
        public AnimatorEffect(int FPS)
        {
            objects = new Dictionary<object, List<AnimJob>>();
            tmrAnim.Interval = 25;
            tmrAnim.Enabled = true;
            this.FPS = FPS;
            tmrAnim.Tick += tmrAnim_Tick;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="thisValue"></param>
        /// <param name="desValue"></param>
        /// <returns></returns>
        private int getStep(int thisValue, int desValue)
        {
            //如果当前值和目标值相同,则不处理
            if (thisValue == desValue) return 0;
            //否则计算每次变化多少个像素
            int step = (desValue - thisValue) / 3;
            //等于0的情况为目标值和当前值在3以内
            if (step == 0)
            {
                //如果目标值大于当前值,则为1,否则为-1
                //在3个像素以内每次变化1
                if (desValue > thisValue) step = 1;
                else step = -1;
            }
            return step;
        }
        private double convertStepToPersent(int intStep)
        {
            double step = (double)intStep / 100;
            if (Math.Abs(step) < 0.01)
            {
                if (intStep > 0) step = 0.01;
                else step = -0.01;
            }
            return step;
        }
        void tmrAnim_Tick(object sender, EventArgs e)
        {
            //循环每一个控件,按照控件所对应的特性和值做相应处理
            foreach (KeyValuePair<object, List<AnimJob>> item in objects)
            {
                if (item.Key is Control)
                {
                    //获取控件
                    Control control = (Control)item.Key;
                    //获取该控件所有特性
                    List<AnimJob> jobs = item.Value;
                    //循环所有特性
                    foreach (AnimJob job in jobs)
                    {
                        //根据特性做相应处理
                        switch (job.Property.ToLower())
                        {
                            case "left":
                                int step = getStep(control.Left, (int)job.Value);
                                //step为0说明该特性设定已达目的,则删除该特性
                                if (step == 0)
                                {
                                    jobs.Remove(job);
                                    if (job.CallBack != null)
                                        job.CallBack(true);
                                    return;
                                }
                                //处理
                                control.Left += step;
                                break;
                            case "top":
                                step = getStep(control.Top, (int)job.Value);
                                if (step == 0)
                                {
                                    jobs.Remove(job);
                                    if (job.CallBack != null)
                                        job.CallBack(true);
                                    return;
                                }
                                control.Top += step;
                                break;
                            case "width":
                                step = getStep(control.Width, (int)job.Value);
                                if (step == 0)
                                {
                                    jobs.Remove(job);
                                    if (job.CallBack != null)
                                        job.CallBack(true);
                                    return;
                                }
                                control.Width += step;
                                break;
                            case "height":
                                step = getStep(control.Height, (int)job.Value);
                                if (step == 0)
                                {
                                    jobs.Remove(job);
                                    if (job.CallBack != null)
                                        job.CallBack(true);
                                    return;
                                }
                                control.Height += step;
                                break;
                            case "backcolor":
                                //颜色变化与上面思路一致,更改的是R/G/B三个值
                                Color val = (Color)job.Value;
                                int valR = val.R;
                                int valG = val.G;
                                int valB = val.B;

                                int stepR = getStep(control.BackColor.R, valR);
                                int stepG = getStep(control.BackColor.G, valG);
                                int stepB = getStep(control.BackColor.B, valB);
                                if (Math.Abs(stepR) + Math.Abs(stepG) + Math.Abs(stepB) == 0)
                                {
                                    jobs.Remove(job);
                                    if (job.CallBack != null)
                                        job.CallBack(true);
                                    return;
                                }
                                Color backColor = Color.FromArgb(control.BackColor.R + stepR,
                                    control.BackColor.G + stepG, control.BackColor.B + stepB);
                                control.BackColor = backColor;
                                break;
                            case "opacity":
                                if (item.Key is Form)
                                {
                                    Form form = (Form)control;
                                    step = getStep((int)(form.Opacity * 100), (int)(Convert.ToDouble(job.Value) * 100));
                                    if (step == 0)
                                    {
                                        jobs.Remove(job);
                                        if (job.CallBack != null)
                                            job.CallBack(true);
                                        return;
                                    }
                                    form.Opacity += convertStepToPersent(step);
                                }
                                else
                                {
                                    jobs.Remove(job);
                                    if (job.CallBack != null)
                                        job.CallBack(false, "只支持窗体调整透明度属性");
                                    return;
                                }
                                break;
                            default:
                                jobs.Remove(job);
                                if (job.CallBack != null)
                                    job.CallBack(false, "控件不支持[" + job.Property + "]属性");
                                return;
                        }
                    }
                }
                else
                {
                }
            }
        }


        /// <summary>
        /// 当多次设置一个控件的不同属性时,则加入list集合一同处理
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="prop"></param>
        /// <param name="value"></param>
        public void Set(Object obj, string prop, Object value, FunctionDelegate callBack = null)
        {
            if (!objects.ContainsKey(obj))
            {
                List<AnimJob> jobs = new List<AnimJob>();
                objects.Add(obj, jobs);
            }
            AnimJob job = new AnimJob();
            job.Property = prop;
            job.Value = value;
            job.CallBack = callBack;
            if (!updateExistProperty(objects[obj], job)) objects[obj].Add(job);
        }
        /// <summary>
        /// 判断对同一控件设定的属性是否已经存在,如果存在,则将目标值重新设定
        /// </summary>
        /// <param name="jobs"></param>
        /// <param name="aJob"></param>
        /// <returns></returns>
        private bool updateExistProperty(List<AnimJob> jobs, AnimJob aJob)
        {
            bool have = false;
            foreach (AnimJob job in jobs)
            {
                if (job.Property == aJob.Property)
                {
                    have = true;
                    job.Value = aJob.Value;
                    break;
                }
            }
            return have;
        }
    }

 

posted @ 2013-09-10 10:25  Micmacs  阅读(235)  评论(0编辑  收藏  举报