Animazione di un oggetto con traiettoria ellittica in Silverlight 2.0

di Alessio Leoncini, in Silverlight 2.0,

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>
Successivamente tutto viene gestito nella classe di code-behind:

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();
    }
}
Il cuore del codice è il calcolo della nuova posizione dell'oggetto in funzione dell'angolo, per questa elaborazione vengono utilizzate le funzioni Coseno e Seno rispettivamente per la nuova posizione X e Y, l'effetto è il seguente:

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti

Nessuna risorsa collegata

I più letti di oggi