Animated API

React Salvador Meetup #14

@pedrorosarioo

Quem somos nós?

Dia de conscientização sobre o autismo

Sanar: trazer conhecimento na área de saúde por um preço acessível

Núcleo em que trabalho: Residência Médica

Objetivo: ajudar o aluno de Medicina a ser aprovado na prova de residência (se tornar um especialista)

Já impactamos mais de 50 mil médicos em todo o Brasil

Existem cursos preparatórios na concorrência que chegam a valores de R$ 16 mil reais (cursos bi-anuais).

Extensivo Sanar: R$ 1800.00 (curso com duração de 1 ano)

Intensivo Sanar: R$ 1000.00 (curso com duração de 6 meses)

Somos uma empresa que incentiva a diversidade e a autonomia

Nossos produtos

Plataforma de cursos online

App de questões

E muitas dashboards para controle...

Alguns dados do nosso o app

 

48 mil usuários registrados

102 mil questões para o usuário responder

18 mil comentários em questões

Mais de 5 milhões de respostas registradas

 

E tudo isso de forma 100% gratuita

Tecnologias que utilizamos

React

React-Native

Styled components

Redux

Redux-Saga

Typescript

Graphql (Apollo)

NodeJS

Jest

MongoDB

Interessa? 

jobs.kenoby.com/sanar

Por que usar animações?

Por que usar animações?

  • Causam impacto visual
  • Melhoram de forma direta a UX
  • Facilitam o entendimento da aplicação
  • Viabilizam features
  • Trazem ao usuário a sensação de fluidez no app

"Animations are important in order to create an optimal user experience, especially in the mobile world. App users have been exposed to a lot of them already, and have become familiar with their usability and beauty. And since they have hands-on experience with them, they expect them as a given in every single app they download."

Marousas, 2018. [3]

Por que usar animações:

Dica

Por que usar animações:

Erros "elegantes"

Por que usar animações:

Indicador de ação

(ou simples distração)

Por que usar animações:

Shared Element Transitions

Por que usar animações:

Chamar a atenção

Por que usar animações:

Feature

Animações x React Native

X

Animações x React Native

SOLUÇÕES:

  • LayoutAnimation: Permite a construção de animações globais, que serão aplicadas a todos os componentes envolvidos na proxima renderização.

 

  • Animated: Oferece um controle de forma mais granular, permite manipular valores de variáveis de forma específica

Animated

  • Animações fluidas, poderosas e fáceis de manter
  • Focada em relações declarativas entre inputs e outputs
  • Voltada para o controle interativo de valores específicos
  • Consiste em construir animações por meio da manipulação de componentes e valores animados.
  • Métodos start() e stop() para iniciar e parar as animações

Animated.Value

  • Valor (classe) que será passado como parâmetro da animação
  • Pode controlar múltiplas animações de forma sincronizada
  • Só pode atender a uma função de animação por vez
  • Usar uma nova função de animação ocasiona a parada de todas as anteriores que fazem seu uso
  • Possui uma série de métodos que facilita a construção de animações

Animated.Value

Vejamos como funciona no codigo!

Configurando animações

  • Animated.timing: manipula um valor em função do tempo. 

 

  • Animated.spring: manipula um valor com base em um modelo fisico de mola simples
  • Animated.decay: começa com uma velocidade inicial e gradualmente diminui (com base em um coeficiente) até parar

Animated.timing(value, config)

Parâmetros:

  • toValue: determina qual valor o parâmetro (value) deve apresentar quando a animação chegar ao fim;
  • duration: determina em quanto tempo o parâmetro deve chegar ao valor final;
  • easing: Easing function que define a curva de animação.
    Default: Easing.inOut(Easing.ease)
  • delay: determina o tempo em ms que a animação, uma vez chamada, deve aguardar antes de iniciar.
  • useNativeDriver: determina uso de driver nativo

Descrição:

Manipula um valor em função do tempo, baseando-se em uma curva facilitadora.

Animated.timing

Animated.spring(value, config)

Parâmetros:

  • toValue: determina qual valor o parâmetro (value) deve apresentar quando a animação chegar ao fim;
  • tension: determina a velocidade inicial (tensão da mola).
    Default: 40
  • friction: controla o "bounciness" da mola (algo como o coeficiente elastico).
    Default: 7
  • speed: controla a velocidade da animação. Default: 12
  • useNativeDriver: determina uso de driver nativo
  • [...]

Descrição:

Manipula um valor com base em um modelo fisico de mola simples, ou de um oscilador harmônico.

Animated.spring

Animated.decay(value, config)

Parâmetros:

 

Descrição:

Começa com uma velocidade inicial e gradualmente diminui (com base em um coeficiente) até parar.

  • velocity: Determina a velocidade inicial (tensão da mola)
  • deceleration: Determina a desaceleração da animação
  • useNativeDriver: determina uso do driver nativo

Animated.decay

Compondo Animações

Conjunto de funções que coordenam/encadeiam animações

  • delay(time): Inicia uma animação após um determinado período (em ms).
  • parallel(Animation[], config): Inicia um conjunto de animações ao mesmo tempo. Por default se uma das animações parar antes da hora, todas param. config = { stopTogether: true }
  • sequence(Animation[]): Inicia um conjunto de animações em sequência, esperando a anterior terminar para iniciar a próxima
  • stagger(time, Animation[]): Inicia um conjunto de animações em sequência, com um delay de time ms entre uma e outra
  • loop(Animation): Faz com que uma determinada animação entre em um loop de repetição.
    config = { iterations: -1 }

Valores combinados

Conjunto de funções que realizam operações aritméticas sobre valores animados

  • add(Value, int | Value): Retorna a soma de um valor animado com um inteiro ou outro valor animado.
  • sub(Value, int | Value): Retorna a diferença de um valor animado com um inteiro ou outro valor animado.
  • multiply(Value, int | Value): Retorna o produto de um valor animado com um inteiro ou outro valor animado.
  • divide(Value, int | Value): Retorna a razão entre um valor animado com um inteiro ou outro valor animado.
  • modulo(Value, int | Value): Retorna o resto da divisão entre um valor animado com um inteiro ou outro valor animado.

Value.interpolate(config)

Função que, dado um range de entrada (inputRange) e um vetor de saída (outputRange), retorna uma interpolação linear dos dois. 

Usado quando se deseja sincronizar valores que crescem de formas muito diferentes (Ex: opacity e translateY).

Value.interpolation(config)

É possivel inserir utilizar multiplas segmentações nos vetores

Value.interpolation(config)

Suporta o uso de strings e valores em outras unidades, permitindo fazer interpolação entre inteiros e cores, ou graus (deg)

Value.interpolation(config)

Parâmetros:

  • inputRange: range de entrada (referente ao Value que invoca a função).
  • outputRange: range de saída
  • extrapolate: Como a interpolação se comporta caso o valor animado se encontre fora do range mapeado (tanto pela esquerda quanto pela direita)
  • extrapolateLeft: Como a interpolação se comporta caso o valor animado se encontre à esquerda do range mapeado (seja menor)
  • extrapolateRight: Como a interpolação se comporta caso o valor animado se encontre à direita do range mapeado (seja maior)

Animated.event([mapping], config)

 

  • Gestos como panning e scrolling, e outros eventos podem ser mapeados usando o Animated.event().
     
  • Permite fazer com que o seu valor animado se torne um listener de um determinado dado do evento

Animated.event([mapping], config)

 

Parâmetros:

  • mapping: mapeamento do evento. Por meio de configuração, navega por qualquer parâmetro do evento, e invoca a função setValue do valor animado passado (usando o parâmetro escolhido).

Animated.event([mapping], config)

 

Parâmetros de config:

  • listener: listener assíncrono opcional
     
  • useNativeDriver: determina uso do driver nativo

useNativeDriver

  • Parâmetro presente no objeto de configuração de boa parte das animações disponíveis na Animated API
     
  • Solução trazida de um esforço coletivo entre a equipe de desenvolvimento da Expo e a comunidade
     
  • Propõe resolver problemas de performance, utilizando o driver nativo (UI Thread) para cuidar das animações, sem a necessidade de usar a bridge a cada frame 

useNativeDriver

Vejamos como funciona...

useNativeDriver: false

  • JS: O driver de animação executa a função requestAnimationFrame  e atualiza o valor com base na curva de animação (para cada frame).
  • JS: Valores intermediários são calculados e passados pra um objeto/componente (node) de propriedades, que é associado à View.
  • JS: A view é atualizada usando o metodo setNativeProps.
  • View é serializada, seus dados passam pela bridge e chegam à UI Thread.
  • Native: UIView ou android.View é atualizada.

useNativeDriver: false

useNativeDriver: true

O que o useNativeDriver faz é deixar que o nativo realize a maior parte dos passos. Ao invés de passar as atualizações dos componentes pela bridge a cada frame da animação, o que se faz é passar um objeto serializado contendo todas as informações da animação, chamado nativeAnimatedModule. Desta forma, o lado nativo pode cuidar da animação diretamente na UI thread a cada frame.

useNativeDriver: true

1. Cria-se um node com as informações do valor que será animado

2. Cria-se um node de interpolação que dirá ao driver nativo como interpolar o valor

useNativeDriver: true

3. Cria um node de propriedade, informando ao driver nativo qual propriedade será atualizada na View

4. Conecta todos os nodes criados

5. Conecta as props com a view

useNativeDriver: true

5. Uma vez passados os passos anteriores, a etapa final da montagem do NativeAnimatedModule consiste em passar as informações de inicio da animação (qual curva será usada, qual valor será atualizado, quais serão os frames)

useNativeDriver: true

Nativo:

  • O driver nativo usa o CADisplayLink ou o android.view.Choreographer para extrair as informações e atualizar os valores baseando-se na curva de animação.
     
  • Valores intermediarios são calculados, passados pra um node de propriedades e associado à view nativa.
     
  • A UIView ou android.View é atualizada.

DUVIDAS?

OBRIGADO PELA PRESENÇA!!

Referencias

 

[1] Duplessis, J. Using Native Driver for Animated. Disponível em: https://facebook.github.io/react-native/blog/2017/02/14/using-native-driver-for-animated, visitado em: jun, 2019.

[2] Facebook React Native docs. Animated. Disponível em: http://facebook.github.io/react-native/docs/animated.html, visitado em: jun, 2019.

[3] Marousas, T. Animations in React Native: how to achieve great performance. Disponível em: https://medium.com/building-with-react-native/animations-in-react-native-how-to-achieve-great-performance-and-tips-1x04-44fd43996428, visitado em: mai, 2019.