Condividi tramite


Animazione di base

Le classi di animazione .NET Multi-platform App UI (.NET MAUI) hanno come destinazione proprietà diverse degli elementi visivi, con un'animazione di base tipica che cambia progressivamente una proprietà da un valore a un altro in un periodo di tempo.

Le animazioni di base possono essere create con metodi di estensione forniti dalla classe ViewExtensions, che operano su oggetti VisualElement:

Per impostazione predefinita, ogni animazione richiederà 250 millisecondi. Tuttavia, è possibile specificare una durata per ogni animazione durante la creazione dell'animazione.

Nota

La classe ViewExtensions fornisce anche un metodo di estensione LayoutTo. Tuttavia, questo metodo deve essere usato dai layout per animare le transizioni tra stati di layout che contengono modifiche di dimensione e posizione.

I metodi di estensione dell'animazione nella classe ViewExtensions sono tutti asincroni e restituiscono un oggetto Task<bool>. Il valore restituito è false se l'animazione viene completata e true se l'animazione viene annullata. Pertanto, quando le operazioni di animazione vengono combinate con l'operatore await diventa possibile creare animazioni sequenziali con i metodi di animazione successivi eseguiti dopo il completamento del metodo precedente. Per altre informazioni, vedere Animazioni composte.

Se è necessario consentire il completamento di un'animazione in background, l'operatore await può essere omesso. In questo scenario, i metodi di estensione dell'animazione verranno restituiti rapidamente dopo l'avvio dell'animazione, con l'animazione che si verifica in background. Questa operazione può essere sfruttata durante la creazione di animazioni composite. Per ulteriori informazioni, consultare Animazioni Composite.

In Android le animazioni rispettano le impostazioni di animazione di sistema:

  • Se le animazioni del sistema sono disabilitate (dalle funzionalità di accessibilità o dalle funzionalità dello sviluppatore), le nuove animazioni passeranno immediatamente allo stato finito.
  • Se la modalità di risparmio energia del dispositivo viene attivata mentre le animazioni sono in corso, le animazioni passeranno immediatamente allo stato finito.
  • Se le durate di animazione del dispositivo sono impostate su zero (disabilitate) mentre le animazioni sono in corso e la versione dell'API è 33 o successiva, le animazioni passeranno immediatamente allo stato finito.

Animazioni singole

Ogni metodo di estensione nella classe ViewExtensions implementa una singola operazione di animazione che modifica progressivamente una proprietà da un valore a un altro in un periodo di tempo.

Rotazione

La rotazione viene eseguita con il metodo RotateTo, che modifica progressivamente la proprietà Rotation di un elemento:

await image.RotateTo(360, 2000);
image.Rotation = 0;

In questo esempio, un'istanza di Image viene ruotata fino a 360 gradi in 2 secondi (2000 millisecondi). Il metodo RotateTo ottiene il valore attuale della proprietà Rotation dell'elemento all'inizio dell'animazione e poi ruota da questo valore fino al suo primo argomento (360). Al termine dell'animazione, la proprietà Rotation dell'immagine viene reimpostata su 0. Ciò garantisce che la proprietà Rotation non rimanga a 360 dopo la conclusione dell'animazione, impedendo rotazioni aggiuntive.

Nota

Oltre al metodo RotateTo, sono disponibili anche metodi RotateXTo e RotateYTo che animano rispettivamente le proprietà RotationX e RotationY.

Rotazione relativa

La rotazione relativa viene eseguita con il metodo RelRotateTo, che modifica progressivamente la proprietà Rotation di un elemento:

await image.RelRotateTo(360, 2000);

In questo esempio, un'istanza di Image viene ruotata di 360 gradi dalla posizione iniziale in 2 secondi (2000 millisecondi). Il metodo RelRotateTo ottiene il valore corrente della proprietà Rotation dell'elemento all'inizio dell'animazione e quindi ruota da tale valore al valore incrementato del primo argomento (360). In questo modo ogni animazione sarà sempre una rotazione di 360 gradi dalla posizione iniziale. Pertanto, se viene richiamata una nuova animazione mentre un'animazione è già in corso, inizierà dalla posizione corrente e potrebbe terminare in una posizione diversa da un incremento di 360 gradi.

Scalare

Il ridimensionamento viene eseguito con il metodo ScaleTo, che modifica progressivamente la proprietà Scale di un elemento:

await image.ScaleTo(2, 2000);

In questo esempio, un'istanza di Image viene ingrandita a il doppio delle sue dimensioni in 2 secondi (2000 millisecondi). Il metodo ScaleTo ottiene il valore corrente della proprietà Scale dell'elemento all'inizio dell'animazione, e quindi lo scala da tale valore fino a raggiungere il suo primo argomento. Questo ha l'effetto di espandere le dimensioni dell'immagine fino al doppio delle dimensioni.

Nota

Oltre al metodo ScaleTo, sono disponibili anche metodi ScaleXTo e ScaleYTo che animano rispettivamente le proprietà ScaleX e ScaleY.

Ridimensionamento relativo

Il ridimensionamento relativo viene eseguito con il metodo RelScaleTo, che modifica progressivamente la proprietà Scale di un elemento:

await image.RelScaleTo(2, 2000);

In questo esempio, un'istanza di Image viene ingrandita fino al doppio delle sue dimensioni in 2 secondi (2000 millisecondi). Il metodo RelScaleTo ottiene il valore attuale della proprietà Scale dell'elemento al momento dell'inizio dell'animazione, e successivamente effettua una scalatura da quel valore al valore più il suo primo argomento. Ciò garantisce che ogni animazione sia sempre una scala di 2 dalla posizione iniziale.

Ridimensionamento e rotazione con ancoraggi

Le proprietà AnchorX e AnchorY di un elemento visivo impostano il centro del ridimensionamento o della rotazione per le proprietà Rotation e Scale. Pertanto, i relativi valori influiscono anche sui metodi RotateTo e ScaleTo.

Dato un Image posizionato al centro di un layout, l'esempio di codice seguente illustra la rotazione dell'immagine intorno al centro del layout impostando la relativa proprietà AnchorY:

double radius = Math.Min(absoluteLayout.Width, absoluteLayout.Height) / 2;
image.AnchorY = radius / image.Height;
await image.RotateTo(360, 2000);

Per ruotare l'istanza Image intorno al centro del layout, le proprietà AnchorX e AnchorY devono essere impostate su valori relativi alla larghezza e all'altezza del Image. In questo esempio il centro del Image viene definito come al centro del layout e quindi il valore predefinito AnchorX pari a 0,5 non richiede la modifica. Tuttavia, la proprietà AnchorY viene ridefinita in modo che sia un valore dalla parte superiore di Image al punto centrale del layout. Ciò garantisce che il Image faccia una rotazione completa di 360 gradi intorno al punto centrale del layout.

Traduzione

La traduzione viene eseguita con il metodo TranslateTo, che modifica progressivamente le proprietà TranslationX e TranslationY di un elemento:

await image.TranslateTo(-100, -100, 1000);

In questo esempio, l'istanza di Image viene traslata orizzontalmente e verticalmente in 1 secondo (1000 millisecondi). Il metodo TranslateTo converte simultaneamente l'immagine 100 unità indipendenti dal dispositivo a sinistra e 100 unità indipendenti dal dispositivo verso l'alto. Ciò è dovuto al fatto che il primo e il secondo argomento sono entrambi numeri negativi. Se si specificano numeri positivi, l'immagine viene convertita a destra e verso il basso.

Importante

Se un elemento viene inizialmente disposto fuori dalla schermata e quindi convertito sullo schermo, dopo la traduzione il layout di input dell'elemento rimane fuori schermo e l'utente non può interagire con esso. Pertanto, è consigliabile disporre una vista nella posizione finale e quindi eseguire tutte le traduzioni necessarie.

Dissolvenza

La dissolvenza viene eseguita con il metodo FadeTo, che modifica progressivamente la proprietà Opacity di un elemento:

image.Opacity = 0;
await image.FadeTo(1, 4000);

In questo esempio l'istanza di Image si dissolve in più di 4 secondi (4000 millisecondi). Il metodo FadeTo ottiene il valore corrente della proprietà Opacity dell'elemento per l'inizio dell'animazione e quindi sbiadisce da tale valore al primo argomento.

Animazioni composte

Un'animazione composta è una combinazione sequenziale di animazioni e può essere creata con l'operatore await:

await image.TranslateTo(-100, 0, 1000);    // Move image left
await image.TranslateTo(-100, -100, 1000); // Move image diagonally up and left
await image.TranslateTo(100, 100, 2000);   // Move image diagonally down and right
await image.TranslateTo(0, 100, 1000);     // Move image left
await image.TranslateTo(0, 0, 1000);       // Move image up

In questo esempio l'istanza di Image viene tradotta in oltre 6 secondi (6000 millisecondi). La traduzione del Image usa cinque animazioni, con l'operatore await che indica che ogni animazione viene eseguita in sequenza. Pertanto, i metodi di animazione successivi vengono eseguiti dopo il completamento del metodo precedente.

Animazioni composite

Un'animazione composita è una combinazione di animazioni in cui due o più animazioni vengono eseguite simultaneamente. Le animazioni composite possono essere create combinando animazioni attese e non attese:

image.RotateTo(360, 4000);
await image.ScaleTo(2, 2000);
await image.ScaleTo(1, 2000);

In questo esempio, l'istanza di Image viene ridimensionata e ruotata contemporaneamente su 4 secondi (4000 millisecondi). Il ridimensionamento della Image utilizza due animazioni sequenziali che avvengono contemporaneamente alla rotazione. Il metodo RotateTo viene eseguito senza un operatore await e restituisce immediatamente; quindi, inizia la prima animazione ScaleTo. L'operatore await nel primo metodo ScaleTo ritarda il secondo metodo ScaleTo fino al completamento del primo metodo ScaleTo. A questo punto l'animazione RotateTo viene completata a metà e il Image verrà ruotato di 180 gradi. Durante gli ultimi 2 secondi (2000 millisecondi), sia la seconda animazione ScaleTo che l'animazione RotateTo si completano.

Eseguire più animazioni contemporaneamente

I metodi Task.WhenAny e Task.WhenAll possono essere usati per eseguire più metodi asincroni contemporaneamente e pertanto possono creare animazioni composite. Entrambi i metodi restituiscono un oggetto Task e accettano una raccolta di metodi che restituiscono un oggetto Task. Il metodo Task.WhenAny viene completato quando un metodo nella raccolta completa l'esecuzione, come illustrato nell'esempio di codice seguente:

await Task.WhenAny<bool>
(
  image.RotateTo(360, 4000),
  image.ScaleTo(2, 2000)
);
await image.ScaleTo(1, 2000);

In questo esempio il metodo Task.WhenAny contiene due attività. La prima attività ruota un'istanza di Image su 4 secondi (4000 millisecondi) e la seconda attività ridimensiona l'immagine su 2 secondi (2000 millisecondi). Al termine della seconda attività, la chiamata al metodo Task.WhenAny viene completata. Tuttavia, anche se il metodo RotateTo è ancora in esecuzione, il secondo metodo ScaleTo può iniziare.

Il metodo Task.WhenAll viene completato quando tutti i metodi nella raccolta sono stati completati, come illustrato nell'esempio di codice seguente:

// 10 minute animation
uint duration = 10 * 60 * 1000;
await Task.WhenAll
(
  image.RotateTo(307 * 360, duration),
  image.RotateXTo(251 * 360, duration),
  image.RotateYTo(199 * 360, duration)
);

In questo esempio il metodo Task.WhenAll contiene tre attività, ognuna delle quali viene eseguita in più di 10 minuti. Ogni Task esegue un numero diverso di rotazioni di 360 gradi - 307 rotazioni per RotateTo, 251 rotazioni per RotateXToe 199 rotazioni per RotateYTo. Questi valori sono numeri primi, garantendo quindi che le rotazioni non siano sincronizzate e quindi non provocheranno modelli ripetitivi.

Annullamento delle animazioni

Il metodo di estensione CancelAnimations viene usato per annullare qualsiasi animazione, ad esempio rotazione, ridimensionamento, traslazione e dissolvenza, in esecuzione in un VisualElementspecifico.

image.CancelAnimations();

In questo esempio tutte le animazioni in esecuzione nell'istanza di Image vengono immediatamente annullate.