"Efeito dominó" em textos com Jquery
Tags: javascript, css, beginners, tutorial
Published: 2020-04-11 23:23:44


Eu gostaria de começar a compartilhar meus conhecimentos e habilidades adquiridos com o tempo estudando e trabalhando com programação, afinal a maioria de nós desenvolvedores temos imenso prazer em compartilhar aquilo que aprendemos. 

Então, nada melhor que começar logo, e com um efeito que inicialmente achei que me daria muita dor de cabeça, mas depois que entendi o conceito, foi até bem fácil de desenvolver


# O efeito <a name="o-efeito"></a>

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3pht84cuumf5o33kj1n5.gif)

A principio, principalmente pra quem está começando, pode parecer algo muito complexo. Mas ao final desse artigo vamos descobrir que na verdade é algo bem simples de se fazer!
 
Como fazer cada letra 'girar' no próprio eixo? E mais, como fazer o efeito acontecer de modo cascata?

Parece um bicho de sete cabeças? Vamos ver que isso não passa de um pequeno e inofensivo gatinho. Mãos no código!

Para esse exemplo, vou assumir que você já tenha noção básica de HTML, CSS e JavaScript. Sobre este terceiro, mas precisamente irei usar a biblioteca JQuery, que facilita (e muito!!!!!) principalmente na hora de selecionarmos os elementos do documento.

# HTML

```html
<h1 id="titulo">
  <span>H</span>
  <span>E</span>
  <span>L</span>
  <span>L</span>
  <span>O</span>
  <span>&nbsp;</span>
  <span>W</span>
  <span>O</span>
  <span>R</span>
  <span>L</span>
  <span>D</span>
</h1>
```
A primeira ação a se fazer é separar cada letra do texto e tratá-la como um elemento independente. Para tal, basta que dentro do meu <code>h1</code> (ou qualquer tag: <code>h2, p</code> etc) eu adicione cada letra como um span. Assim o html vai tê-las como elementos independentes.

# CSS

```css
#titulo {
  width: 340px;
  margin: 0 auto;
  align-text: center;
}

#titulo span {
  display: inline-block;
  transition: .5s ease-out;
  transform: rotate3d(0,1,0,0deg);
}
```

Aqui já começamos a entender como o efeito vai acontecer.

No primeiro seletor, estamos definindo uma largura para o <code>h1</code> com classe titulo, centralizando ele horizontalmente e alinhando seu texto ao centro. Como sua largura padrão é 100%, seria um incomodo pois qualquer passada com o mouse na mesma direção do titulo, iria ativar o efeito. E nós não queremos isso.

No segundo seletor estamos definindo o comportamento padrão das nossas letras:

<code>display: inline-block;</code> precisamos defini-los assim, pois um span por default é um elemento inline e não pode ser rotacionado. Com essa linha forçamos eles para block e isso vai permitir que sejam rotacionados.

<code>transition: .5s ease-out;</code> aqui não tem muito o que explicar. Simplesmente definimos quanto tempo a transição vai durar e como ela vai acontecer.

<code>transform: rotate3d(0,1,0,0deg);</code> aqui parece confuso, mas não é: o nome da função já é autoexplicativo. Ela faz o elemento em questão girar no seu próprio eixo, sem alterar seu tamanho ou forma. Os três primeiros valores são respectivamente os eixos x, y e z, e o ultimo é a quantidade em graus que a rotação acontecerá.

```css
#titulo:hover span {
  transform: rotate3d(0,1,0,360deg);
  color: red
}
```
Nessas ultimas linhas estamos adicionando o efeito hover que vai atingir a todos os <code>span</code> dentro do elemento <code>#titulo</code> , ou seja, nossas letras. Repare que a única alteração significativa que estou fazendo é fazer o <code>rotate3d</code> fazer com que os elementos deem uma volta de 360 graus em torno do seu eixo <code>X</code> . Somente com essas linhas, já obteremos o seguinte resultado:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/pii9ga5imvuq24mqqtok.gif)

Bem legal, né ?! Mas ainda não terminamos.

# Javascript (Jquery)

Precisamos definir um delay gradativo para o nosso texto. Isso poderia ser feito no próprio css, mas tem que ser feito item por item, e se o texto for um pouco grande, não vai ser nem um pouco legal digitar isso tudo. Então apelamos ao Javascript (no caso, Jquery).

```javascript
$(document).ready(function(){

   $('#titulo').on('mouseenter', function(){ 
   
    var delay = 0

    $(this).children().each(function(){

      var el = $(this)
 
      el.css('transition-delay', delay+'s')
      
      delay += 0.03

    })
  })
})
```

O que está acontecendo aqui é simples, mas vamos por partes:

<code>$('#titulo').on('mouseenter', function()</code> Aqui estamos definindo um evento que será executado sempre que o mouse 'entrar' no campo do elemento <code>#titulo</code>

<code>$(this).children().each(function()</code> Nessa linha estamos definindo uma função que irá percorrer todos os elementos filhos de <code>#titulo</code>, ou seja, nossas letras.

```javascript
el.css('transition-delay', delay+'s')
delay += 0.03
```
Veja bem, a propriedade <code>transition-delay</code> do css, recebe um valor numérico que representa justamente o tempo que levará ate a animação iniciar.
Repare que, a cada iteração, estamos atribuindo a propriedade <code>transition-delay</code> no item em questão e logo após incrementando a variável <code>delay</code> em 0.03 (3 centésimos de segundo).

Vamos testar ?!

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/3pht84cuumf5o33kj1n5.gif)

E _voilá_! Nosso efeito está funcionando como esperado! Não foi tão difícil, foi?

![](https://media.giphy.com/media/fxsqOYnIMEefC/giphy.gif)

Aprender as principais propriedades e efeitos css e depois aprender a manipulá-los com Javascript/Jquery pode fazer com que você faça animações muito legais nas suas páginas HTML!



## Indo um pouco além

Mas somos programadores! Gostamos de desafios! Vamos pensar um pouco: se por um acaso eu precisasse que esse efeito ocorresse de forma contrária ao retirar o mouse do elemento?

Para isso, basta adicionarmos uma outra função com o evento <code>'mouseleave'</code> e ao invés de incrementar a variável <code>delay</code>, vamos decresce-la em cada iteração, veja como fica nosso Javascript:

```javascript
$(document).ready(function(){
  var totalDelay;

  $('#titulo').on('mouseenter', function(){ 
   
    var delay = 0
    obj.children().each(function(){

      var el = $(this)
    
      el.css('transition-delay', delay+'s')
      
      delay += 0.03
      
      totalDelay = delay

    })
    
  })
  
  
  $('#titulo').on('mouseleave', function(){
    var obj = $(this) 

      var delay = totalDelay

      $(this).children().each(function(){
        
        var el = $(this)
        
        el.css('transition-delay', delay+'s')
        
        delay -= 0.03

      })
  })
})
```

No final da função que já estava escrita adicionamos a linha <code>totalDelay = delay</code> justamente para guardarmos o valor em que o delay parou para o usarmos como referência.
A função que o evento <code>'mouseleave'</code> invoca faz basicamente o inverso da de cima. A diferença é que <code>delay</code> inicia com o valor guardado em <code>totalDelay</code> (que vai ser o valor da ultima iteração). E como havia dito, ela vai decrescer o valor do delay ao invés de incrementá-lo.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/no4348apyzxguejy8h5s.gif)

Essa animação é muito simples, mas assim que me deparei com a necessidade de desenvolve-la eu confesso que me assustei um pouco... Mas no fim saiu!

Vou deixar o código escrito nesse post disponível no meu <a href="https://codepen.io/claitonbarreto/pen/jObEGPy" target="_blank">Codepen</a> pra vocês usarem de referência e criarem suas próprias animações que com certeza serão muito daora!