Animação básica

As classes de animação .NET Multi-platform App UI (.NET MAUI) destinam-se a propriedades diferentes de elementos visuais, com uma animação básica típica alterando progressivamente uma propriedade de um valor para outro ao longo de um período de tempo.

Animações básicas podem ser criadas com métodos de extensão fornecidos pela ViewExtensions classe, que operam em VisualElement objetos:

Por padrão, cada animação levará 250 milissegundos. No entanto, uma duração para cada animação pode ser especificada ao criar a animação.

Observação

A ViewExtensions classe também fornece um método de LayoutTo extensão. No entanto, esse método destina-se a ser usado por layouts para animar transições entre estados de layout que contêm alterações de tamanho e posição.

Os métodos de extensão de animação na classe são todos assíncronos ViewExtensions e retornam um Task<bool> objeto. O valor de retorno é false se a animação for concluída e true se a animação for cancelada. Portanto, quando as operações de animação são combinadas com o operador, await torna-se possível criar animações sequenciais com métodos de animação subsequentes em execução após a conclusão do método anterior. Para obter mais informações, consulte Animações compostas.

Se houver um requisito para permitir que uma animação seja concluída em segundo plano, o await operador poderá ser omitido. Nesse cenário, os métodos de extensão de animação retornarão rapidamente depois de iniciar a animação, com a animação ocorrendo em segundo plano. Essa operação pode ser aproveitada ao criar animações compostas. Para obter mais informações, consulte Animações compostas.

No Android, as animações respeitam as configurações de animação do sistema:

  • Se as animações do sistema estiverem desativadas (por recursos de acessibilidade ou recursos do desenvolvedor), as novas animações saltarão imediatamente para seu estado concluído.
  • Se o modo de economia de energia do dispositivo for ativado enquanto as animações estiverem em andamento, as animações saltarão imediatamente para o estado final.
  • Se as durações de animação do dispositivo estiverem definidas como zero (desabilitadas) enquanto as animações estiverem em andamento e a versão da API for 33 ou maior, as animações saltarão imediatamente para o estado concluído.

Animações individuais

Cada método de extensão na classe implementa ViewExtensions uma única operação de animação que altera progressivamente uma propriedade de um valor para outro valor ao longo de um período de tempo.

Rotação

A rotação é realizada com o RotateTo método, que altera progressivamente a Rotation propriedade de um elemento:

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

Neste exemplo, uma Image instância é girada até 360 graus em 2 segundos (2000 milissegundos). O RotateTo método obtém o valor da propriedade atual Rotation do elemento para o início da animação e, em seguida, gira desse valor para seu primeiro argumento (360). Quando a animação estiver concluída, a propriedade da Rotation imagem será redefinida para 0. Isso garante que a propriedade não permaneça em 360 após a Rotation conclusão da animação, o que impediria rotações adicionais.

Observação

Além do RotateTo método, existem também RotateXTo e métodos que animam as RotationX e RotateYToRotationY propriedades, respectivamente.

Rotação relativa

A rotação relativa é realizada com o RelRotateTo método, que altera progressivamente a Rotation propriedade de um elemento:

await image.RelRotateTo(360, 2000);

Neste exemplo, uma Image instância é girada 360 graus de sua posição inicial em 2 segundos (2000 milissegundos). O RelRotateTo método obtém o valor da propriedade atual Rotation do elemento para o início da animação e, em seguida, gira desse valor para o valor mais seu primeiro argumento (360). Isso garante que cada animação será sempre uma rotação de 360 graus a partir da posição inicial. Portanto, se uma nova animação for invocada enquanto uma animação já estiver em andamento, ela começará a partir da posição atual e poderá terminar em uma posição que não seja um incremento de 360 graus.

Scaling

O dimensionamento é executado com o ScaleTo método, que altera progressivamente a Scale propriedade de um elemento:

await image.ScaleTo(2, 2000);

Neste exemplo, uma Image instância é dimensionada até o dobro de seu tamanho em 2 segundos (2000 milissegundos). O ScaleTo método obtém o valor da propriedade atual Scale do elemento para o início da animação e, em seguida, dimensiona desse valor para seu primeiro argumento. Isso tem o efeito de expandir o tamanho da imagem para o dobro de seu tamanho.

Observação

Além do ScaleTo método, existem também ScaleXTo e métodos que animam as ScaleX e ScaleYToScaleY propriedades, respectivamente.

Dimensionamento relativo

O dimensionamento relativo é executado com o RelScaleTo método, que altera progressivamente a Scale propriedade de um elemento:

await image.RelScaleTo(2, 2000);

Neste exemplo, uma Image instância é dimensionada até o dobro de seu tamanho em 2 segundos (2000 milissegundos). O RelScaleTo método obtém o valor da propriedade atual Scale do elemento para o início da animação e, em seguida, dimensiona desse valor para o valor mais seu primeiro argumento. Isso garante que cada animação sempre será uma escala de 2 a partir da posição inicial.

Dimensionamento e rotação com âncoras

As AnchorX propriedades e de um elemento visual definem o centro de dimensionamento ou rotação para as Rotation propriedades e AnchorYScale . Portanto, seus valores também afetam os RotateTo e ScaleTo métodos.

Dado um que foi colocado no centro de um Image layout, o exemplo de código a seguir demonstra girar a imagem em torno do centro do layout definindo sua AnchorY propriedade:

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

Para girar a Image ocorrência em torno do centro do layout, as AnchorX propriedades e devem ser definidas como valores relativos à largura e AnchorY altura do Image. Neste exemplo, o centro do é definido para estar no centro do Image layout e, portanto, o valor padrão AnchorX de 0,5 não requer alteração. No entanto, a AnchorY propriedade é redefinida para ser um valor da parte superior do ponto central do Image layout. Isso garante que o Image faz uma rotação completa de 360 graus em torno do ponto central do layout.

Tradução

A tradução é realizada com o TranslateTo método, que altera progressivamente as TranslationX propriedades de TranslationY um elemento:

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

Neste exemplo, a Image instância é traduzida horizontal e verticalmente em 1 segundo (1000 milissegundos). O TranslateTo método traduz simultaneamente a imagem 100 unidades independentes de dispositivo para a esquerda e 100 unidades independentes de dispositivo para cima. Isso porque o primeiro e o segundo argumentos são ambos números negativos. Fornecer números positivos traduziria a imagem para a direita e para baixo.

Importante

Se um elemento for inicialmente colocado fora da tela e, em seguida, traduzido para a tela, após a tradução, o layout de entrada do elemento permanecerá fora da tela e o usuário não poderá interagir com ele. Portanto, recomenda-se que uma visão seja apresentada em sua posição final e, em seguida, quaisquer traduções necessárias sejam realizadas.

Esmaecimento

O fading é realizado com o FadeTo método, que altera progressivamente a Opacity propriedade de um elemento:

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

Neste exemplo, a Image instância desaparece em mais de 4 segundos (4000 milissegundos). O FadeTo método obtém o valor da propriedade atual Opacity do elemento para o início da animação e, em seguida, desaparece desse valor para seu primeiro argumento.

Animações compostas

Uma animação composta é uma combinação sequencial de animações e pode ser criada com o await operador:

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

Neste exemplo, a Image instância é convertida em 6 segundos (6000 milissegundos). A tradução do Image usa cinco animações, com o await operador indicando que cada animação é executada sequencialmente. Portanto, os métodos de animação subsequentes são executados após a conclusão do método anterior.

Animações compostas

Uma animação composta é uma combinação de animações em que duas ou mais animações são executadas simultaneamente. As animações compostas podem ser criadas combinando animações aguardadas e não aguardadas:

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

Neste exemplo, a instância é dimensionada Image e girada simultaneamente ao longo de 4 segundos (4000 milissegundos). O dimensionamento do Image usa duas animações sequenciais que ocorrem ao mesmo tempo que a rotação. O RotateTo método é executado sem um await operador e retorna imediatamente, com a primeira ScaleTo animação em seguida, começando. O await operador no primeiro método atrasa o segundo ScaleTo método até que o primeiro ScaleToScaleTo método seja concluído. Neste ponto, a animação está semiconcluída e a RotateToImage será girada em 180 graus. Durante os 2 segundos finais (2000 milissegundos), a segunda ScaleTo animação e a RotateTo animação são concluídas.

Executar várias animações simultaneamente

Os Task.WhenAny métodos e podem ser usados para executar vários métodos assíncronos simultaneamente e Task.WhenAll , portanto, podem criar animações compostas. Ambos os métodos retornam um objeto e aceitam uma coleção de métodos que cada um retorna um TaskTask objeto. O Task.WhenAny método é concluído quando qualquer método em sua coleção conclui a execução, conforme demonstrado no exemplo de código a seguir:

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

Neste exemplo, o Task.WhenAny método contém duas tarefas. A primeira tarefa gira uma Image instância em 4 segundos (4000 milissegundos) e a segunda tarefa dimensiona a imagem em 2 segundos (2000 milissegundos). Quando a segunda tarefa for concluída, a chamada de Task.WhenAny método será concluída. No entanto, mesmo que o método ainda esteja em execução, o RotateTo segundo ScaleTo método pode começar.

O Task.WhenAll método é concluído quando todos os métodos em sua coleção foram concluídos, conforme demonstrado no exemplo de código a seguir:

// 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)
);

Neste exemplo, o Task.WhenAll método contém três tarefas, cada uma das quais é executada ao longo de 10 minutos. Cada Task um faz um número diferente de rotações de 360 graus – 307 rotações para , 251 rotações para , e 199 rotações para RotateXToRotateToRotateYTo. Esses valores são números primos, portanto, garantindo que as rotações não sejam sincronizadas e, portanto, não resultem em padrões repetitivos.

Cancelando animações

Um aplicativo pode cancelar uma ou mais animações com uma chamada para o método de CancelAnimations extensão:

image.CancelAnimations();

Neste exemplo, todas as animações em execução na Image instância são imediatamente canceladas.