Agora iremos começar a adicionar o JavaScript para nosso projeto. Mas antes, vou inserir mais um pouco de CSS.
Relembrando nosso HTML e nosso CSS:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Exercício para respiração</title>
</head>
<body>
<h1>Exercício para respiração</h1>
<div class="container" id="container">
<div class="circle"></div>
<p id="text">Inspire...</p>
<div class="pointer-container">
<span class="pointer"></span>
</div>
<div class="gradient-circle"></div>
</div>
<script src="main.js"></script>
</body>
</html>
* {
box-sizing: border-box;
}
body {
color: #fff;
font-family: 'Quicksand', sans-serif;
background: #224941 url('./img/bg5.jpg') no-repeat center center/cover;
min-height: 100vh;
overflow: hidden;
display: flex;
flex-direction: column;
align-items: center;
margin: 0;
}
.container {
display: flex;
align-items: center;
justify-content: center;
margin: auto;
height: 300px;
width: 300px;
position: relative;
transform: scale(1);
}
.circle {
background-color: #010f1c;
height: 100%;
width: 100%;
position: absolute;
top: 0;
left: 0;
z-index: -1;
border-radius: 50%;
}
.gradient-circle {
background: conic-gradient(
#55b7a4 0%,
#4ca493 40%,
#fff 40%,
#fff 60%,
#336d62 60%,
#2a5b22 100%
);
width: 320px;
height: 320px;
position: absolute;
z-index: -2;
border-radius: 50%;
}
.pointer {
background-color: #fff;
border-radius: 50%;
height: 20px;
width: 20px;
display: block;
}
.pointer-container {
position: absolute;
top: -40px;
width: 20px;
height: 190px;
animation: rotation 7.5s linear forwards infinite;
transform-origin: bottom center;
}
@keyframes rotation {
from {
transform: rotate(0deg)
}
to {
transform: rotate(360deg)
}
}
Preciso inserir um código de estilo específico para quando eu quiser que meu círculo cresça e diminua de tamanho. Vou criar uma animação que vai ser "engatilhada" quando nosso container também tiver a classe "grow", e outra animação que vai ser engatilhada quando nosso container também tiver a classe "shrink".
A princípio, vamos fazer com que quando nosso container também tenha uma classe chamada grow, uma animação também chamada grow seja criada, que irá durar 3 segundos, que é o tempo de inspiração que iremos criar, que também terá os valores linear e forwards que vimos ontem, mas não terá o valor infinite porque a animação não será infinita. Gerando o keyframe que vai comandar como essa animação irá ocorrer, iremos fazer um transform que irá mudar o tamanho do círculo, então irei usar a função scale, que irá de um valor 1, que é o default, para um valor 1.2:
.container.grow {
animation: grow 3s linear forwards;
}
@keyframes grow {
from {
transform: scale(1);
}
to {
transform: scale(1.2);
}
}
Para testar, vamos alterar nosso HTML e inserir meio "hard-coded" a classe grow em container para vermos a mudança:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style2.css" />
<title>Exercício para respiração</title>
</head>
<body>
<h1>Exercício para respiração</h1>
<!-- Mudança feita na linha abaixo -->
<div class="container grow" id="container">
<!-- Mudança feita na linha acima -->
<div class="circle"></div>
<p id="text">Inspire...</p>
<div class="pointer-container">
<span class="pointer"></span>
</div>
<div class="gradient-circle"></div>
</div>
<script src="main2.js"></script>
</body>
</html>
Salvando e abrindo nosso site agora vocês verão o círculo principal crescer (infelizmente aqui no site os gifs não estão sendo mostrados de forma animada e pra eu não gravar um vídeo e subir no youtube pra cada passo, espero que vocês tentem fazer e vejam as alterações).
Vamos fazer o mesmo agora criando uma classe shrink que irá determinar a diminuição do círculo, de um scale(1.2) para um scale(1) em 3 segundos também.
.container.shrink {
animation: shrink 3s linear forwards;
}
@keyframes shrink {
from {
transform: scale(1.2);
}
to {
transform: scale(1);
}
}
Podemos ver o círculo diminuindo adicionando a classe de forma hard-coded no HTML também, em container:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style2.css" />
<title>Exercício para respiração</title>
</head>
<body>
<h1>Exercício para respiração</h1>
<!-- Mudança feita na linha abaixo -->
<div class="container shrink" id="container">
<!-- Mudança feita na linha acima -->
<div class="circle"></div>
<p id="text">Inspire...</p>
<div class="pointer-container">
<span class="pointer"></span>
</div>
<div class="gradient-circle"></div>
</div>
<script src="main2.js"></script>
</body>
</html>
Testando essa animação, podemos remover a classe shrink de container pois quem vai adicionar essa classe e a classe grow será o JavaScript.
Ainda não falei nada de JavaScript manipulando o DOM que é a árvore do HTML, ainda estamos chegando nessa parte nos chats semanais, mas hoje vamos ver uma palhinha disso.
Abrindo o arquivo main.js, vamos capturar os elementos do HTML em nosso JavaScript. Só preciso manipular o círculo e o texto dentro do círculo, então vamos capturar o container e o parágrafo. Ambos têm id, que respectivamente é container e text, então vamos capturá-los usando a função de document no JavaScript chamada getElementById:

Pra vermos como podemos alterar os elementos do DOM usando JavaScript, vamos apagar o texto dentro do parágrafo:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style2.css" />
<title>Exercício para respiração</title>
</head>
<body>
<h1>Exercício para respiração</h1>
<div class="container" id="container">
<div class="circle"></div>
<!-- Mudança feita na linha abaixo -->
<p id="text"></p>
<!-- Mudança feita na linha acima -->
<div class="pointer-container">
<span class="pointer"></span>
</div>
<div class="gradient-circle"></div>
</div>
<script src="main2.js"></script>
</body>
</html>
Nosso círculo agora não apresenta mais texto:

Mas eu posso mudar esse texto usando JavaScript (a partir de agora os códigos serão em imagens pois de alguma forma o código JS tava conflitando com alguma ferramenta de proteção aqui do site e tava me impedindo de postar o tópico):

Observando nosso site agora:

É manipulando o innerText, ou texto interno, da nossa variável text que iremos criar o passo a passo de inspirar, segurar a respiração e expirar.
Vamos criar uma nova variável que vai definir o tempo total de cada ciclo nosso. O ciclo total vai durar 7,5 segundos, ou 7500 milissegundos que é a unidade que o JavaScript usa pra definir o tempo e iremos precisar desse tempo em milissegundos mais pra frente.

Vamos criar um tempo para a respiração (tanto inspiração quanto expiração) que será de 3 segundos, ou (7,5 / 5) * 2:

O tempo de segurar a respiração vai ser de 1,5 segundos, ou 7,5 dividido por 5:

Podemos conferir esses valores em nosso console, dando um console.log nesses valores:

Para abrir nosso console, no Google Chrome basta pressionar ctrl + shift + j:

Percebam agora como os valores no código JavaScript batem com os valores das animações grow e shrink. O breatheTime é 3 segundos, que é o tempo das duas animações. Se houver alguma mudança no JS que não seja feita também no CSS o aplicativo vai ficar descompassado e não irá funcionar bem.
Agora iremos começar a preparar a animação sendo comandada dinamicamente pelo JavaScript, mas como irei falar de muita coisa nova vou deixar pra continuar amanhã pra não ficar muito pesado este tópico.