Silverlight dispone di molti oggetti per la realizzazione di animazioni, il namespace System.Windows.Media.Animation espone una serie di classi ben progettate, ognuna di esse orientata all'interpolazione lineare e non di specifiche proprietà nel tempo, mettendo a disposizione strumenti molto flessibili per l'implementazione di svariati effetti animati.
Qualora ce ne sia necessità è possibile utilizzare l'oggetto Storyboard come timer ciclico per il calcolo manuale dei valori degli oggetti da assegnare nel tempo; con questa modalità si possono coprire quegli scenari in cui la semplice interpolazione non è sufficiente ed andare a realizzare animazioni ancora più ricche.
In questo script è illustrata la possibilità di animare lo spostamento di un oggetto seguendo una traiettoria ellittica anzichè rettilinea, l'implementazione è molto semplice e si basa sull'uso della trigonometria per il calcolo istante per istante della posizione dell'oggetto in funzione dell'angolo di rotazione.
Il primo aspetto importante è posizionare l'oggetto da animare all'interno di un Canvas in modo da avere completo controllo sul suo posizionamento assoluto:
<UserControl x:Class="_40.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="800" Height="600"> <Canvas x:Name="LayoutRoot"> <Ellipse x:Name="Ellipse1" Height="50" Width="50" Fill="Red"></Ellipse> </Canvas> </UserControl>
public partial class Page : UserControl { //Storyboard da utilizzare come timer Storyboard _anim = new Storyboard(); //centro dell'applicazione Point _center = new Point(); //velocità dell'oggetto double _speed = 0.02; //angolo di partenza double _angleCurrent = -0.5; //angolo di destinazione double _angleEnd = 2.75; //raggio orizzontale dell'arco double _radiusX = 200; //raggio verticale dell'arco double _radiusY = 100; public Page() { InitializeComponent(); //calcolo centro dell'applicazione _center.X = (this.Width / 2); _center.Y = (this.Height / 2); //posizionamento iniziale dell'oggetto da animare Ellipse1.SetValue(Canvas.LeftProperty, _center.X); Ellipse1.SetValue(Canvas.TopProperty, _center.Y); //animazione timer _anim.Duration = new Duration(TimeSpan.FromMilliseconds(10)); _anim.Completed += new EventHandler(_anim_Completed); _anim.Begin(); }
Nella classe vengono dichiarate alcune varibili per l'animazione, _radiusX e _radiusY definiscono l'ampiezza dell'ellisse attraverso due raggi; nel costruttore l'oggetto Storyboard _anim imposta la cadenza con cui vengono ricalcolati i valori attraverso il metodo _anim_Completed che viene eseguito ogni 10 millisecondi:
void _anim_Completed(object sender, EventArgs e) { //controllo angolo di rotazione if (_angleCurrent <= _angleEnd) { //calcolo posizione sull'arco double _newX = _center.X + (Math.Cos(_angleCurrent) * _radiusX); double _newY = _center.Y + (Math.Sin(_angleCurrent) * _radiusY); //posizionamento dell'oggetto Ellipse1.SetValue(Canvas.LeftProperty, _newX - (Ellipse1.Width / 2)); Ellipse1.SetValue(Canvas.TopProperty, _newY - (Ellipse1.Height / 2)); //tracciatura per visione della traiettoria Line _line1 = new Line(); _line1.Stroke = new SolidColorBrush(Color.FromArgb(100, 50, 50, 50)); _line1.StrokeThickness = 1; _line1.X1 = _newX; _line1.Y1 = _newY; _line1.X2 = _newX + 1; _line1.Y2 = _newY + 1; LayoutRoot.Children.Add(_line1); //variazione dell'angolo in funzione della velocità desiderata _angleCurrent = _angleCurrent + _speed; _anim.Begin(); } }
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.