渐变动画生成
/// <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; } }