Fade a color to white (increasing brightness)

前端 未结 4 1943
温柔的废话
温柔的废话 2021-02-04 18:20

I want to make a text box in .NET \"glow\" yellow, and then \"fade\" to white (basically, by incrementally increasing the brightness). I think Stackoverflow does this after you\

4条回答
  •  有刺的猬
    2021-02-04 18:36

    This may be more than you need, here's the code for the class I use:

    public class ControlColorAnimator
    {
        private const int INTERVAL = 100;
    
        private readonly decimal _alphaIncrement;
        private readonly decimal _blueIncrement;
        private readonly Color _endColor;
        private readonly decimal _greenIncrement;
        private readonly int _iterations;
        private readonly decimal _redIncrement;
        private readonly Color _startColor;
    
        private decimal _currentAlpha;
        private decimal _currentBlueValue;
        private decimal _currentGreenValue;
        private decimal _currentRedValue;
    
        private Timer _timer;
    
        public ControlColorAnimator(TimeSpan duration, Color startColor, Color endColor)
        {
            _startColor = startColor;
            _endColor = endColor;
            resetColor();
    
            _iterations = duration.Milliseconds / INTERVAL;
            _alphaIncrement = ((decimal) startColor.A - endColor.A) / _iterations;
            _redIncrement = ((decimal) startColor.R - endColor.R) / _iterations;
            _greenIncrement = ((decimal) startColor.G - endColor.G) / _iterations;
            _blueIncrement = ((decimal) startColor.B - endColor.B) / _iterations;
        }
    
        public Color CurrentColor
        {
            get
            {
                int alpha = Convert.ToInt32(_currentAlpha);
                int red = Convert.ToInt32(_currentRedValue);
                int green = Convert.ToInt32(_currentGreenValue);
                int blue = Convert.ToInt32(_currentBlueValue);
    
                return Color.FromArgb(alpha, red, green, blue);
            }
        }
    
        public event EventHandler> ColorChanged;
    
        public void Go()
        {
            disposeOfTheTimer();
            OnColorChanged(_startColor);
    
            resetColor();
    
            int currentIteration = 0;
            _timer = new Timer(delegate
                {
                    if (currentIteration++ >= _iterations)
                    {
                        Stop();
                        return;
                    }
                    _currentAlpha -= _alphaIncrement;
                    _currentRedValue -= _redIncrement;
                    _currentGreenValue -= _greenIncrement;
                    _currentBlueValue -= _blueIncrement;
                    OnColorChanged(CurrentColor);
                }, null, TimeSpan.FromMilliseconds(INTERVAL), TimeSpan.FromMilliseconds(INTERVAL));
        }
    
        public void Stop()
        {
            disposeOfTheTimer();
            OnColorChanged(_endColor);
        }
    
        protected virtual void OnColorChanged(Color color)
        {
            if (ColorChanged == null) return;
            ColorChanged(this, color);
        }
    
        private void disposeOfTheTimer()
        {
            Timer timer = _timer;
            _timer = null;
    
            if (timer != null) timer.Dispose();
        }
    
        private void resetColor()
        {
            _currentAlpha = _startColor.A;
            _currentRedValue = _startColor.R;
            _currentGreenValue = _startColor.G;
            _currentBlueValue = _startColor.B;
        }
    }
    

    This uses DataEventArgs (shown below)

    /// 
    /// Generic implementation of  that allows for a data element to be passed.
    /// 
    /// The type of data to contain.
    [DebuggerDisplay("{Data}")]
    public class DataEventArgs : EventArgs
    {
        private T _data;
    
        /// 
        /// Constructs a .
        /// 
        /// The data to contain in the 
        [DebuggerHidden]
        public DataEventArgs(T data)
        {
            _data = data;
        }
    
        /// 
        /// Gets the data for this .
        /// 
        public virtual T Data
        {
            [DebuggerHidden]
            get { return _data; }
            [DebuggerHidden]
            protected set { _data = value; }
        }
    
        [DebuggerHidden]
        public static implicit operator DataEventArgs(T data)
        {
            return new DataEventArgs(data);
        }
    
        [DebuggerHidden]
        public static implicit operator T(DataEventArgs e)
        {
            return e.Data;
        }
    }
    

    Use in your form like this:

    private ControlColorAnimator _animator;
    
    private void runColorLoop()
    {
        endCurrentAnimation();
        startNewAnimation();
    }
    
    private void endCurrentAnimation()
    {
        ControlColorAnimator animator = _animator;
        _animator = null;
        if (animator != null)
        {
            animator.ColorChanged -= _animator_ColorChanged;
            animator.Stop();
        }
    }
    
    private void startNewAnimation()
    {
        _animator = new ControlColorAnimator(TimeSpan.FromSeconds(.6), Color.Yellow, BackColor);
        _animator.ColorChanged += _animator_ColorChanged;
        _animator.Go();
    }
    
    private void _animator_ColorChanged(object sender, DataEventArgs e)
    {
        invokeOnFormThread(delegate { setColor(e); });
    }
    
    private void setColor(Color color)
    {
        // code to set color of the controls goes here
    }
    
    private void invokeOnFormThread(MethodInvoker method)
    {
        if (IsHandleCreated)
            Invoke(method);
        else
            method();
    }
    

提交回复
热议问题