Graphics And Animation תכנות אסינכרוני, תקשורת ופיתוח אפליקציות ל-Windows 8.1 ואפליקציות ל-Windows Phone 8 Graphics And Animation
Graphics And Animation Understanding Graphical Rendering Services Shapes Brushes Transformations Drawings and Geometries Animation
Understanding Graphical Rendering Services פרק זה עוסק ביכולות בגרפיות של WPF. WPF מציגה תשתית מקיפה, ניתנת להרחבה, ובעלת גמישות רבה של יכולות גרפיות. יתרונות WPF בגרפיקה: device-independent pixel – אין תלות בחומרה - יחידה בסיסית של מדידה היא "פיקסל עצמאי" או פיקסל "לוגי" שגודלו 1/96 אינצ' ללא קשר לרזולוציית המסך בפועל, כל פיקסל מותאם ליחידות ה- DPI (Dots Per Inch ) של המערכת (פיקסל פיזי). double-precision floating-point – מערכת הקואורדינטות נמדדת באמצעות הטיפוס Double ולא Int ולכן מקבלים דיוק הרבה יותר גבוה (תכונה הנתמכת על ידי כרטיסי המסך החדישים). תמיכה ב- scRGB - שימושי ביותר באלגוריתמים לעיבוד תמונה, בשימושיים מדעיים ורפואיים. גרפיקה מתקדמת ותמיכה באנימציה, ניהול סצנות אנימציה, עיבוד תמונה, ועוד... האצת חומרה - WPF מנצלת חומרה גרפית כדי לצמצם את השימוש במעבד.
Understanding Graphical Rendering Services WPF מספקת שלוש גישות שונות לעיבוד גרפי: Shapes – ב- WPF מוגר מרחב השמותSystem.Windows.Shapes אשר מגדיר מספר קטן של מחלקות לעיבוד אובייקטים גיאומטריים דו ממדיים (מלבן, אליפסה, פוליגון, קו וכו '). מחלקות אלו הן פשוטות וקלות מאוד לשימוש Drawing and Geometries - עיבוד אובייקטים גראפיים באמצעות מחלקות נגזרות של המחלקה המופשטת System.Windows.Media.Drawing . על ידי שימוש במחלקות כגון GeometryDrawing או ImageDrawing ניתן לעבד נתונים גרפיים בשיטה שהיא לא עשירה כל כך ביכולות אולם חסכונית במשאבים. Visuals- השיטה המהירה והקלה ביותר לעיבוד מידע גרפי ב-WPF על ידי שימוש במחלקות היורשות את המחלקה System.Windows.Media.Visual. אין תמיכה ב- XAML. ההבדל בין הגישות הוא בשלושה ממדים: פשטות הפיתוח, שימוש בזיכרון וביצועים. באפליקציה גראפית מבוססת WPF יכולים להתקיים אלפי אובייקטים גראפיים ולכן לבחירת השיטה יש השפעה ניכרת. ישנם מיקרים שבאותה אפליקציה נשתמש בשלושת הגישות מקביל.
Understanding Graphical Rendering Services לדוגמה: Drawings and Geometries יותר נוחים לתכנות מודלים וקטוריים, אבל דורשים יותר קוד על מנת לתכנת אינטראקטיביות עם המשתמש. Visual – מאוד נוח ומהיר כאשר זקוקים לצייר כמות גדולה מאוד של נתונים.
Shapes השיטה הפשוטה ביותר לצייר אלמנטים דו ממדיים, בשל פשטותה מכונה גם drawing primitives. משתמשים בה במחלקות פשוטות המייצגות מלבנים, אליפסות, קווים, פוליגונים היורשות את המחלקה הבסיסית Shape . מספר קטן של מחלקות נגזרות.
Shapes מחלקת הבסיס של כל המחלקות שיש להם אספקטים ויזאליים (פקדים למשל, אובייקטים גראפיים, רכיבי Layout), מגדיר, בין השאר, את "מנוע הציור" (Rendering), איפשור לכידת אירועי עכבר (hit testing), גבולות הפקד (Bounding) ... מוגדרת במרחב השמות System.Threading, כל המחלקות היורשות ממנה הם STA – Single Thread Apartment. המחלקות היורשות אותה יכולות להתקיים רק ב- thread שבה הם נוצרו ולכן הם Thread Unsafe. מחלקת חובה עבור תמיכה ב- dependency properties. סוג שונה ומתוחכם של מאפיינים (שהוא לא בדיוק מאפיין אמיתי) שימושי במיוחד בהגדרות Style, Change Notification, Data Binding וכו'. משפר ביצועים ומאפשר הוספת פונקציונאליות תוך חיסכון במשאבים. הוספת תמיכה ביכולות בסיסיות של אלמנטים ויזואליים ללכוד או להעלות אירועים, הפצת האירוע לגורמים נוספים (Routed Event), הגדרות Layout של הפקד, והגדרת פוקוס. מחלקת הבסיס של כל הצורות הגיאומטריות מרחיב ומשכלל את היכולות של UIElement, מסויף תמיכה בסגנונות, tooltips, אנימציה, יכולות נוספות של Data Binding .....
Shapes Rectangles And Ellipse <StackPanel Width="400"> <Ellipse Fill="Yellow" Stroke="Blue" StrokeThickness="4" Height="150" Width="200" Margin="15"></Ellipse> <Rectangle Fill="Beige" Stroke="Chocolate" StrokeThickness="7" Height="150" Width="200" Margin="15" HorizontalAlignment="Left"></Rectangle> </StackPanel> <Canvas Width="400"> <Ellipse Fill="Yellow" Stroke="Blue" StrokeThickness="4" Height="150" Width="200" Canvas.Top="10" Canvas.Left="20" ></Ellipse> <Rectangle Fill="Beige" Stroke="Chocolate" StrokeThickness="7" Height="150" Width="200" Canvas.Top="100" Canvas.Left="120"></Rectangle> </Canvas> דוגמת קוד: RectangleAndEllipse
Shapes Rectangles And Ellipse { Rectangle rect = new Rectangle(); private void Window_Loaded(object sender, RoutedEventArgs e) { Rectangle rect = new Rectangle(); rect.Width = 200; rect.Height = 150; rect.Fill = new SolidColorBrush(Colors.Red); rect.Stroke = new SolidColorBrush(Colors.RoyalBlue); rect.StrokeThickness = 5; Canvas.SetTop(rect, 20); Canvas.SetLeft(rect, 30); canvas.Children.Add(rect); } דוגמת קוד: RectangleAndEllipseInCode
Shapes ViewBox מאפשר לאלמנטים גרפיים לשנות את גודלם ביחס לשינוי גודל החלון בו הם מוצבים ולשמור על קנה מידה ביניהם. <Grid> <Viewbox > <Canvas Width="525" Height="350"> <Ellipse Fill="Yellow" Stroke="Blue" StrokeThickness="4" Height="150" Width="200" Canvas.Top="10" Canvas.Left="20" ></Ellipse> <Rectangle Fill="Beige" Stroke="Chocolate" StrokeThickness="7" Height="150" Width="200" Canvas.Top="100" Canvas.Left="120"></Rectangle> </Canvas> </Viewbox> </Grid> דוגמת קוד: ViewBoxSample
Shapes Line and Polyline <Canvas > <Line Stroke="Green" StrokeThickness="3" X1="0" Y1="0" X2="380" Y2="300" ></Line> <Polyline Stroke="Blue" StrokeThickness="5" Points="10,150 30,140 50,160 70,130 90,170 110,120 130,180 150,110 170,190 190,100 210,240 230,70 250,280 " > </Polyline> </Canvas> דוגמת קוד: LineAndPolyline
Shapes Polygone <Grid> <Polygon Stroke="Blue" StrokeThickness="3" Fill="Red" Canvas.Left="10" Canvas.Top="175" FillRule="Nonzero" Points="15,250 136,35 220,200 0,125 270,60"> </Polygon> </Grid> דוגמת קוד: PolygoneSample
Brushes "מברשות" משמשות למילוי שטחים או קוים (background, foreground, border, fill ,stroke) שינוי "מברשת" גורם לצביעה אוטומטית של הצורה (אירוע מודיע לצורה על השינוי) מברשות תומכות בשקיפות (Transparency) או בשקיפות חלקית (Partial Transparency). במרחב השמות System.Windows.Media מוגדרת מחלקת הבסיס של כל המברשות, המחלקה Brush. במחלקהSystemBrushes מוגדרות אוסף של מברשות סטנדרטיות מוכנות לשימוש. ישנם 7 סוגי מברשות שונים, כל מברשת מציגה Pattern אחר, בשלב זה רלבנטיים עבורנו 4 בלבד.
Brushes SolidColorBrush צביעת צורה באמצעות צבע יחיד. LinearGradientBrush צבע מדורג, מילוי שמשתנה בהדרגה בצורה ליניארית מצבע אחד לצבע שני, או בין מספר גדול יותר של צבעים. RadialGradientBrush צבע מדורג, מילוי שמשתנה בהדרגה בצורה מעגלית מצבע אחד לצבע שני, או בין מספר גדול יותר של צבעים. ImageBrush מתבסס על תמונה כצורת המברשת. מברשות נוספות:DrawingBrush , VisualBrush, BitmapCacheBrush
Color color = Color.FromRgb(200, 13, 75); Brushes צבעים מברשות מתבססות על צבעים (ברובם), צבעים מוגדרים באמצעות המבנה Color המוגדר במרחב השמות System.Windows.Media. ב-Color מוגדרות מספר מתודות סטאטיות מעניינות: לדוגמה: Color color = Color.FromRgb(200, 13, 75); Color.Add המתודה מקבלת שני צבעים ומוסיפה את ערכי האדום, ירוק, כחול ואלפא של שני הפרמטרים ליצירת צבע אחד. Color.FromRgb מקבלת ערכי אדום, ירוק, כחול ומחזירה צבע. Color.FromArgb מקבלת ערכי אלפא, אדום, ירוק, כחול ומחזירה צבע.
Brushes המחלקה Colors מכילה פלטת צבעים מוכנה המכילה כמה מאות צבעים: המחלקה SystemColors מכילה פלטת צבעים המורכבת מצבעי המערכת:
Brushes SolidColorBrush הגדרת מברשת על ידי בחירת צבע מוכן: Rect.Fill = new SolidColorBrush(Colors.AliceBlue); הגדרת מברשת המתבססת על צבע מערכת: Rect.Fill = SystemColors.ControlBrush; קביעת מברשת על בסיס שלושת צבעי RGB: ב- XAML: int red = 10; int green = 145; int blue = 35; Rect.Fill = new SolidColorBrush(Color.FromRgb(red, green, blue)); <Rectangle Name="rect" Width="200" Height="200" Fill="Blue"></Rectangle> <Rectangle Name="rect" Width="200" Height="200" Fill="#FF2B44"></Rectangle>
Brushes LinearGradientBrush בקוד: LinearGradientBrush brush1 = new LinearGradientBrush(); brush1.StartPoint = new Point(0, 0); brush1.EndPoint = new Point(1, 1); brush1.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0)); brush1.GradientStops.Add(new GradientStop(Colors.Red, 0.25)); brush1.GradientStops.Add(new GradientStop(Colors.Blue, 0.75)); brush1.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0)); rect2.Fill = brush1;
Brushes LinearGradientBrush ב-XAML <Rectangle Width="200" Height="100"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="1,1"> <GradientStop Color="Yellow" Offset="0.0" /> <GradientStop Color="Red" Offset="0.25" /> <GradientStop Color="Blue" Offset="0.75" /> <GradientStop Color="LimeGreen" Offset="1.0" /> </LinearGradientBrush> </Rectangle.Fill> </Rectangle>
Brushes RadialGradientBrush בקוד RadialGradientBrush brush2 = new RadialGradientBrush(); brush2.GradientOrigin = new Point(0.5, 0.5); brush2.Center = new Point(0.5, 0.5); brush2.RadiusX = 0.5; brush2.RadiusY = 0.5; brush2.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0)); brush2.GradientStops.Add(new GradientStop(Colors.Red, 0.25)); brush2.GradientStops.Add(new GradientStop(Colors.Blue, 0.75)); brush2.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0)); rect3.Fill = brush2;
Brushes RadialGradientBrush ב-XAML <Rectangle Name="rect3" Width="200" Height="200" Margin="5"> <Rectangle.Fill> <RadialGradientBrush GradientOrigin="0.5,0.5" Center="0.5,0.5" RadiusX="0.5" RadiusY="0.5"> <RadialGradientBrush.GradientStops> <GradientStop Color="Yellow" Offset="0" /> <GradientStop Color="Red" Offset="0.25" /> <GradientStop Color="Blue" Offset="0.75" /> <GradientStop Color="LimeGreen" Offset="1" /> </RadialGradientBrush.GradientStops> </RadialGradientBrush> </Rectangle.Fill> </Rectangle>
Brushes טעינת התמונה מהמשאבים של התוכנית ImageBrush בקוד: מתיחת התמונה ImageBrush brush3 = new ImageBrush(); brush3.ImageSource = new BitmapImage(new Uri(@"pack://application:,,,/Assets/Smily.png")); brush3.Stretch = Stretch.None; brush3.TileMode = TileMode.Tile; brush3.Viewport = new Rect(0, 0, 0.2, 0.2); rect4.Fill = brush3; סידור ה-"אריח" הגדרת המיקום של האריח
Brushes ImageBrush ב-XAML: RadialGradientBrush brush2 = new RadialGradientBrush(); brush2.GradientOrigin = new Point(0.5, 0.5); brush2.Center = new Point(0.5, 0.5); brush2.RadiusX = 0.5; brush2.RadiusY = 0.5; brush2.GradientStops.Add(new GradientStop(Colors.Yellow, 0.0)); brush2.GradientStops.Add(new GradientStop(Colors.Red, 0.25)); brush2.GradientStops.Add(new GradientStop(Colors.Blue, 0.75)); brush2.GradientStops.Add(new GradientStop(Colors.LimeGreen, 1.0)); rect3.Fill = brush2;
Transformations Transformation – שינוי צורה, מאפשר לשנות את הדרך בה מצויר האובייקט הגראפי על ידי שינוי מערכת הקואורדינטות הקשורות לאובייקט ובאמצעות מספר מחלקות מוכנות. מחלקת הבסיס של כל מחלקות ה- Tranformation היא המחלקה Transform המוגדרת במרחב השמות System.Windows.Media. המחלקה TranslateTransform מאפשר לבצע הסטה של האובייקט הגראפי/פקד ממקומו המקורי. מגדירים את גודל ההסטה באמצעות X,Y. המיקום המקורי המיקום החדש לאחר ההזחה
Transformations TranslateTransform - XAML: בקוד: הזזת המלבן הזזת המלבן <Canvas> <Rectangle Height="250" Width="250" Stroke="Blue" StrokeThickness="1" StrokeDashArray="10" Canvas.Left="100" Canvas.Top="100"> </Rectangle> <Rectangle Height="250" Width="250" Fill="Red" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100"> <Rectangle.RenderTransform> <TranslateTransform X="150" Y="150" /> </Rectangle.RenderTransform> </Canvas> הזזת המלבן TranslateTransform transform = new TranslateTransform(-100, -100); rect.RenderTransform = transform; הזזת המלבן
Transformations סיבוב המלבן סיבוב המלבן RotateTransform מאפשר לסובב אובייקט גראפי/פקד. מגדירים את מיקום ציר הסיבוב באמצעות X,Y ואת זווית הסיבוב באמצעות Angle. XAML: קוד: <Canvas> <Rectangle Height="250" Width="250" Stroke="Blue" StrokeThickness="1" StrokeDashArray="10" Canvas.Left="100" Canvas.Top="100"> </Rectangle> <Rectangle Height="250" Width="250" Fill="Red" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100"> <Rectangle.RenderTransform> <TranslateTransform X="150" Y="150" /> </Rectangle.RenderTransform> </Canvas> סיבוב המלבן RotateTransform transform = new RotateTransform(-45, 0, 0); rect.RenderTransform = transform; סיבוב המלבן
Transformations ScaleTransform הגדלת או הקטנת אובייקט גראפי/פקד, מאפשר להגדיל ע"פ קנה מידה, למתוח או לכווץ. מיקום האובייקט לאחר ההגדלה/הקטנה על ידי X,Y. סדר גודל הקטנה/הגדלה על ידי ScaleX, ScaleY – הערך 1 מייצג 100%. XAML: <Canvas> <Rectangle Name="rect" Height="250" Width="250" Fill="Red" Stroke="Blue" StrokeThickness="2" Canvas.Left="100" Canvas.Top="100" MouseUp="Rectangle_MouseUp"> <Rectangle.RenderTransform> <ScaleTransform CenterX="50" CenterY="50" ScaleX="2" ScaleY="2" /> </Rectangle.RenderTransform> </Rectangle> <Rectangle Height="250" Width="250" Stroke="Blue" StrokeThickness="1" StrokeDashArray="10" Canvas.Left="100" Canvas.Top="100"> </Canvas> הגדלת המלבן
Transformations Code: הגדלת המלבן ScaleTransform transform = new ScaleTransform(1.5, 1.5, 100, 100); rect.RenderTransform = transform; הגדלת המלבן
Transformations SkewTransform עיקום, עיוות, פיתול; שיפוע, לכסון, עיקום. מייצר אילוזיה של 3D. <Canvas> <Rectangle Name="rect" Height="250" Width="250" Fill="Red" Stroke="Blue" StrokeThickness="2" Canvas.Left="200" Canvas.Top="200" MouseUp="Rectangle_MouseUp"> <Rectangle.RenderTransform> <SkewTransform CenterX="0" CenterY="0" AngleX="15" AngleY="0" /> </Rectangle.RenderTransform> </Rectangle> <Rectangle Height="250" Width="250" Stroke="Blue" StrokeThickness="1" StrokeDashArray="10" Canvas.Left="200" Canvas.Top="200"> </Canvas>
Drawings and Geometries המחלקה Path יורשת את המחלקה Shape (כמו כל הצורות שראינו עד כה). המחלקה Path היא קונטיינר של צורות פשוטות ומורכבות. למחלקה Path מאפיין חשוב בשם Data , המאפיין מכיל את אובייקט יחיד ממחלקה היורשת את המחלקה Geometry: RectangleGeometry EllipseGeometry PathGeometry CombinedGeometry LineGeometry GeometryGroup
Drawings and Geometries Simple Geometry <Path Fill="Yellow" Stroke="Blue" Canvas.Left="15" Canvas.Top="10" > <Path.Data> <RectangleGeometry Rect="10,10 150,80"></RectangleGeometry> </Path.Data> </Path> <Path Fill="Red" Stroke="Green" StrokeThickness="3" Canvas.Top="70" Canvas.Left="290" Height="100" Stretch="Fill" Width="160"> <EllipseGeometry RadiusX="50" RadiusY="25" Center="50,25"></EllipseGeometry> דוגמת קוד: 01PathSample
Drawings and Geometries <Path Fill="Yellow" Stroke="Blue" Canvas.Top="180" Canvas.Left="90" StrokeThickness="3" > <Path.Data> <GeometryGroup FillRule="Nonzero"> <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry> <EllipseGeometry Center="120,50" RadiusX="35" RadiusY="25"></EllipseGeometry> <LineGeometry StartPoint="10,20" EndPoint="100,130"></LineGeometry> </GeometryGroup> </Path.Data> </Path> Geometry Group דוגמת קוד: 01PathSample
Drawings and Geometries <Path Stroke="Black" StrokeThickness="1" Fill="AliceBlue" Canvas.Top="380" Canvas.Left="60"> <Path.Data> <CombinedGeometry GeometryCombineMode="Union"> <CombinedGeometry.Geometry1> <EllipseGeometry RadiusX="50" RadiusY="50" Center="75,75"/> </CombinedGeometry.Geometry1> <CombinedGeometry.Geometry2> <GeometryGroup> <EllipseGeometry RadiusX="50" RadiusY="50" Center="125,75" /> <RectangleGeometry Rect="0,0 100,100"></RectangleGeometry> </GeometryGroup> </CombinedGeometry.Geometry2> </CombinedGeometry> </Path.Data> </Path> Combined Geometry דוגמת קוד: 01PathSample
Animation באמצעות אנימציה נוכל לייצר ממשק משתמש דינאמי. שימושי מאוד במשחקים, אולם גם במערכות מידע. שני סוגים של מנגנוני אנימציה: Timer Based Animation Property Based Animation
Timer Based Animation דומה מאוד למנגנון האנימציה מבוסס טיימר כפי שהיה מקובל ב- Windows Forms. מנגנון המתבסס על המחלקה DispatcherTimer שמוגדרת במרחב השמות System.Windows.Threading. public partial class MainWindow : Window { private DispatcherTimer timer = new DispatcherTimer(); public MainWindow() InitializeComponent(); timer.Interval = new TimeSpan(0,0,0,0,100); timer.Tick += timer_Tick; timer.Start(); } void timer_Tick(object sender, EventArgs e) Canvas.SetTop(ellipse, Canvas.GetTop(ellipse) + 1); Canvas.SetLeft(ellipse, Canvas.GetLeft(ellipse) + 1); הגדרת אובייקט Timer הגדרת פרק זמן טיפול באירוע אקטיבציה של הטיימר
Property Based Animation מודל המאפשר לך להתמקד בהגדרת האנימציות מבלי לדאוג לדרך שבה הם יבוצעו. מתמקד במה ישתנה ולא באיך ישתנה. כל רכיב אנימציה משפיע על מאפיין אחד בלבד. חייבים להתאים את רכיב האנימציה לטיפוס של המאפיין שרוצים לשנות. מרחב השמות System.Windows.Media.Animation מכיל אוסף מחלקות אנימציה מבוססות מאפיינים, נותנות מענה כמעט לכל הטיפוסים עליהם נרצה לבצע אנימציה.
Property Based Animation DoubleAnimation – אנימציה למאפיינים שהם מטיפוס Double: Width, Height, Opacity ...... DoubleAnimation animation = new DoubleAnimation(); animation.From = 100; //animation.By = this.Width - 50 - btn.Width; animation.To = this.Width - 50; animation.Duration = TimeSpan.FromSeconds(3); btn1.BeginAnimation(Button.WidthProperty, animation);
Property Based Animation ColorAnimation – אנימציה למאפיינים שמבוססים על צבע: ColorAnimation animation = new ColorAnimation(); btn2.Background = new SolidColorBrush(Colors.Gray); animation.From = Colors.Gray; animation.To = Colors.Red; animation.Duration = TimeSpan.FromSeconds(3); animation.RepeatBehavior = new RepeatBehavior(3); btn2.Background.BeginAnimation(SolidColorBrush.ColorProperty, animation);
Property Based Animation אנימציה כפולה (מתבצעת בו בעת): DoubleAnimation animation1 = new DoubleAnimation(); animation1.From = 300; animation1.To = this.Width - 50; animation1.Duration = TimeSpan.FromSeconds(3); DoubleAnimation animation2 = new DoubleAnimation(); animation2.From = 50; animation2.To = 100; animation2.Duration = TimeSpan.FromSeconds(3); btn3.BeginAnimation(Button.WidthProperty, animation1); btn3.BeginAnimation(Button.HeightProperty, animation2);
Property Based Animation Storyboard מאפשר לרכז מספר פעולות אנימציה. מאפשר לשלוט על ה- Playback של האנימציה. מאפשר להגדיר אנימציה ב-XAML על ידי Trigger.
Property Based Animation הגדרת Storyboard אנימציה ראשונה storyboard = new Storyboard(); DoubleAnimation animation1 = new DoubleAnimation(); animation1.From = 300; animation1.To = this.Width - 50; animation1.Duration = TimeSpan.FromSeconds(3); Storyboard.SetTargetName(animation1, ellipse.Name); Storyboard.SetTargetProperty(animation1, new PropertyPath(Ellipse.WidthProperty)); storyboard.Children.Add(animation1); DoubleAnimation animation2 = new DoubleAnimation(); animation2.BeginTime = TimeSpan.FromSeconds(3); animation2.From = 150; animation2.To = 300; animation2.Duration = TimeSpan.FromSeconds(3); Storyboard.SetTargetName(animation2, ellipse.Name); Storyboard.SetTargetProperty(animation2, new PropertyPath(Ellipse.HeightProperty)); storyboard.Children.Add(animation2); storyboard.Begin(ellipse); Storyboard הגדרת אובייקט יעד הגדרת מאפיין יעד אנימציה שניה
Property Based Animation <Ellipse Name="ellipse" Width="300" Height="300" > <Ellipse.Fill> <SolidColorBrush x:Name="brush" Color="Red"/> </Ellipse.Fill> <Ellipse.Triggers> <EventTrigger RoutedEvent="Window.Loaded"> <BeginStoryboard> <Storyboard RepeatBehavior="Forever"> <ColorAnimation Storyboard.TargetName="brush" Storyboard.TargetProperty="Color" From="Red" To="Green" Duration="0:0:1" BeginTime="0:0:0"/> Storyboard.TargetProperty="Color" From="Green" To="Blue" Duration="0:0:1" BeginTime="0:0:1"/> Storyboard.TargetProperty="Color" From="Blue" To="Yellow" Duration="0:0:1" BeginTime="0:0:2"/> Storyboard.TargetProperty="Color" From="Yellow" To="Red" Duration="0:0:1" BeginTime="0:0:3"/> </Storyboard> </BeginStoryboard> </EventTrigger> </Ellipse.Triggers> </Ellipse> Storyboard With XAML
את הסילבוס, חומרים, מצגות ניתן להוריד ב: www.corner.co.il