[C#] Fade Animation

Danielku15

Erfahrenes Mitglied
Hallo zusammen.

Ich arbeite z.Z. an einem neuen Control. Nun hab ich bei diversen Bereichen Hover-Effekte. Diese möchte ich nun aber nicht abrupt zeichnen, sondern schön über einen Fade. Ich hatte bereits schon Ideen, jedoch bin ich mir nich sicher ob dies auch einfacher lösbar wäre:
  1. Ich mache eine Kopie vom entsprechenden Bereich in einem Image, zeichne den Hover-Effekt in eine weitere Kopie, füge diese mit entsprechenden Alphawerten zusammen und zeichne dieses darauf ins Control.
  2. Ich ändere Dynamisch die Alphawerte der Farben so, dass der Hovereffekt nur farblich über Alphawerte sichtbar wird.
...
Wie würdet ihr das Lösen ohne Performanceprobleme zu bekommen. Weiters möchte ich diese Animation in eine AnimationHelper Klasse kapseln welche mir das Alphawert Handling übernimmt und auch dafür sorgt dass die entsprechenden Bereiche im gewünschten Intervall neu gezeichnet werden.

Gruß Daniel
 
Im Endeffekt musst du testen was performance mäßig besser ist.

Ich würde erstmal alles im Paint Ereignis zeichnen und nicht mit Images rum hantieren das ist denke ich mal die performateste Lösung.
 
Hallo.
Ich hab nun die Zeichenmethode meines Controls so angepasst dass ich nur noch einen Alphawert für die Hover-Effekte benötigt habe. Darauf war es kein großer Aufwand mehr den gewünschten FadeAnimationsHelper zu schreiben. Ich hoffe ihr könnt ihn auch mal gebrauchen. Die Kommentierung sollte genügen:

FadeAnimationHelper.cs
C#:
using System;
using System.Windows.Forms;

namespace CoderLine.UI.Animation
{
    /// <summary>
    /// Mit dieser Klasse ist es möglich Controls FadeAnimationen hinzuzufügen.
    /// </summary>
    /// <example>
    ///  Deklaration:
    ///  <code>
    ///   private readonly FadeAnimationHelper _oFadeAnimation;
    ///  </code>
    ///  Initialisierung (Interval und Schrittgröße): 
    ///  <code>
    ///    _oFadeAnimation = new FadeAnimationHelper();
    ///    _oFadeAnimation.AnimationStep += _oFadeAnimation_AnimationStep;
    ///    _oFadeAnimation.FadeInStep = 0.1f;
    ///    _oFadeAnimation.FadeOutStep = 0.2f;
    ///    _oFadeAnimation.FadeInInterval = 100;
    ///    _oFadeAnimation.FadeOutInterval = 50;
    ///  </code>
    ///  EventHandler (Neuzeichnen auslösen):
    ///  <code>
    ///  void _oFadeAnimation_AnimationStep(object sender, EventArgs e)
    ///  {
    ///      Invalidate();
    ///  }
    ///  </code>
    ///  Animationsstart (Beim MouseOver/Leave animieren):
    ///  <code>
    ///  public bool Hover
    ///  {
    ///      get
    ///      {
    ///          return _bHover;
    ///      }
    ///      internal set
    ///      {
    ///          if(_bHover == value)
    ///              return;
    ///          bool _bOldValue = _bHover;
    ///          _bHover = value;
    ///          // Von true auf false --> Ausblenden
    ///          if(_bOldValue && !_bHover)
    ///          {
    ///              _oFadeAnimation.FadeOut();
    ///          }
    ///          else // Von False auf True --> Einblenden
    ///          {
    ///              _oFadeAnimation.FadeIn();
    ///          }       
    ///      }
    ///  }
    ///  </code>
    ///  Über _oFadeAnimation.Alpha kann dann der aktuelle Alphawert für das Zeichnen abgerufen werden.
    /// </example>
    internal class FadeAnimationHelper : IDisposable
    {
        #region Felder

        /// <summary>
        /// Timer für die Fade-In Animation.
        /// </summary>
        private readonly Timer _oFadeInTimer;
        /// <summary>
        /// Schrittgröße für Fade-In Animationsinterval.
        /// </summary>
        private float _fFadeInStep;

        /// <summary>
        /// TImer für die Fade-Out Animation.
        /// </summary>
        private readonly Timer _oFadeOutTimer;
        /// <summary>
        /// Schrittgröße für Fade-Out Animationsinterval.
        /// </summary>
        private float _fFadeOutStep;

        /// <summary>
        /// Aktueller Alphawert.
        /// </summary>
        private float _fAlpha;     

        #endregion

        #region Eigenschaften

        /// <summary>
        /// Ruft ab um wieviel der Alphawert pro Fade-In Animationsschritt zunimmt oder legt dies fest.
        /// </summary>
        public float FadeInStep
        {
            get
            {
                return _fFadeInStep;
            }
            set
            {
                _fFadeInStep = value;
            }
        }

        /// <summary>
        /// Ruft ab um wieviel der Alphawert pro Fade-Out Animationsschritt abnimmt oder legt dies fest.
        /// </summary>
        public float FadeOutStep
        {
            get
            {
                return _fFadeOutStep;
            }
            set
            {
                _fFadeOutStep = value;
            }
        }

        /// <summary>
        /// Ruft den aktuellen Alphawert der Animation ab.
        /// </summary>
        public float Alpha
        {
            get
            {
                return _fAlpha;
            }
        }


        /// <summary>
        /// Das Animationsintervall für den Fade-In in Millisekunden
        /// </summary>
        public int FadeInInterval
        {
            get
            {
                return _oFadeInTimer.Interval;
            }
            set
            {
                _oFadeInTimer.Interval = value;
            }
        }

        /// <summary>
        /// Das Animationsintervall für den Fade-Out in Millisekunden
        /// </summary>
        public int FadeOutInterval
        {
            get
            {
                return _oFadeOutTimer.Interval;
            }
            set
            {
                _oFadeOutTimer.Interval = value;
            }
        }
        #endregion

        #region Konstruktor und Destruktor

        /// <summary>
        /// Initialisiert eine neue Instanz der <see cref="FadeAnimationHelper"/> Klasse.
        /// </summary>
        public FadeAnimationHelper()
        {
            _oFadeInTimer = new Timer();
            _oFadeOutTimer = new Timer();

            _oFadeInTimer.Interval = 100;
            _oFadeOutTimer.Interval = 100;

            _fFadeInStep = 0.1f;
            _fFadeOutStep = 0.1f;

            _oFadeInTimer.Tick += _oFadeInTimer_Tick;
            _oFadeOutTimer.Tick += _oAnimationTimer_Tick;

            _fAlpha = 0f;
        }

        /// <summary>
        /// Führt anwendungsspezifische Aufgaben durch, die mit der Freigabe, 
        /// der Zurückgabe oder dem Zurücksetzen von nicht verwalteten Ressourcen zusammenhängen.
        /// </summary>
        public void Dispose()
        {
            if (_oFadeInTimer != null)
                _oFadeInTimer.Dispose();
            if (_oFadeOutTimer != null)
                _oFadeOutTimer.Dispose();
        }

        #endregion

        #region Methoden
        void _oFadeInTimer_Tick(object sender, EventArgs e)
        {
            _fAlpha += _fFadeInStep;
            if (_fAlpha >= 1f)
            {
                _fAlpha = 1f;
                _oFadeInTimer.Stop();
            }
            OnAnimationStep(EventArgs.Empty);
        }

        void _oAnimationTimer_Tick(object sender, EventArgs e)
        {
            _fAlpha -= _fFadeOutStep;
            if (_fAlpha <= 0f)
            {
                _fAlpha = 0f;
                _oFadeOutTimer.Stop();
            }
            OnAnimationStep(EventArgs.Empty);
        }

        /// <summary>
        /// Startet die Fade-In Animation
        /// </summary>
        public void FadeIn()
        {
            _oFadeOutTimer.Stop();
            _oFadeInTimer.Start();
        }
        /// <summary>
        /// Startet die Fade-Out Animation
        /// </summary>
        public void FadeOut()
        {
            _oFadeInTimer.Stop();
            _oFadeOutTimer.Start();
        }
        #endregion

        #region Events

        #region AnimationStep
        /// <summary>
        /// Löst das AnimationStep-Event aus.
        /// </summary>
        /// <param name="e">Eine Instanz der EventArgs-Klasse, die die Eventdaten beinhält.</param>
        protected virtual void OnAnimationStep(EventArgs e)
        {
            if (_oAnimationStep != null)
                _oAnimationStep(this, e);
        }

        private event EventHandler _oAnimationStep;
        /// <summary>
        /// Wird ausgelöst wenn die Animation ein Interval abgeschlossen hat.
        /// </summary>
        public event EventHandler AnimationStep
        {
            add
            {
                _oAnimationStep += value;
            }
            remove
            {
                _oAnimationStep -= value;
            }
        }
        #endregion

        #endregion
    }
}
 

Neue Beiträge

Zurück