Bem-vindo à segunda parte da nossa série de tutoriais Framer. No último artigo , aprendemos sobre os fundamentos do uso do Framer no modo Design, bem como como escrever alguns códigos simples para dar vida aos nossos designs. Nesta peça, vamos nos concentrar no uso do Framer para criar microinterações e transições animadas. Mostraremos como criar sete interações úteis para seus protótipos.
Movimentos suaves, mudanças de estado e transições sutis ajudam o usuário a entender como usar sua interface, fornecendo feedback sobre certas ações. Freqüentemente, essas transições ecoarão análogos do mundo real (como o deslizamento de um controle de chave) ou utilizarão padrões de interação de dispositivo comuns (como toque para expandir). Neste tutorial, vamos nos concentrar nas interações que adicionam um toque final à interface para orientar a compreensão e despertar o prazer do usuário.
Dê uma olhada nos exemplos abaixo. Designers de todo o mundo estão criando essas microinterações em vários produtos.
Neste tutorial, darei uma visão geral de cada microinteração e alguns trechos de código. Estaremos utilizando várias técnicas diferentes, para que você possa escolher a que melhor se adapta ao seu produto. Não existe uma maneira “certa” de criar qualquer coisa dentro do Framer Studio - como mencionei no meu artigo anterior, o Framer oferece muita liberdade para criar da maneira que você quiser.
Você já viu interações como essas antes? Claro, você tem! Você os vê todos os dias em seu smartphone. É hora de criar o seu próprio.
O botão de ação geralmente representa a ação principal da tela atual. Às vezes, contém várias ações internas. Estaremos criando uma interação para o segundo caso. Baixe o protótipo funcional aqui: https://framer.cloud/ShBnH
Para começar, crie um botão principal em forma de círculo com um ícone dentro e dois botões menores colocados sob o botão principal. Não se esqueça de marcar todas essas camadas como interativas no modo de design (com o indicador de destino).
Crie dois estados diferentes para as camadas. Use o código abaixo para fazer os botões menores moverem-se acima do principal e girar o ícone 45 °:
button_1.states.a = y: 427 x: 246 width: 64 height: 64 button_2.states.a = y: 330 x: 246 width: 64 height: 64 icon.states.a = rotation: 45
Para fazer este protótipo animado, temos que adicionar um evento. Depois de tocar no botão de ação, altere os estados de todas as camadas:
button.onTap -> button_1.stateCycle() button_2.stateCycle() icon.stateCycle()
Neste ponto, a animação parece muito mecânica. Para adicionar um toque humano, vamos adicionar uma animação de primavera para todas as camadas:
button_1.animationOptions = curve: Spring(tension: 170, friction: 12) button_2.animationOptions = delay: 0.05 curve: Spring(tension: 170, friction: 12) icon.animationOptions = curve: Spring(tension: 250, friction: 5)
O botão de ação está pronto para usar!
As etapas a seguir permitirão que você crie sua própria interação de switch. Baixe o protótipo funcional aqui: https://framer.cloud/ieypV
Você precisará de apenas duas coisas: a própria chave, que contém pelo menos duas camadas (fundo e ponto), e algumas camadas para animar após usar a chave.
c e c ++
Você se lembra do primeiro artigo como projetar estados diretamente no Framer Studio? Projete seus estados como quiser ou use minhas configurações:
dot.states.a = x: 50 backgroundColor: 'rgba(5,106,161,1)' switch_bg.states.a = backgroundColor: 'rgba(0,136,205,1)' icon.states.a = opacity: 0 circle.states.a = x: 37 y: 183 width: 301 height: 301 circle_1.states.a = x: 20 y: 166 width: 337 height: 337
Para fazer o protótipo funcionar, temos que adicionar um evento ao switch. Depois de tocar no botão, mudaremos o estado de todas as camadas:
switch_1.onTap (event, layer) -> dot.stateCycle() switch_bg.stateCycle() circle.stateCycle() circle_1.stateCycle() icon.stateCycle()
Para tornar tudo mais natural, ajuste o tempo e o atraso de todos os estados:
dot.animationOptions = time: 0.2 switch_bg.animationOptions = time: 0.2 circle_1.animationOptions = time: 0.5 curve: Spring circle.animationOptions = time: 0.5 delay: 0.05 curve: Spring icon.animationOptions = time: 0.5 curve: Spring
Agora nosso protótipo está pronto!
Esta é uma interação típica para remover, arquivar ou salvar itens de uma lista. Deslize para a esquerda ou direita e um item será apagado. Baixe o protótipo aqui: https://framer.cloud/rzMWP
Você pode usar seu próprio design, se desejar. Basta manter a mesma estrutura das camadas. Como você pode ver na imagem acima, todos os itens da lista possuem um botão “desfazer” abaixo deles.
Para simplificar, criaremos uma interação apenas para o primeiro item da lista. Primeiro, torne o item da lista arrastável: item.draggable = true
.
Em seguida, bloqueie o eixo vertical: item.draggable.vertical = false
.
Configure as restrições da área arrastável: item.draggable.constraints
E, finalmente, defina o tamanho para o tamanho do item: size: item
.
É assim que todo o código se parece:
item.draggable = true item.draggable.vertical = false item.draggable.constraints = size: item
Agora você pode deslizar para a esquerda e para a direita e o item sempre retornará à sua posição original.
Em seguida, crie o estado para o item da lista quando ele for removido. Eu simplesmente o movi para fora da tela usando o eixo x.
item.states.a = x: -360
Finalmente, temos que criar um gatilho para iniciar a interação. Quando arrastamos o item para o lado esquerdo da tela, ele deve ser removido. O código será semelhante a este:
item.onMove -> if item.x <-70 item.stateCycle('a')
Nesse caso, estamos usando uma declaração “if”. O código acima diz basicamente, quando movemos a camada do item mais de 70px, então mudamos o estado do item para o estado 'a'. Você pode ler sobre as declarações if na documentação do Framer Studio: https://framer.com/getstarted/programming/#conditional
Estamos quase terminando essa interação. A única coisa que resta é desfazer esta ação:
item_bg.onTap -> item.stateCycle('default')
Você deve estar familiarizado com este código do tutorial anterior.
Se desejar, você pode ajustar o tempo da animação:
item.animationOptions = time: 0.75 curve: Spring
Esta é uma interação muito útil para ações que requerem carregamento ou tempos de espera para o usuário. Quando criarmos essa interação, você aprenderá como gerenciar muitas animações que estão acontecendo uma a uma. Baixe o protótipo aqui: https://framer.cloud/FxmHN
práticas recomendadas de web design para celular 2018
Crie um botão simples com quatro subcamadas: uma barra de progresso e três ícones para diferentes estados. Projetei meu botão com um ícone de upload visível, uma barra de progresso na parte inferior com largura 0 e mais dois ícones ocultos.
Todo esse protótipo pode ser feito sem escrever uma única linha de código, apenas usando os recursos de autocode do Framer.
Primeiro, adicione um evento. Iremos acionar toda a interação com um toque na camada do botão:
Este é o código que Framer escreveu para você:
button.onTap (event, layer) ->
Usaremos os recursos de autocode do Framer para projetar todas as animações:
Eu projetei quatro animações com tempos diferentes:
Aqui está o código que Framer escreveu para cada uma dessas animações:
# change progress bar width progress.animate width: 247 options: time: 1.4 curve: Bezier.ease # hide upload icon upload.animate opacity: 0.00 y: 39 options: time: 0.2 curve: Bezier.ease # show and rotate loader icon load.animate opacity: 1.00 rotation: 360 options: time: 1 curve: Bezier.ease # show and scale check icon done.animate opacity: 1.00 scale: 1.4 options: time: 0.2 curve: Bezier.ease delay: 1.00
Como você deve ter notado, não ocultamos o ícone do carregador após o término da animação. Para finalizar este protótipo, acione outra animação usando este evento: load.onAnimationEnd ->
load.animate opacity: 0.00 options: time: 0.2 curve: Bezier.ease
Quase todos os produtos com uma lista dentro dela usam esse tipo de interação. O usuário puxa para baixo a lista inteira para atualizá-la. É muito fácil de criar. Baixe o protótipo aqui: https://framer.cloud/DgMDw
Podemos pular direto para o modo de design. Precisamos de duas coisas: uma lista e um ícone de atualização. O crucial aqui é ocultar o ícone de atualização com opacidade e colocá-lo em nossa lista:
Queremos tornar nossa lista rolável. Para fazer isso, use um componente de rolagem e adicione uma camada de lista a ele:
scroll = new ScrollComponent size: Screen scrollHorizontal: false list.parent = scroll.content
Crie um estado simples para o ícone:
icon.states.a = opacity: 1
Nossa lista é rolável agora. Isso significa que quando rolamos para cima ou para baixo, todo o conteúdo da rolagem se move no eixo ‘y’. Com esse conhecimento, podemos criar um evento:
scroll.content.onMove -> if scroll.content.y > 180 icon.stateCycle('a')
Novamente, estamos usando uma declaração “if”. Se a lista for puxada para baixo (movida no eixo y) por mais de 180 pixels, iniciaremos uma ação. Neste caso, vamos animar duas camadas: a lista e o ícone de atualização.
scroll.content.onMove -> if scroll.content.y > 180 icon.stateCycle('a') list.animate y: 210 options: time: 1 curve: Bezier.ease refresh.animate rotation: 360 options: time: 1
Estamos usando “animate” para mover a lista para baixo em 210 px e girar o ícone de atualização 360 °.
llc s corp ou c corp
O protótipo está quase funcionando, mas temos que redefinir todas as camadas após a atualização da animação. Para fazer isso, usaremos um evento após o término da animação:
icon.onAnimationEnd ->
Estamos animando a rotação do ícone de atualização de volta à sua posição original e, usando o ciclo de estado, estamos redefinindo a lista e o estado de fundo do ícone:
scroll.content.onMove -> if scroll.content.y > 180 icon.stateCycle('a') list.animate y: 210 options: time: 1 curve: Bezier.ease refresh.animate rotation: 360 options: time: 1 icon.onAnimationEnd -> refresh.animate rotation: 0 list.stateCycle('default') icon.stateCycle('default')
É isso aí!
Você já percebeu que, enquanto arrasta um item para dentro de um aplicativo, sempre há algo acontecendo com o próprio item? Às vezes, o item encolhe, talvez outros itens estejam desfocados ou a opacidade muda. Vamos aprender como criar esse tipo de interação. Baixe o protótipo funcional aqui: https://framer.cloud/YstiW
Crie uma grade de blocos e verifique se eles estão dentro do elemento pai.
“for
loop ”pode parecer assustador, mas é muito simples. Se você não estiver familiarizado com for
loops, você pode ler um pouco do contexto primeiro: https://framer.com/getstarted/programming/#loops-and-arrays
como fazer chamadas assíncronas em javascript
Usaremos o for
loop para direcionar todos os blocos dentro de nossa grade:
for item in grid.subLayers
Com esta linha simples de código, você direcionou todas as camadas dentro da camada de grade.
Faça com que cada item dentro da grade seja arrastável:
for item in grid.subLayers item.draggable = true
Todos os itens devem ter um estado enquanto estão sendo arrastados. Você tem que começar a partir do código, mas posteriormente você será capaz de editar este estado no Editor de camadas:
for item in grid.subLayers item.draggable = true item.states.a = scale: 1.1 shadowBlur: 50 shadowColor: 'rgba(0,0,0,0.5)'
Temos que criar eventos para disparar diferentes estados enquanto o item está sendo arrastado. O primeiro evento irá desencadear uma ação enquanto começamos a arrastar:
for item in grid.subLayers item.draggable = true item.states.a = scale: 1.1 shadowBlur: 50 shadowColor: 'rgba(0,0,0,0.5)' item.onDragStart -> this.bringToFront() this.stateCycle('a')
Eu usei this.bringToFront()
para garantir que o item esteja sempre acima das outras camadas.
O segundo gatilho redefinirá o estado do item:
for item in grid.subLayers item.draggable = true item.states.a = scale: 1.1 shadowBlur: 50 shadowColor: 'rgba(0,0,0,0.5)' item.onDragStart -> this.bringToFront() this.stateCycle('a') item.onDragEnd -> this.sendToBack() this.stateCycle('default')
Neste ponto, temos um protótipo funcionando.
A interação sempre acontece ao longo de uma linha do tempo. É bom ajustar a linha do tempo para obter um efeito perfeito:
for item in grid.subLayers item.draggable = true item.states.a = scale: 1.1 shadowBlur: 50 shadowColor: 'rgba(0,0,0,0.5)' item.onDragStart -> this.bringToFront() this.stateCycle('a') item.onDragEnd -> this.sendToBack() this.stateCycle('default') item.animationOptions = time: 0.3 curve: Spring
Neste protótipo, usaremos técnicas mais avançadas para mostrar a você uma maneira diferente de direcionar camadas no Framer Studio, o que criará interações mais responsivas em menos tempo. Se você não está familiarizado com a codificação básica, encorajo-o a ler este artigo primeiro: https://blog.framer.com/code-less-achieve-more-with-arrays-in-framer-c43594d13d59
Para essa interação, pularemos a parte do design e usaremos um protótipo que criei especificamente para este artigo: https://framer.cloud/SZMCH
Dê uma olhada na estrutura das camadas dentro do Framer Studio:
Temos um “botão” dentro de uma “linha” no grupo “lista”. Estaremos criando uma interação nas camadas do botão, então temos que direcioná-los. Mas, primeiro, temos que encontrar todas as camadas de linha e colocá-las dentro de uma matriz:
rows = list.children buttons = []
Eu também criei uma matriz vazia para todas as camadas de 'botão': buttons = []
.
Vamos começar do “loop for”:
for i in rows buttons.push(i.children[0])
Para adicionar camadas ao array, usaremos: buttons.push()
. Isso significa que estamos colocando a primeira camada de cada grupo de “linhas” dentro de um array.
Agora vamos criar um estado para nossos botões 'curtir' e adicionar um evento a eles enquanto tocamos:
for i in buttons i.states.a = scale: 1.2 hueRotate: -80 i.onTap -> this.stateCycle() i.animationOptions = time: 0.3 curve: Spring
Você pode usar essa técnica para recriar todos os protótipos anteriores e torná-los mais complexos.
Quando você está criando microinterações, está se concentrando nos menores detalhes. Você pode criar animações acionadas por qualquer tipo de ação e torná-las absolutamente perfeitas. Lembre-se de que existem centenas de maneiras de criar o mesmo protótipo e você deve usar o método que se adapte às suas habilidades e às necessidades dos designs de seus produtos.
• • •