As animações geralmente aumentam o apelo visual de um aplicativo ou site e melhoram o envolvimento geral dos usuários. De acordo com um estudo da Forrester Research, sites com animações bem executadas apresentam um aumento no engajamento do usuário em até 400%. Animações envolventes podem capturar a atenção dos usuários e incentivá-los a interagir mais com a plataforma. No entanto, há uma curva de aprendizado para os desenvolvedores dominarem a animação, especialmente ao trabalhar com ferramentas e técnicas de animação mais avançadas.
Compreender o Rive como um desenvolvedor sem experiência em animação pode ser relativamente fácil em comparação com outras ferramentas ou estruturas de animação. O Rive (anteriormente conhecido como Flare) foi projetado para ser amigável e acessível aos desenvolvedores, mesmo aqueles com pouca ou nenhuma experiência anterior em animação. Neste artigo, você aprenderá como criar animações simples e impressionantes do Rive com facilidade e gerenciá-las em seu aplicativo Flutter.
Introdução ao Rive🧙♂️
Uma animação simples de login interativo🚀
Conclusão🏋️♀️
Referências🧶
O Rive é uma ferramenta de animação poderosa e fácil de usar e um mecanismo de tempo de execução que permite que desenvolvedores e designers criem animações impressionantes e interativas para várias plataformas, incluindo aplicativos móveis, aplicativos da Web e jogos.
Aqui estão os principais conceitos:
Passaremos pelo processo de criar uma animação de login simples e exportá-la para nosso aplicativo Flutter. Utilizaremos o StateMachine para gerenciar a interatividade desta animação no app. No final deve ficar assim 👇🏽
Siga as etapas abaixo para configurar o elemento na prancheta do Rive:
Em seguida, amarraremos nossos ossos e os pesaremos. A ligação garante que, quando um osso se move, as partes correspondentes da superfície do personagem se movam de acordo, criando a ilusão de deformação. A ponderação, também conhecida como ponderação de vértice, envolve atribuir valores de influência (pesos) a cada vértice da malha do personagem com base em sua proximidade a ossos específicos. Vamos navegar para o caminho da forma que estaríamos vinculando. Para o pescoço, é assim que o ligamos ao osso do pescoço.
Depois de amarrar os ossos, definimos os vértices atribuindo pesos a eles. Aqui, observe que colocamos o último conjunto de vértices em 50% porque queremos que os dois ossos tenham um efeito de 50% sobre eles. Você deve usar 50%, especialmente quando os vértices definidos cobrem uma seção que afeta os dois ossos. Agora, faríamos o mesmo para o caminho do cabelo. Também vamos mudar os ossos esquerdo e direito de um para dois ossos para nos ajudar a conseguir o movimento fluido que queremos para o cabelo.
Gostaríamos de ter um efeito de piscar nesta animação, para conseguir isso, usaremos o recurso de clipe nas duas formas de olho como esta 👇🏽
Em seguida, adicionaremos rastreamento de cabeça usando restrições de translação a esse elemento porque queremos mover a cabeça durante a animação. Como é um elemento 2D, adicionar restrições de translação dará profundidade e alguma forma de efeito 3D. Selecione tudo e agrupe. Agora temos um único grupo.
Em seguida, no canto superior esquerdo, selecione a ferramenta de grupo e crie um grupo no centro da cabeça (na área do nariz). Na barra de ferramentas à direita, altere seu estilo de grupo para destino, nomeie-o ctrl_front, duplique-o e nomeie a duplicata ctrl_back.
Para o ctrl_back de destino, selecione a opção de restrições na barra de ferramentas à direita. Escolha restrições de tradução na lista de opções de restrições disponíveis. Clique no ícone antes da opção de restrição selecionada para definir suas propriedades.
Defina a força para -100 e defina seu alvo como ctrl front. Agora, quando você move o ctrl front, o ctrl back se move na direção oposta. Isso nos ajudará a definir restrições para partes do rosto que devem se mover na direção oposta, como as orelhas. Deve ficar assim 👇🏽
Agora vamos definir restrições para o resto da face. Também agruparemos os olhos (esquerdo e direito) e os ouvidos (esquerdo e direito) para nos ajudar a administrá-los melhor. Vamos definir restrições para os olhos assim 👇🏽
Grupo | força de restrição | posição de origem | Alvo |
---|---|---|---|
copos | 5% | o mesmo que ctrl_front origem | ctrl_front |
sobrancelhas | 10% | o mesmo que ctrl_front origem | ctrl_front |
ouvidos | 5% | não há necessidade de definir a origem | ctrl_back |
nariz | 5% | o mesmo que ctrl_front origem | ctrl_front |
face | 5% | o mesmo que ctrl_front origem | ctrl_front |
Não precisamos definir restrições para os lábios.
É assim que fica depois que terminamos de adicionar todas as nossas restrições 👇🏽
💃🏽 🥳 Parabéns, conseguimos preparar nosso elemento com sucesso para o tipo de animação que queremos alcançar. Ufa!!
Na barra de ferramentas à direita, clique no botão Animar para alternar para a interface de animação. Criaremos seis cronogramas de animação e amarraremos tudo com uma máquina de estado. Na linha do tempo, usando o que configuramos anteriormente com ossos e restrições, podemos definir quadros-chave para criar a animação que queremos alcançar.
A primeira animação da linha do tempo é a animação ociosa. Será o estado Idle da animação. Usaremos isso quando o elemento animado não estiver ativado.
Para esta animação inativa, criaremos uma ilusão de respiração, um leve movimento do cabelo e um piscar de olhos. Usando o osso do pescoço, os ossos do cabelo e os elementos do olho direito/esquerdo, definiremos os quadros-chave necessários em diferentes poses, o que significa que podemos definir as propriedades específicas do item selecionado nos pontos da linha do tempo. Considerando o estilo de transição de um quadro-chave para o próximo, escolheremos o tipo de interpolação que precisamos. Você pode encontrá-lo na parte inferior à direita da seção Timeline. A interpolação é mantida, linear ou curva, dependendo de como você deseja mover de um quadro-chave para o próximo. Vai ficar assim 👇🏽
No gif acima, você pode notar que nos diferentes quadros-chave na linha do tempo, definimos diferentes poses para os itens selecionados. Essa transição de um quadro-chave para o outro forma a animação. Usando este mesmo procedimento, criaremos as outras cinco linhas do tempo. Você pode clicar aqui para ver esta animação e conferir as diferentes linhas do tempo em detalhes. Fica assim 👇🏽
Chegamos à parte final deste processo de animação. Uma máquina de estado é uma maneira visual de conectar a animação. Usando a máquina de estado, podemos controlar qual animação é reproduzida com base na entrada que definimos. Podemos misturar ou mesclar duas ou mais animações de linha do tempo para que sejam reproduzidas simultaneamente. Devemos selecionar o tipo certo de entradas na máquina de estado, pois é isso que usaremos para controlar a animação no aplicativo.
Na máquina de estados, temos três tipos de entradas:
No painel Animation, clique no botão de adição e crie uma máquina de estado. Vamos nomeá-lo Login State Machine . Esse nome é importante porque é dele que precisaremos para identificar nossa máquina de estado posteriormente no código.
Siga as etapas abaixo para configurar sua máquina de estado:
Agora a animação completa na máquina de estados ficará assim 👇🏽
Confira a animação completa e a máquina de estado aqui .
Parabéns 🥳, animamos com sucesso nosso elemento e o configuramos com uma máquina de estado! Porém, antes de exportarmos o arquivo rive, vamos alterar o fundo e as cores da camisa do personagem. Vai ficar assim👇🏽
A cor de fundo é (#B581EB) e a cor da camisa do personagem é (#BD08D7)
Aqui fica o link da animação para ver tudo ao pormenor
Usaremos esta animação em nossa página de login. Crie um projeto de aplicativo Flutter e adicione a dependência do Rive ao pubspec.yaml
dependencies: rive: ^0.11.12
Além disso, adicione o arquivo Rive exportado aos recursos do projeto. Agora podemos prosseguir para criar a interface do usuário com base em nosso design. Nosso objetivo é que a animação faça o seguinte:
Primeiro definiremos algumas coisas antes da função Widget Build.
///Login details String emailCred = "[email protected]"; String passwordCred = "123456"; /// input form controller FocusNode emailFocusNode = FocusNode(); TextEditingController emailCtr = TextEditingController(); FocusNode passwordFocusNode = FocusNode(); TextEditingController passwordCtr = TextEditingController(); /// rive controller and input values StateMachineController? controller; SMIInput<bool>? check; SMIInput<double>? look; SMIInput<bool>? success; SMIInput<bool>? fail; bool isLoading = false; bool isError = false; @override void initState() { emailFocusNode.addListener(emailFocus); passwordFocusNode.addListener(passwordFocus); super.initState(); } @override void dispose() { emailFocusNode.removeListener(emailFocus); passwordFocusNode.removeListener(passwordFocus); super.dispose(); } void emailFocus() { check?.change(emailFocusNode.hasFocus); } void passwordFocus() { check?.change(passwordFocusNode.hasFocus); }
Aqui, podemos observar o seguinte:
emailFocus
e passwordFocus
, a entrada de verificação é alterada com base no booleano FocusNode.hasFocus
initState
e dispose
, vemos que os ouvintes são adicionados e removidos. Os ouvintes são usados para ouvir a mudança de foco.
Você pode verificar o código da interface do usuário e o restante do código aqui . Este trecho de código mostra como adicionar o RiveAsset:
SizedBox( height: 250, width: 250, child: RiveAnimation.asset( "assets/login_screen.riv", fit: BoxFit.fitHeight, stateMachines: const ["Login State Machine"], onInit: (artboard) { controller = StateMachineController.fromArtboard( artboard, "Login State Machine", ); if (controller == null) return; artboard.addController(controller!); check = controller?.findInput("check"); look = controller?.findInput("look"); success = controller?.findInput("success"); fail = controller?.findInput("fail"); }, ), ),
No código acima, podemos observar o seguinte:
Aqui está o código para a função de login:
void login()async{ //extract the text coming from the text fields final email = emailCtr.text; final password = passwordCtr.text; //Set loading boolean to true and delay to give an illusion of loading setState(() { isLoading = true; }); await Future.delayed( const Duration(milliseconds: 2000), ); // check if details entered is the same as the correct creditials defined if (email == emailCred && password == passwordCred) { //if correct trigger the success input and set error boolean to false success?.change(true); setState(() { isError = false; }); if(context.mounted){ // delay and navigate to home screen await Future.delayed( const Duration(seconds: 2),(){ Navigator.push(context, MaterialPageRoute(builder: (context) =>const HomeScreen())); }); } } else { // if details don't match defined credentials // set error boolean to true and trigger the fail input // set loading boolean to false setState(() { isError = true; }); fail?.change(true); } setState(() { isLoading = false; }); }
Confira o código completo aqui .
Ao fazer isso, concluímos nosso código de animação de login. Aqui está como tudo parece:
Parabéns! Concluímos esta simples animação interativa de login. Aqui está uma visão geral de tudo o que conseguimos realizar:
Seguindo este tutorial passo a passo, você pode enfrentar alguns gargalos, mas ficará mais fácil com a prática. Você pode entrar em contato comigo no Twitter ou comentar se precisar de ajuda enquanto segue este tutorial.
Confira estes tutoriais em vídeo para entender melhor a animação do Rive
Você também pode conferir o canal Rive para vários tutoriais em vídeo sobre as animações do Rive.
Publicado também aqui .