2009-04-02 15 views
7

मैं .NET "चमक" पीले रंग में एक टेक्स्ट बॉक्स बनाना चाहता हूं, और उसके बाद "फीका" सफेद (मूल रूप से, चमक को बढ़ाकर) में एक टेक्स्ट बॉक्स बनाना चाहता हूं। मुझे लगता है कि एक उत्तर पोस्ट करने के बाद स्टैक ओवरफ्लो ऐसा करता है। मुझे पता है कि चमक बढ़ाना इतना आसान नहीं है (यह आरजीबी में समान रूप से बढ़ता/घटता नहीं है), लेकिन मुझे यकीन नहीं है कि यह कैसे करें।सफेद रंग (चमक बढ़ रहा है)

इसके लिए बिल्कुल सही रंग सटीकता महत्वपूर्ण नहीं है। मैं सी # का उपयोग कर रहा हूं, हालांकि वीबी उदाहरण भी ठीक होंगे।

संपादित करें: यह Winforms के लिए है।

उत्तर

8

इस से अधिक आप की जरूरत हो सकता है, यहां वर्ग मैं उपयोग के लिए कोड है:

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(); 
} 
+0

यह बहुत चालाक है, धन्यवाद :) मैंने इसे संशोधित किया है (एनीमेशन समाप्त होने पर एक छुपा पैरामीटर पास करने के लिए, नियंत्रण छिपा हुआ है) और इसे मेरे बेसक्लास में जोड़ा गया, अब मेरे सभी विरासत वाले रूप संभावित रूप से सेट को ओवरराइड कर सकते हैं और इसका उपयोग कर सकते हैं । मुझे सेटकॉलर में "हार्डकोडिंग" की बजाय एनीमेशन होगा, जहां नियंत्रण होगा, एक नियंत्रण प्राप्त करने में सक्षम होने का एक शानदार तरीका नहीं मिला है। कोई विचार? –

+0

ने कोशिश नहीं की है, लेकिन शायद नियंत्रण पर एक विस्तार विधि ... तो आप इसे "invokeOnFormThread (myControl.SetColor (e)) के रूप में कॉल कर सकते हैं;" –

+0

धन्यवाद, जांच करेगा।इस बीच, मैंने runColorLoop() को संशोधित किया है, इसलिए मैं एक रंग, एक अवधि, नियंत्रण पास कर सकता हूं और अगर मैं एनीमेशन समाप्त होने के बाद छिपाना चाहता हूं, तो इस तरह मैं इसे अपने बेस क्लास में और प्रत्येक विरासत में उपयोग कर सकता हूं फॉर्म base.runColorLoop (x, y, z, f) का उपयोग कर सकता है; –

0

जब मैंने यह उत्तर सबमिट किया था तो आपने मूल रूप से एक तकनीक निर्दिष्ट नहीं की थी, लेकिन यहां आप jQuery का उपयोग करके इसे कैसे करेंगे।

UI/Effects/Highlight

$("div").click(function() { 
     $(this).effect("highlight", {}, 3000); 
}); 
+0

उन्होंने कहा "Winforms" –

+0

बह, स्पष्ट रूप से भविष्य आपके "ई-साथी" पर "क्लाउड" में "वेब ऐप्स" है। तो उसे अपने आवेदन में वेबकिट लपेटना चाहिए और सीएसएस प्रभाव और एनिमेशन का उपयोग करना चाहिए जो इसका समर्थन करता है! – JeeBee

+0

मुझे बहुत रेट्रो लगता है :) –

2

बस समय के आधार पर रंगों के बीच अंतरण करें।

यदि आपका नारंगी रंग (आर 1, जी 1, बी 1) है और आप एक अलग रंग (आर 2, जी 2, बी 2) में फीका करना चाहते हैं, तो रैखिक इंटरपोलेशन के लिए सूत्र (आर 1 + (आर 2-आर 1) * टी, जी 1 + (जी 2-जी 1) * टी, बी 1 + (बी 2-बी 1) * टी), जहां टी [0.0 1.0] की सीमा में है।

आपके उदाहरण में, आपका पहला रंग शायद कुछ (255,200,0) जैसा है और आपका दूसरा रंग (255,255,255) होगा।

यदि आप चिकनी संक्रमण की इच्छा रखते हैं, तो इंटरपोलेशन के विभिन्न तरीकों को देखें।

0

यदि आप इसे क्विकली और सुचारु रूप से करना चाहते हैं, तो ColorMatrix क्लास पर एक नज़र डालें।

+0

रंगमेट्रिक्स छवियों पर अधिक या रंग बदल नहीं है? – Haukman

संबंधित मुद्दे