├── README.md
├── base
├── index.html
└── style.css
└── desafios
├── 01
├── index.html
└── style.css
├── 02
├── index.html
└── style.css
├── 03
├── index.html
├── script.js
└── style.css
├── 04
├── index.html
├── script.js
└── style.css
├── 05
├── index.html
├── script.js
└── style.css
├── 06
├── index.html
├── script.js
└── style.css
└── 07
├── index.html
├── script.js
└── style.css
/README.md:
--------------------------------------------------------------------------------
1 | # Formulário animado com JS puro e CSS Animation
2 |
3 | ## Desafios
4 |
5 | - [x] Fazer o formulário aparecer, suavemente, quando a página abrir
6 | - [x] Fazer os campos aparecem da esquerda pra direita, suavizando a entrada e fazendo-os entrar em momentos distintos
7 | - [x] Quando clicar em Login, fazer o formulário sair da tela, indo para baixo
8 | - [x] Remover formulário do html e não mostrar rolagem enquanto o formulário está saindo da tela
9 | - [x] Adicionar um efeito diferente de timing para a saída do formulário
10 | - [x] Fazer o formulário dizer não-não (vibrar) caso haja campos vazios.
11 | - [x] Criar alguns quadrados animados (que fiquem girando) e que saem de baixo da tela (fora do campo de visão) e vão para cima da tela (que saia do campo de visão também). _Detalhes_: Deve ter tamanhos diferentes, sairem em momentos diferentes, terem timing diferente, animação contínua.
12 |
13 | ## Animation
14 |
15 |
16 | 8 propriedades:
17 |
18 | - animation-name: animationname;
19 | - animation-duration: 2s;
20 | - animation-delay: 3s;
21 | - animation-fill-mode: none;
22 | - animation-play-state: running;
23 | - animation-timing-function: ease;
24 | - animation-direction: reverse;
25 | - animation-iteration-count: infinite;
26 |
27 | ```css
28 | @keyframes animationname {
29 | 0% {
30 |
31 | }
32 |
33 | 100%{
34 |
35 | }
36 | }
37 | ```
38 |
39 |
40 | podemos ter múltiplas animações no mesmo elemento
41 |
42 | ```css
43 | .animate {
44 | animation: slide-top 2s, bounce 1s, fade 0.2s;
45 | }
46 | ```
47 |
48 |
49 | ## References
50 |
51 | [CSS Animation Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Using_CSS_animations)
52 |
53 | [Animation Timing Docs](https://developer.mozilla.org/en-US/docs/Web/CSS/animation-timing-function)
54 |
55 | [Site para criar animações](http://animista.net/play/basic/scale-up)
56 |
57 | [Site para criar cubic Bézier timming](https://matthewlein.com/tools/ceaser)
--------------------------------------------------------------------------------
/base/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/base/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | html,
8 | body {
9 | height: 100vh;
10 | }
11 |
12 | body {
13 | background-color: #7159c1;
14 | font-family: Roboto, Arial, sans-serif;
15 | }
16 |
17 | section {
18 | display: flex;
19 | flex-direction: column;
20 | justify-content: center;
21 | align-items: center;
22 | }
23 |
24 | h1 {
25 | font-size: 32px;
26 | letter-spacing: 1px;
27 | margin: 20px 0;
28 | color: white;
29 | }
30 |
31 | form {
32 | margin: 20px 0;
33 | background-color: white;
34 | padding: 30px 25px;
35 | border-radius: 5px;
36 | }
37 |
38 | form .input-block {
39 | margin-bottom: 20px;
40 | }
41 |
42 | form .input-block label {
43 | font-size: 14px;
44 | color: darkslateblue;
45 | }
46 |
47 | form .input-block input {
48 | width: 100%;
49 | display: block;
50 | margin-top: 8px;
51 | padding: 7px;
52 | font-size: 16px;
53 | color: #7159c1;
54 | border-radius: 2px;
55 | border: 1px solid #ccddef;
56 | outline-color: #7159c1;
57 | }
58 |
59 | form .btn-login {
60 | display: block;
61 | min-width: 120px;
62 | border: none;
63 | background-color: #7159c1;
64 | color: white;
65 | border-radius: 25px;
66 | margin: auto;
67 | padding: 7px;
68 | }
69 |
--------------------------------------------------------------------------------
/desafios/01/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/desafios/01/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | html,
8 | body {
9 | height: 100vh;
10 | }
11 |
12 | body {
13 | background-color: #7159c1;
14 | font-family: Roboto, Arial, sans-serif;
15 | }
16 |
17 | section {
18 | display: flex;
19 | flex-direction: column;
20 | justify-content: center;
21 | align-items: center;
22 | }
23 |
24 | h1 {
25 | font-size: 32px;
26 | letter-spacing: 1px;
27 | margin: 20px 0;
28 | color: white;
29 | }
30 |
31 | form {
32 | margin: 20px 0;
33 | background-color: white;
34 | padding: 30px 25px;
35 | border-radius: 5px;
36 | }
37 |
38 | form .input-block {
39 | margin-bottom: 20px;
40 | }
41 |
42 | form .input-block label {
43 | font-size: 14px;
44 | color: darkslateblue;
45 | }
46 |
47 | form .input-block input {
48 | width: 100%;
49 | display: block;
50 | margin-top: 8px;
51 | padding: 7px;
52 | font-size: 16px;
53 | color: #7159c1;
54 | border-radius: 2px;
55 | border: 1px solid #ccddef;
56 | outline-color: #7159c1;
57 | }
58 |
59 | form .btn-login {
60 | display: block;
61 | min-width: 120px;
62 | border: none;
63 | background-color: #7159c1;
64 | color: white;
65 | border-radius: 25px;
66 | margin: auto;
67 | padding: 7px;
68 | }
69 |
70 | /* APARIÇÃO DO FORM */
71 |
72 | form {
73 | animation-name: fade;
74 | animation-duration: 500ms;
75 | }
76 |
77 | @keyframes fade {
78 | from {
79 | opacity: 0;
80 | transform: scale(0.9);
81 | }
82 | to {
83 | opacity: 1;
84 | transform: scale(1);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/desafios/02/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/desafios/02/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | html,
8 | body {
9 | height: 100vh;
10 | }
11 |
12 | body {
13 | background-color: #7159c1;
14 | font-family: Roboto, Arial, sans-serif;
15 | }
16 |
17 | section {
18 | display: flex;
19 | flex-direction: column;
20 | justify-content: center;
21 | align-items: center;
22 | }
23 |
24 | h1 {
25 | font-size: 32px;
26 | letter-spacing: 1px;
27 | margin: 20px 0;
28 | color: white;
29 | }
30 |
31 | form {
32 | margin: 20px 0;
33 | background-color: white;
34 | padding: 30px 25px;
35 | border-radius: 5px;
36 | }
37 |
38 | form .input-block {
39 | margin-bottom: 20px;
40 | }
41 |
42 | form .input-block label {
43 | font-size: 14px;
44 | color: darkslateblue;
45 | }
46 |
47 | form .input-block input {
48 | width: 100%;
49 | display: block;
50 | margin-top: 8px;
51 | padding: 7px;
52 | font-size: 16px;
53 | color: #7159c1;
54 | border-radius: 2px;
55 | border: 1px solid #ccddef;
56 | outline-color: #7159c1;
57 | }
58 |
59 | form .btn-login {
60 | display: block;
61 | min-width: 120px;
62 | border: none;
63 | background-color: #7159c1;
64 | color: white;
65 | border-radius: 25px;
66 | margin: auto;
67 | padding: 7px;
68 | }
69 |
70 | /* APARIÇÃO DO FORM */
71 | form {
72 | overflow: hidden;
73 | animation: fade 0.2s;
74 | }
75 |
76 | form .input-block:nth-child(1) {
77 | animation: move 500ms;
78 | }
79 |
80 | form .input-block:nth-child(2) {
81 | animation: move 400ms;
82 | animation-delay: 100ms;
83 | animation-fill-mode: backwards;
84 | }
85 |
86 | form .btn-login {
87 | animation: move 400ms;
88 | animation-delay: 250ms;
89 | animation-fill-mode: backwards;
90 | }
91 |
92 | @keyframes move {
93 | from {
94 | opacity: 0;
95 | transform: translateX(-35%);
96 | }
97 | to {
98 | opacity: 1;
99 | transform: translateX(0%);
100 | }
101 | }
102 |
103 | @keyframes fade {
104 | from {
105 | opacity: 0;
106 | transform: scale(0.9);
107 | }
108 | to {
109 | opacity: 1;
110 | transform: scale(1);
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/desafios/03/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/desafios/03/script.js:
--------------------------------------------------------------------------------
1 | const btnLogin = document.querySelector(".btn-login");
2 | const form = document.querySelector("form");
3 |
4 | btnLogin.addEventListener("click", event => {
5 | event.preventDefault();
6 | form.classList.add("form-hide");
7 | });
8 |
--------------------------------------------------------------------------------
/desafios/03/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | html,
8 | body {
9 | height: 100vh;
10 | }
11 |
12 | body {
13 | background-color: #7159c1;
14 | font-family: Roboto, Arial, sans-serif;
15 | }
16 |
17 | section {
18 | display: flex;
19 | flex-direction: column;
20 | justify-content: center;
21 | align-items: center;
22 | }
23 |
24 | h1 {
25 | font-size: 32px;
26 | letter-spacing: 1px;
27 | margin: 20px 0;
28 | color: white;
29 | }
30 |
31 | form {
32 | margin: 20px 0;
33 | background-color: white;
34 | padding: 30px 25px;
35 | border-radius: 5px;
36 | }
37 |
38 | form .input-block {
39 | margin-bottom: 20px;
40 | }
41 |
42 | form .input-block label {
43 | font-size: 14px;
44 | color: darkslateblue;
45 | }
46 |
47 | form .input-block input {
48 | width: 100%;
49 | display: block;
50 | margin-top: 8px;
51 | padding: 7px;
52 | font-size: 16px;
53 | color: #7159c1;
54 | border-radius: 2px;
55 | border: 1px solid #ccddef;
56 | outline-color: #7159c1;
57 | }
58 |
59 | form .btn-login {
60 | display: block;
61 | min-width: 120px;
62 | border: none;
63 | background-color: #7159c1;
64 | color: white;
65 | border-radius: 25px;
66 | margin: auto;
67 | padding: 7px;
68 | }
69 |
70 | /* APARIÇÃO DO FORM */
71 | form {
72 | overflow: hidden;
73 | animation: fade 0.2s;
74 | }
75 |
76 | form .input-block:nth-child(1) {
77 | animation: move 500ms;
78 | }
79 |
80 | form .input-block:nth-child(2) {
81 | animation: move 400ms;
82 | animation-delay: 100ms;
83 | animation-fill-mode: backwards;
84 | }
85 |
86 | form .btn-login {
87 | animation: move 400ms;
88 | animation-delay: 250ms;
89 | animation-fill-mode: backwards;
90 | }
91 |
92 | @keyframes move {
93 | from {
94 | opacity: 0;
95 | transform: translateX(-35%);
96 | }
97 | to {
98 | opacity: 1;
99 | transform: translateX(0%);
100 | }
101 | }
102 |
103 | @keyframes fade {
104 | from {
105 | opacity: 0;
106 | transform: scale(0.9);
107 | }
108 | to {
109 | opacity: 1;
110 | transform: scale(1);
111 | }
112 | }
113 |
114 | /* Quando clicar no botão, sumir com o form */
115 | .form-hide {
116 | animation: down 500ms forwards;
117 | }
118 |
119 | @keyframes down {
120 | from {
121 | transform: translateY(0);
122 | }
123 | to {
124 | transform: translateY(100vh);
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/desafios/04/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/desafios/04/script.js:
--------------------------------------------------------------------------------
1 | const btnLogin = document.querySelector(".btn-login");
2 | const form = document.querySelector("form");
3 |
4 | btnLogin.addEventListener("click", event => {
5 | event.preventDefault();
6 | form.classList.add("form-hide");
7 | });
8 |
9 | form.addEventListener("animationstart", event => {
10 | if (event.animationName === "down") {
11 | document.querySelector("body").style.overflow = "hidden";
12 | }
13 | });
14 |
15 | form.addEventListener("animationend", event => {
16 | if (event.animationName === "down") {
17 | form.style.display = "none";
18 | document.querySelector("body").style.overflow = "none";
19 | }
20 | });
21 |
--------------------------------------------------------------------------------
/desafios/04/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | html,
8 | body {
9 | height: 100vh;
10 | }
11 |
12 | body {
13 | background-color: #7159c1;
14 | font-family: Roboto, Arial, sans-serif;
15 | }
16 |
17 | section {
18 | display: flex;
19 | flex-direction: column;
20 | justify-content: center;
21 | align-items: center;
22 | }
23 |
24 | h1 {
25 | font-size: 32px;
26 | letter-spacing: 1px;
27 | margin: 20px 0;
28 | color: white;
29 | }
30 |
31 | form {
32 | margin: 20px 0;
33 | background-color: white;
34 | padding: 30px 25px;
35 | border-radius: 5px;
36 | }
37 |
38 | form .input-block {
39 | margin-bottom: 20px;
40 | }
41 |
42 | form .input-block label {
43 | font-size: 14px;
44 | color: darkslateblue;
45 | }
46 |
47 | form .input-block input {
48 | width: 100%;
49 | display: block;
50 | margin-top: 8px;
51 | padding: 7px;
52 | font-size: 16px;
53 | color: #7159c1;
54 | border-radius: 2px;
55 | border: 1px solid #ccddef;
56 | outline-color: #7159c1;
57 | }
58 |
59 | form .btn-login {
60 | display: block;
61 | min-width: 120px;
62 | border: none;
63 | background-color: #7159c1;
64 | color: white;
65 | border-radius: 25px;
66 | margin: auto;
67 | padding: 7px;
68 | }
69 |
70 | /* APARIÇÃO DO FORM */
71 | form {
72 | overflow: hidden;
73 | animation: fade 0.2s;
74 | }
75 |
76 | form .input-block:nth-child(1) {
77 | animation: move 500ms;
78 | }
79 |
80 | form .input-block:nth-child(2) {
81 | animation: move 400ms;
82 | animation-delay: 100ms;
83 | animation-fill-mode: backwards;
84 | }
85 |
86 | form .btn-login {
87 | animation: move 400ms;
88 | animation-delay: 250ms;
89 | animation-fill-mode: backwards;
90 | }
91 |
92 | @keyframes move {
93 | from {
94 | opacity: 0;
95 | transform: translateX(-35%);
96 | }
97 | to {
98 | opacity: 1;
99 | transform: translateX(0%);
100 | }
101 | }
102 |
103 | @keyframes fade {
104 | from {
105 | opacity: 0;
106 | transform: scale(0.9);
107 | }
108 | to {
109 | opacity: 1;
110 | transform: scale(1);
111 | }
112 | }
113 |
114 | /* Quando clicar no botão, sumir com o form */
115 | .form-hide {
116 | animation: down 500ms forwards;
117 | }
118 |
119 | @keyframes down {
120 | from {
121 | transform: translateY(0);
122 | }
123 | to {
124 | transform: translateY(100vh);
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/desafios/05/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/desafios/05/script.js:
--------------------------------------------------------------------------------
1 | const btnLogin = document.querySelector(".btn-login");
2 | const form = document.querySelector("form");
3 |
4 | btnLogin.addEventListener("click", event => {
5 | event.preventDefault();
6 | form.classList.add("form-hide");
7 | });
8 |
9 | form.addEventListener("animationstart", event => {
10 | if (event.animationName === "down") {
11 | document.querySelector("body").style.overflow = "hidden";
12 | }
13 | });
14 |
15 | form.addEventListener("animationend", event => {
16 | if (event.animationName === "down") {
17 | form.style.display = "none";
18 | document.querySelector("body").style.overflow = "none";
19 | }
20 | });
21 |
--------------------------------------------------------------------------------
/desafios/05/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | html,
8 | body {
9 | height: 100vh;
10 | }
11 |
12 | body {
13 | background-color: #7159c1;
14 | font-family: Roboto, Arial, sans-serif;
15 | }
16 |
17 | section {
18 | display: flex;
19 | flex-direction: column;
20 | justify-content: center;
21 | align-items: center;
22 | }
23 |
24 | h1 {
25 | font-size: 32px;
26 | letter-spacing: 1px;
27 | margin: 20px 0;
28 | color: white;
29 | }
30 |
31 | form {
32 | margin: 20px 0;
33 | background-color: white;
34 | padding: 30px 25px;
35 | border-radius: 5px;
36 | }
37 |
38 | form .input-block {
39 | margin-bottom: 20px;
40 | }
41 |
42 | form .input-block label {
43 | font-size: 14px;
44 | color: darkslateblue;
45 | }
46 |
47 | form .input-block input {
48 | width: 100%;
49 | display: block;
50 | margin-top: 8px;
51 | padding: 7px;
52 | font-size: 16px;
53 | color: #7159c1;
54 | border-radius: 2px;
55 | border: 1px solid #ccddef;
56 | outline-color: #7159c1;
57 | }
58 |
59 | form .btn-login {
60 | display: block;
61 | min-width: 120px;
62 | border: none;
63 | background-color: #7159c1;
64 | color: white;
65 | border-radius: 25px;
66 | margin: auto;
67 | padding: 7px;
68 | }
69 |
70 | /* APARIÇÃO DO FORM */
71 | form {
72 | overflow: hidden;
73 | animation: fade 0.2s;
74 | }
75 |
76 | form .input-block:nth-child(1) {
77 | animation: move 500ms;
78 | }
79 |
80 | form .input-block:nth-child(2) {
81 | animation: move 400ms;
82 | animation-delay: 100ms;
83 | animation-fill-mode: backwards;
84 | }
85 |
86 | form .btn-login {
87 | animation: move 400ms;
88 | animation-delay: 250ms;
89 | animation-fill-mode: backwards;
90 | }
91 |
92 | @keyframes move {
93 | from {
94 | opacity: 0;
95 | transform: translateX(-35%);
96 | }
97 | to {
98 | opacity: 1;
99 | transform: translateX(0%);
100 | }
101 | }
102 |
103 | @keyframes fade {
104 | from {
105 | opacity: 0;
106 | transform: scale(0.9);
107 | }
108 | to {
109 | opacity: 1;
110 | transform: scale(1);
111 | }
112 | }
113 |
114 | /* Quando clicar no botão, sumir com o form */
115 | .form-hide {
116 | animation: down 500ms forwards;
117 | animation-timing-function: cubic-bezier(0, 1.2, 0.6, 0.2);
118 | }
119 |
120 | @keyframes down {
121 | from {
122 | transform: translateY(0);
123 | }
124 | to {
125 | transform: translateY(50vh);
126 | }
127 | }
128 |
--------------------------------------------------------------------------------
/desafios/06/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/desafios/06/script.js:
--------------------------------------------------------------------------------
1 | const btnLogin = document.querySelector(".btn-login");
2 | const form = document.querySelector("form");
3 |
4 | btnLogin.addEventListener("click", event => {
5 | event.preventDefault();
6 |
7 | const fields = [...document.querySelectorAll(".input-block input")];
8 |
9 | fields.forEach(field => {
10 | if (field.value === "") form.classList.add("validate-error");
11 | });
12 |
13 | const formError = document.querySelector(".validate-error");
14 | if (formError) {
15 | formError.addEventListener("animationend", event => {
16 | if (event.animationName === "nono") {
17 | formError.classList.remove("validate-error");
18 | }
19 | });
20 | } else {
21 | form.classList.add("form-hide");
22 | }
23 | });
24 |
25 | form.addEventListener("animationstart", event => {
26 | if (event.animationName === "down") {
27 | document.querySelector("body").style.overflow = "hidden";
28 | }
29 | });
30 |
31 | form.addEventListener("animationend", event => {
32 | if (event.animationName === "down") {
33 | form.style.display = "none";
34 | document.querySelector("body").style.overflow = "none";
35 | }
36 | });
37 |
--------------------------------------------------------------------------------
/desafios/06/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | html,
8 | body {
9 | height: 100vh;
10 | }
11 |
12 | body {
13 | background-color: #7159c1;
14 | font-family: Roboto, Arial, sans-serif;
15 | }
16 |
17 | section {
18 | display: flex;
19 | flex-direction: column;
20 | justify-content: center;
21 | align-items: center;
22 | }
23 |
24 | h1 {
25 | font-size: 32px;
26 | letter-spacing: 1px;
27 | margin: 20px 0;
28 | color: white;
29 | }
30 |
31 | form {
32 | margin: 20px 0;
33 | background-color: white;
34 | padding: 30px 25px;
35 | border-radius: 5px;
36 | }
37 |
38 | form .input-block {
39 | margin-bottom: 20px;
40 | }
41 |
42 | form .input-block label {
43 | font-size: 14px;
44 | color: darkslateblue;
45 | }
46 |
47 | form .input-block input {
48 | width: 100%;
49 | display: block;
50 | margin-top: 8px;
51 | padding: 7px;
52 | font-size: 16px;
53 | color: #7159c1;
54 | border-radius: 2px;
55 | border: 1px solid #ccddef;
56 | outline-color: #7159c1;
57 | }
58 |
59 | form .btn-login {
60 | display: block;
61 | min-width: 120px;
62 | border: none;
63 | background-color: #7159c1;
64 | color: white;
65 | border-radius: 25px;
66 | margin: auto;
67 | padding: 7px;
68 | }
69 |
70 | /* APARIÇÃO DO FORM */
71 | form {
72 | overflow: hidden;
73 | animation: fade 0.2s;
74 | }
75 |
76 | form .input-block:nth-child(1) {
77 | animation: move 500ms;
78 | }
79 |
80 | form .input-block:nth-child(2) {
81 | animation: move 400ms;
82 | animation-delay: 100ms;
83 | animation-fill-mode: backwards;
84 | }
85 |
86 | form .btn-login {
87 | animation: move 400ms;
88 | animation-delay: 250ms;
89 | animation-fill-mode: backwards;
90 | }
91 |
92 | @keyframes move {
93 | from {
94 | opacity: 0;
95 | transform: translateX(-35%);
96 | }
97 | to {
98 | opacity: 1;
99 | transform: translateX(0%);
100 | }
101 | }
102 |
103 | @keyframes fade {
104 | from {
105 | opacity: 0;
106 | transform: scale(0.9);
107 | }
108 | to {
109 | opacity: 1;
110 | transform: scale(1);
111 | }
112 | }
113 |
114 | /* Quando clicar no botão, sumir com o form */
115 | .form-hide {
116 | animation: down 1.2s forwards;
117 | animation-timing-function: cubic-bezier(0.075, 0.82, 0.165, 1);
118 | }
119 |
120 | @keyframes down {
121 | from {
122 | transform: translateY(0);
123 | }
124 | to {
125 | transform: translateY(100vh);
126 | }
127 | }
128 |
129 | /* FORM NO-NO */
130 | form.validate-error {
131 | animation: nono 200ms linear, fade paused;
132 | animation-iteration-count: 2;
133 | }
134 |
135 | @keyframes nono {
136 | 0%,
137 | 100% {
138 | transform: translateX(0);
139 | }
140 | 35% {
141 | transform: translateX(-15%);
142 | }
143 | 70% {
144 | transform: translateX(15%);
145 | }
146 | }
147 |
--------------------------------------------------------------------------------
/desafios/07/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Document
8 |
9 |
10 |
11 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/desafios/07/script.js:
--------------------------------------------------------------------------------
1 | const btnLogin = document.querySelector(".btn-login");
2 | const form = document.querySelector("form");
3 |
4 | btnLogin.addEventListener("click", event => {
5 | event.preventDefault();
6 |
7 | const fields = [...document.querySelectorAll(".input-block input")];
8 |
9 | fields.forEach(field => {
10 | if (field.value === "") form.classList.add("validate-error");
11 | });
12 |
13 | const formError = document.querySelector(".validate-error");
14 | if (formError) {
15 | formError.addEventListener("animationend", event => {
16 | if (event.animationName === "nono") {
17 | formError.classList.remove("validate-error");
18 | }
19 | });
20 | } else {
21 | form.classList.add("form-hide");
22 | }
23 | });
24 |
25 | form.addEventListener("animationstart", event => {
26 | if (event.animationName === "down") {
27 | document.querySelector("body").style.overflow = "hidden";
28 | }
29 | });
30 |
31 | form.addEventListener("animationend", event => {
32 | if (event.animationName === "down") {
33 | form.style.display = "none";
34 | document.querySelector("body").style.overflow = "none";
35 | }
36 | });
37 |
38 | /* background squares */
39 | const ulSquares = document.querySelector("ul.squares");
40 |
41 | for (let i = 0; i < 11; i++) {
42 | const li = document.createElement("li");
43 |
44 | const random = (min, max) => Math.random() * (max - min) + min;
45 |
46 | const size = Math.floor(random(10, 120));
47 | const position = random(1, 99);
48 | const delay = random(5, 0.1);
49 | const duration = random(24, 12);
50 |
51 | li.style.width = `${size}px`;
52 | li.style.height = `${size}px`;
53 | li.style.bottom = `-${size}px`;
54 |
55 | li.style.left = `${position}%`;
56 |
57 | li.style.animationDelay = `${delay}s`;
58 | li.style.animationDuration = `${duration}s`;
59 | li.style.animationTimingFunction = `cubic-bezier(${Math.random()}, ${Math.random()}, ${Math.random()}, ${Math.random()})`;
60 |
61 | ulSquares.appendChild(li);
62 | }
63 |
--------------------------------------------------------------------------------
/desafios/07/style.css:
--------------------------------------------------------------------------------
1 | * {
2 | box-sizing: border-box;
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | html,
8 | body {
9 | height: 100vh;
10 | }
11 |
12 | body {
13 | background-color: #7159c1;
14 | font-family: Roboto, Arial, sans-serif;
15 | }
16 |
17 | section {
18 | display: flex;
19 | flex-direction: column;
20 | justify-content: center;
21 | align-items: center;
22 | }
23 |
24 | h1 {
25 | font-size: 32px;
26 | letter-spacing: 1px;
27 | margin: 20px 0;
28 | color: white;
29 | }
30 |
31 | form {
32 | margin: 20px 0;
33 | background-color: white;
34 | padding: 30px 25px;
35 | border-radius: 5px;
36 | }
37 |
38 | form .input-block {
39 | margin-bottom: 20px;
40 | }
41 |
42 | form .input-block label {
43 | font-size: 14px;
44 | color: darkslateblue;
45 | }
46 |
47 | form .input-block input {
48 | width: 100%;
49 | display: block;
50 | margin-top: 8px;
51 | padding: 7px;
52 | font-size: 16px;
53 | color: #7159c1;
54 | border-radius: 2px;
55 | border: 1px solid #ccddef;
56 | outline-color: #7159c1;
57 | }
58 |
59 | form .btn-login {
60 | display: block;
61 | min-width: 120px;
62 | border: none;
63 | background-color: #7159c1;
64 | color: white;
65 | border-radius: 25px;
66 | margin: auto;
67 | padding: 7px;
68 | }
69 |
70 | /* APARIÇÃO DO FORM */
71 | form {
72 | overflow: hidden;
73 | animation: fade 0.2s;
74 | }
75 |
76 | form .input-block:nth-child(1) {
77 | animation: move 500ms;
78 | }
79 |
80 | form .input-block:nth-child(2) {
81 | animation: move 400ms;
82 | animation-delay: 100ms;
83 | animation-fill-mode: backwards;
84 | }
85 |
86 | form .btn-login {
87 | animation: move 400ms;
88 | animation-delay: 250ms;
89 | animation-fill-mode: backwards;
90 | }
91 |
92 | @keyframes move {
93 | from {
94 | opacity: 0;
95 | transform: translateX(-35%);
96 | }
97 | to {
98 | opacity: 1;
99 | transform: translateX(0%);
100 | }
101 | }
102 |
103 | @keyframes fade {
104 | from {
105 | opacity: 0;
106 | transform: scale(0.9);
107 | }
108 | to {
109 | opacity: 1;
110 | transform: scale(1);
111 | }
112 | }
113 |
114 | /* Quando clicar no botão, sumir com o form */
115 | .form-hide {
116 | animation: down 1.2s forwards;
117 | animation-timing-function: cubic-bezier(0.075, 0.82, 0.165, 1);
118 | }
119 |
120 | @keyframes down {
121 | from {
122 | transform: translateY(0);
123 | }
124 | to {
125 | transform: translateY(100vh);
126 | }
127 | }
128 |
129 | /* FORM NO-NO */
130 |
131 | form.validate-error {
132 | animation: nono 200ms linear, fade paused;
133 | animation-iteration-count: 2;
134 | }
135 |
136 | @keyframes nono {
137 | 0%,
138 | 100% {
139 | transform: translateX(0);
140 | }
141 | 35% {
142 | transform: translateX(-15%);
143 | }
144 | 70% {
145 | transform: translateX(15%);
146 | }
147 | }
148 |
149 | /* squares */
150 | body {
151 | overflow: hidden;
152 | }
153 | .squares li {
154 | width: 40px;
155 | height: 40px;
156 | background-color: rgba(255, 255, 255, 0.15);
157 | display: block;
158 | position: absolute;
159 | bottom: -40px;
160 | animation: up 2s infinite alternate;
161 | z-index:-1
162 | }
163 |
164 | @keyframes up {
165 | from {
166 | opacity: 0;
167 | transform: translateY(0);
168 | }
169 | 50% {
170 | opacity: 1;
171 | }
172 | to {
173 | transform: translateY(-800px) rotate(960deg);
174 | }
175 | }
176 |
--------------------------------------------------------------------------------