Feedback

C# - Mehrere Bilder animiert darstellen

Veröffentlicht von am 25.01.2014
(0 Bewertungen)
Diese Klasse dient zum Darstellen von Animierten Bildern auf einem Control, bei welchen die einzelnen Frames als einzelne Bilder vorhanden sind.
Das ganze wird dann wie folgt verwendet:

Neue Animation Anzeigen
using AnimationUtils;
List<Image> imgs = new List<Image>();
imgs.Add(Properties.Resources._1);
imgs.Add(Properties.Resources._2);
imgs.Add(Properties.Resources._3);
myLabel.SetBackgroundImageLayout(ImageLayout.Center);
Animator.RunAnimation("myAnimation", myLabel, imgs.ToArray(), 100, true);

Animation anhalten
Animator.StopAnimation("myAnimation");

Animation Erneut starten
Animator.RerunAnimation("myAnimation");

Alle erstellten Animationen erhalten
AnimationInfo[] AIs = Animator.GetAllAnimations();

Alle erstellten Animationen anhalten (Sollte bei Programmende aufgerufen werden)
Animator.StopAll();


Einmal erstellte Animationen bleiben erhalten und können einfach per RerunAnimation() erneut abgespielt werden. Möchte man einstellungen ändern kann man die Animation dafür einfach Überschreiben. (Bei RunAnimation() den gleichen Namen verwenden)

Beispielprojekt: https://dl.dropboxusercontent.com/s/o61yqja17arw2e7/Animator.zip?dl=1&token_hash=AAEVGtpPiPJ5Q0clxARl__B49xQD9DPTEId7bR4YhF1iKA
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

namespace AnimationUtils
{
    /// <summary>
    /// Helfer-Klasse für Animationen.
    /// </summary>
    public static class AnimationHelper
    {
        /// <summary>
        /// Setzt das BackgroundImageLayout des Controls, da dieses nicht bei allen von Control erbenden Elementen von der IntelliSence unterstützt wird.
        /// </summary>
        /// <param name="c">Das Steuerelement, dessen BackgroundImageLayout gesetzt werden soll.</param>
        /// <param name="Layout">Das BackgroundImageLayout, das dem Steuerelement zugewiesen werden soll. Verwenden Sie None, Tile, Stretch und Zoom nur dann, wenn alle Bilder gleich groß sind.</param>
        public static void SetBackgroundImageLayout(this Control c, ImageLayout Layout)
        {
            c.BackgroundImageLayout = Layout;
        }
    }

    /// <summary>
    /// Klasse zum speichern der Basis-Informationen für eine Animation.
    /// </summary>
    public class AnimationInfo
    {
        /// <summary>
        /// Control als dessen BackgroundImage die Animation angezeigt werden soll.
        /// </summary>
        public Control TargetControl = null;
        /// <summary>
        /// Die Frames der Animation.
        /// </summary>
        public Image[] Source = null;
        /// <summary>
        /// Die Verzögerung zwischen den Bildern.
        /// </summary>
        public int DelayMS = 100;
        /// <summary>
        /// Wert, der Angibt ob die Animation wiederholt werden soll.
        /// </summary>
        public bool Loop = true;
        /// <summary>
        /// Wert, der Angibt ob die Animation zur Zeit läuft. ACHTUNG: Der Wert darf durch den Programmierer nur auf False gesetzt werden, was das Programm anhällt. Das Setzen auf True darf ausschließlich durch das Programm beim Aufrufen von RunAnimation oder RerunAnimation erfolgen. Andernfalls ist die Funktionalität der Klasse nicht gewährleistet.
        /// </summary>
        public bool Running = false;
        /// <summary>
        /// Instanziert eine neue AnimationInfo.
        /// </summary>
        /// <param name="TargetControl">Control als dessen BackgroundImage die Animation angezeigt werden soll.</param>
        /// <param name="Source">Die Frames der Animation.</param>
        /// <param name="DelayMS">Die Verzögerung zwischen den Bildern in Millisekunden.</param>
        /// <param name="Loop">Wert, der Angibt ob die Animation wiederholt werden soll.</param>
        public AnimationInfo(Control TargetControl, Image[] Source, int DelayMS, bool Loop)
        {
            this.TargetControl = TargetControl;
            this.Source = Source;
            this.DelayMS = DelayMS;
            this.Loop = Loop;
        }
    }

    /// <summary>
    /// Klasse mit Funktionen zum Anzeigen einer Animation.
    /// </summary>
    public static class Animator
    {
        private static Dictionary<string, AnimationInfo> infos = new Dictionary<string, AnimationInfo>();
        
        /// <summary>
        /// Zeigt eine Animation an.
        /// </summary>
        /// <param name="Name">Name der Animation. Er wird verwendet, um aus anderen Methoden auf die Animation zuzugreifen.</param>
        /// <param name="TargetControl">Control als dessen BackgroundImage die Animation angezeigt werden soll.</param>
        /// <param name="Source">Die Frames der Animation.</param>
        /// <param name="DelayMS">Die Verzögerung zwischen den Bildern in Millisekunden.</param>
        /// <param name="Loop">Wert, der Angibt ob die Animation wiederholt werden soll.</param>
        public static void RunAnimation(string Name, Control TargetControl, Image[] Source, int DelayMS, bool Loop)
        {
            AnimationInfo ai = new AnimationInfo(TargetControl, Source, DelayMS, Loop);
            ai.Running = true;
            if (infos.Keys.Contains(Name))
                infos[Name.ToString()] = ai;
            else
                infos.Add(Name, ai);
            ParameterizedThreadStart ts = new ParameterizedThreadStart(RA);
            Thread t = new Thread(ts);
            t.Start(Name);
        }

        /// <summary>
        /// Hällt eine Animation an.
        /// </summary>
        /// <param name="Name">Name der Animation.</param>
        public static void StopAnimation(string Name)
        {
            if (infos.Keys.Contains(Name))
                infos[Name].Running = false;
        }

        /// <summary>
        /// Zeigt die Animation erneut an.
        /// </summary>
        /// <param name="name">Name der Animation.</param>
        public static void RerunAnimation(string Name)
        {
            AnimationInfo ai = infos[Name];
            RunAnimation(Name.ToString(), ai.TargetControl, ai.Source, ai.DelayMS, ai.Loop);
        }

        private static void RA(object name)
        {
            try
            {
                while (infos[name.ToString()].Running)
                {
                    foreach (Image img in infos[name.ToString()].Source)
                    {
                        infos[name.ToString()].TargetControl.BackgroundImage = img;
                        System.Threading.Thread.Sleep(infos[name.ToString()].DelayMS);
                    }
                    if (!infos[name.ToString()].Loop)
                        StopAnimation(name.ToString());
                }
            }
            catch (KeyNotFoundException)
            {
            }
            catch
            {
                throw new Exception("An error occurred while showing the animation.");
            }
        }

        /// <summary>
        /// Hällt alle Animationen an. Diese Methedo sollte vor Programmende aufgreufen bzw. mit FormClosing verknüpft werden.
        /// </summary>
        public static void StopAll()
        {
            foreach (AnimationInfo ai in GetAllAnimations())
                ai.Running = false;
        }

        /// <summary>
        /// Ermittelt alle Animationen.
        /// </summary>
        /// <returns>Die AnimationInfos zu den Animationen.</returns>
        public static AnimationInfo[] GetAllAnimations()
        {
            AnimationInfo[] allAnimations = new AnimationInfo[infos.Count];
            int i = 0;
            foreach (object o in infos.Keys)
            {
                allAnimations[i] = infos[o.ToString()];
                i++;
            }
            return allAnimations;
        }

        /// <summary>
        /// Ermittelt die Namen aller Animationen.
        /// </summary>
        /// <returns>Die Namen zu den Animationen.</returns>
        public static string[] GetAllAnimationNames()
        {
            string[] names = new string[infos.Count];
            int i = 0;
            foreach (object o in infos.Keys)
            {
                names[i] = o.ToString();
                i++;
            }
            return names;
        }
    }
}

Kommentare zum Snippet

 

Logge dich ein, um hier zu kommentieren!