代码之家  ›  专栏  ›  技术社区  ›  Jon B

将颜色淡入白色(增加亮度)

  •  7
  • Jon B  · 技术社区  · 17 年前

    我想在.NET中设置一个文本框“发光”黄色,然后“褪色”为白色(基本上,通过增加亮度)。我想StackOverflow在你发布答案后会这么做。我知道增加亮度并不是那么简单(不仅仅是均匀地增加/减少RGB),但我不知道如何做到这一点。

    完美的色彩准确度对这一点并不重要。我正在使用C,虽然VB示例也很好。

    编辑: 这是给Winforms的。

    4 回复  |  直到 16 年前
        1
  •  8
  •   Michael Meadows    17 年前

    这可能比你需要的更多,下面是我使用的类的代码:

    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<DataEventArgs<Color>> 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;
        }
    }
    

    这种用途 DataEventArgs<T> (如下所示)

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

    以这种形式使用:

    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<Color> 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();
    }
    
        2
  •  2
  •   Andrei Krotkov    17 年前

    只需根据时间在颜色之间插入即可。

    如果您的橙色是(r1、g1、b1),并且您希望淡入不同的颜色(r2、g2、b2),则线性插值的公式是(r1+(r2-r1)*t、g1+(g2-g1)*t、b1+(b2-b1)*t,其中t在[0.0 1.0]范围内。

    在您的示例中,第一种颜色可能类似于(255200,0),第二种颜色可能类似于(255255255)。

    如果希望平滑过渡,请查找不同的插值方法。

        3
  •  0
  •   Neil N HLGEM    17 年前

    如果你想做得恰到好处和顺利,看看ColorMatrix类。

        4
  •  0
  •   Chris Doggett    17 年前

    当我提交这个答案时,您最初并没有指定一种技术,但下面是使用jquery的方法。

    UI/Effects/Highlight .

    $("div").click(function () {
          $(this).effect("highlight", {}, 3000);
    });
    
    推荐文章