सेरेवेलैट, एनीमेशन और अच्छे पुराने कोड-पीछे

मैंने सिल्वरलाइट में थोड़ा तराशा और उस पर कुछ ठंडा करने का फैसला किया। यह शांत, निश्चित रूप से, हिलना चाहिए और सुचारू रूप से चिकोटी चाहिए, क्योंकि हमारे पास एक वेबडानोल है या कहां है? :)। और यहां मुझे एक अच्छा सामना करना पड़ा, वास्तव में, WPF / सिल्वरलाइट में एनीमेशन सिस्टम। MSDN स्मोक्ड होने के बाद, मैंने उत्साह से XAML में एनिमेशन लिखना शुरू कर दिया। मैंने एक, दूसरा, तीसरा लिखा ... और फिर मैं उन्हें एक निश्चित क्रम में जाना चाहता था। और फिर मुझे महसूस हुआ कि XAML, संक्रमण बहुत बेमानी है। यह इंटरफेस का वर्णन करने के लिए आदर्श रूप से अनुकूल है: आप तुरंत देख सकते हैं कि यह क्या संदर्भित करता है और एक दृश्य संपादक की आवश्यकता पूरी तरह से थोड़ा कम गायब हो जाती है। लेकिन जब आप इस XAML में कुछ तर्क लिखने की कोशिश करते हैं, तो इसकी सारी गैरबराबरी दिखाई देने लगती है। Google को धूम्रपान करने के बाद, मुझे बहुत आश्चर्य हुआ कि ज्यादातर लोग सब कुछ XAML में चमकाने की कोशिश कर रहे हैं। वे शपथ लेते हैं, कोड में भ्रमित होते हैं, रोते हैं, लेकिन लिखना जारी रखते हैं। जैसे कैक्टस, चेस्लोवो वाले चूहे। और फिर मुझे नियमित सी # कोड का उपयोग करके एनिमेशन का सटीक वर्णन करने का विचार मिला। हम, बोलने के लिए, ओल्डफैग, विनएपीआई को सीधे कॉल द्वारा इंटरफ़ेस आकर्षित करते हैं, क्या वास्तव में कोई एनिमेशन हैं जो हमें डराते हैं? :)





परिणाम इस तरह के एक पोर्टेबल वर्ग एनीमेशनबाग है । यह पोर्टेबल है क्योंकि इसका उपयोग WPF और सिल्वरलाइट दोनों में बिना किसी बदलाव के किया जा सकता है।



public class AnimationItem { public event EventHandler Completed; private void OnStoryboardComplete(object sender, EventArgs e) { if (Completed != null) Completed(this, EventArgs.Empty); } private Storyboard storyboard; public Storyboard Storyboard { get { return storyboard; } set { if (storyboard != null) storyboard.Completed -= OnStoryboardComplete; storyboard = value; storyboard.Completed += OnStoryboardComplete; } } public Action BeginAction { get; set; } public Action EndAction { get; set; } } public class AnimationBag { private readonly Dictionary<string, AnimationItem> storyboards = new Dictionary<string, AnimationItem>(); public void AddAnimation(string name, DependencyObject control, string propertyName, Timeline animation, Action beginAction = null, Action endAction = null) { Storyboard board = new Storyboard(); AnimationItem item = new AnimationItem { BeginAction = beginAction, EndAction = endAction }; Storyboard.SetTarget(animation, control); Storyboard.SetTargetProperty(animation, new PropertyPath(propertyName)); board.Children.Add(animation); if (endAction != null) item.Completed += item_Completed; item.Storyboard = board; storyboards[name] = item; } private void item_Completed(object sender, EventArgs e) { KeyValuePair<string, AnimationItem> pair = storyboards.Where(x => x.Value.Equals(sender)).FirstOrDefault(); if (pair.Value != null && pair.Value.EndAction != null) pair.Value.EndAction.Invoke(); } public void StartAnimation(string name) { if (!storyboards.ContainsKey(name)) return; if (storyboards[name].BeginAction != null) storyboards[name].BeginAction.Invoke(); storyboards[name].Storyboard.Begin(); } public void StopAnimation(string name) { if (!storyboards.ContainsKey(name)) return; storyboards[name].Storyboard.Stop(); if (storyboards[name].EndAction != null) storyboards[name].EndAction.Invoke(); } public static DoubleAnimation CreateDoubleAnimation(double? to, long durationMs, double? from = null, bool repeat = false) { DoubleAnimation ret = new DoubleAnimation { To = to, From = from, Duration = new Duration(TimeSpan.FromMilliseconds(durationMs)) }; if (repeat) ret.RepeatBehavior = RepeatBehavior.Forever; return ret; } }
      
      







जैसा कि आप कोड से देख सकते हैं, कक्षा बेहद सरल है। यहाँ एक उदाहरण है।



XAML:

 <Window x:Class="Animation.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> <Rectangle Height="110" HorizontalAlignment="Left" Margin="55,71,0,0" Name="rectangle1" Stroke="Black" VerticalAlignment="Top" Width="181" Fill="#FF9D3434" /> <Button Content="Button" Height="36" HorizontalAlignment="Left" Margin="286,93,0,0" Name="button1" VerticalAlignment="Top" Width="149" Click="button1_Click" /> </Grid> </Window>
      
      







कोड-पीछे:

 public partial class MainWindow : Window { private readonly AnimationBag animations = new AnimationBag(); public MainWindow() { InitializeComponent(); InitAnimations(); } private void InitAnimations() { animations.AddAnimation( "fadeOut", rectangle1, "Opacity", AnimationBag.CreateDoubleAnimation(0, 500), null, () => animations.StartAnimation("fadeIn")); animations.AddAnimation( "fadeIn", rectangle1, "Opacity", AnimationBag.CreateDoubleAnimation(1, 500)); } private void button1_Click(object sender, RoutedEventArgs e) { animations.StartAnimation("fadeOut"); } }
      
      







कक्षा अपने आप में कुंजियों के साथ एक प्रकार का शब्दकोश है - एनीमेशन नाम और मूल्य - एनिमेशन। InitAnimations पद्धति में, नाम के साथ संग्रह में दो एनिमेशन जोड़े गए हैं, जिस पर नियंत्रण किया जाएगा, इस नियंत्रण की संपत्ति और एनीमेशन ऑब्जेक्ट पर ही कार्रवाई की जाएगी। आप इसे पेन से बना सकते हैं, या आप DoubleAnimation के लिए मौजूदा विधि में स्थैतिक सहायकों को जोड़ सकते हैं। अन्य बातों के अलावा, AddAnimation पद्धति दो प्रतिनिधियों को स्वीकार कर सकती है, जिन्हें एनीमेशन से पहले और बाद में निष्पादित किया जाएगा। उदाहरण के लिए, यहाँ एनीमेशन के बाद "fadeOut" पूरा हो गया है, "fadeIn" तुरंत शुरू होता है।



नतीजतन, हमें एक बल्कि सुविधाजनक तंत्र मिला जो हमें ओवरलोड एक्सएएमएल के किलोबाइट के बजाय कोड की एक पंक्ति के साथ एनिमेशन का वर्णन करने की अनुमति देता है।



परीक्षण परियोजनाओं के साथ स्रोत डाउनलोड करें



All Articles