关注小程序 找一找教程网-随时随地学编程

Net Core教程

用C#写一个防安卓的属性动画

用C#写一个防安卓的属性动画

  • 定义独立动画接口
  • 实现接口,创建值动画类
  • 实现对象属性动画
  • 应用

定义独立动画接口

public interface IAnimator
{
        IAnimator Start();
        IAnimator Stop();
        IAnimator Reset();
        IAnimator SetDuration(int times);
        IAnimator SetNext(IAnimator next);
}

实现接口,创建值动画类

using Doraemon.Common.Utility;
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace Doraemon.Common.Animation
{
    public class ValueAnimator<T> : IAnimator
    {
        private T start = default(T);
        private T end = default(T);
        private int times = 1000;
        private T curValue;
        private long ticks = 0;
        private IAnimator next = null;

        private Timer timer;

        public T CurValue
        {
            get => curValue;

            set
            {
                if ((IComparable)curValue != (IComparable)value)
                {
                    curValue = value;
                    Update?.Invoke(this, curValue);
                }
            }
        }

        public ValueAnimator(T start, T end)
        {
            CreateBase(start, end);
        }

        private void CreateBase(T start, T end)
        {
            this.start = start;
            this.end = end;
            timer = new Timer();
            timer.Enabled = false;
            timer.Interval = 10;
            timer.Tick += Timer_Tick;
        }

        public IAnimator Start()
        {
            timer.Start();
            return this;
        }

        public IAnimator Stop()
        {
            timer.Stop();
            return this;
        }

        public IAnimator Reset()
        {
            timer.Stop();
            CurValue = default(T);
            return this;
        }

        public event Handler<ValueAnimator<T>, T> Update;

        public event Handler<ValueAnimator<T>, T> Done;

        private List<string> strs = new List<string>();

        private void Timer_Tick(object sender, EventArgs e)
        {
            if (ticks == 0)
                ticks = SystemHelper.Ticks;
            double curRate = (SystemHelper.Ticks - ticks) / (times * 1000.0);
            double v1 = double.Parse(start.ToString());
            double v2 = double.Parse(end.ToString());
            
            bool reverse = (v2 - v1) < 0;
            double val = (v1 + (v2 - v1) * curRate);
            if ((!reverse && val >= v2)
                || (reverse && val <= v2))
            {
                CurValue = end;
                Stop();
                ticks = 0;
                Done?.Invoke(this, CurValue);
                if (next != null)
                    next.Start();
                
            }
            else
                CurValue = (T)Convert.ChangeType(val, typeof(T));
        }

        public IAnimator SetNext(IAnimator ani)
        {
            next = ani;
            return this;
        }

        public IAnimator SetDuration(int times)
        {
            this.times = times;
            return this;
        }
    }
}

实现对象属性动画

using System;
using System.Reflection;

namespace Doraemon.Common.Animation
{
    public class ObjectAnimator : IAnimator
    {
        private object obj = null;
        private string propertyName = string.Empty;
        private IAnimator animator;

        private ObjectAnimator(object obj, string propertyName, int start, int end)
        {
            this.obj = obj;
            this.propertyName = propertyName;
            var ani = new ValueAnimator<int>(start, end);
            this.animator = ani;
            ani.Update += Ani_Update;
        }
        private ObjectAnimator(object obj, string propertyName, double start, double end)
        {
            this.obj = obj;
            this.propertyName = propertyName;
            var ani = new ValueAnimator<double>(start, end);
            this.animator = ani;
            ani.Update += Ani_Update1;
        }

        private void Ani_Update1(ValueAnimator<double> sender, double e)
        {
            SetValue<double>(e);
        }

        private void SetValue<T>(T e)
        {
            try
            {
                Type t = this.obj.GetType();
                PropertyInfo pi = t.GetProperty(propertyName);
                pi.SetValue(this.obj, e);
            }
            catch
            {
                animator.Stop();
            }
        }

        private void Ani_Update(ValueAnimator<int> sender, int e)
        {
            SetValue<int>(e);
        }

        public static ObjectAnimator OfInt(object obj, string propertyName, int start, int end)
        {
            return new ObjectAnimator(obj, propertyName, start, end);
        }

        public static ObjectAnimator OfDouble(object obj, string propertyName, double start, double end)
        {
            return new ObjectAnimator(obj, propertyName, start, end);
        }

        public IAnimator Start()
        {
            return animator.Start();
        }

        public IAnimator Stop()
        {
            return animator.Stop();
        }

        public IAnimator Reset()
        {
            return animator.Reset();
        }

        public IAnimator SetDuration(int times)
        {
            return animator.SetDuration(times);
        }

        public IAnimator SetNext(IAnimator next)
        {
            return animator.SetNext(next);
        }
    }
}

应用

在WinForm中调用

         IAnimator ani1 = ObjectAnimator.OfDouble(this, "Opacity", 1, 0).SetDuration(200);
         IAnimator ani2 = ObjectAnimator.OfDouble(this, "Opacity", 0, 1).SetDuration(200);
         ani1.SetNext(ani2);
         ani2.SetNext(ani1);
         ani1.Start();

类安卓属性动画展示