test.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Form Animation</title>

    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.15.4/css/all.css"
        integrity="sha384-DyZ88mC6Up2uqS4h/KRgHuoeGwBcD4Ng9SiP4dIRy0EXTlnuz47vAwmeGwVChigm" crossorigin="anonymous">
    <link rel="stylesheet" href="./style.css" />
</head>

<body>
    <form>
        <div class="field-name">
            <i class="fas fa-user"></i>
            <input type="text" placeholder="Username" required />
            <i class="fas fa-arrow-down"></i>
        </div>
        <div class="field-email innactive">
            <i class="fas fa-arrow-down"></i>
            <input type="email" placeholder="Email" required />
            <i class="fas fa-arrow-down"></i>
        </div>
        <div class="field-password innactive">
            <i class="fas fa-key"></i>
            <input type="password" placeholder="Password" required />
            <i class="fas fa-arrow-down"></i>
        </div>
        <div class="field-finish innactive">
            <i class="fas fa-heart"></i>
            <p>Thank you!</p>
            <i class="fas fa-heart"></i>
        </div>

    </form>
    <script type="text/javascript" src="app.js"></script>
</body>

</html>
.css

*{
margin:0;
box-sizing: border-box;
padding: 0;
}
body{
    height:100vh;
    /* 열로 정렬된 속성들을 가로행으로 바꾸다 */
    display: flex;
    background-color: rgb(87,189,130);
    transition:background 0.5s ease;
    position:relative;
}
.field-name,
.field-email,
.field-password,
.field-finish
{
    /* 조상을 기준으로 움직이다, absolute만 있다면 body를 기준으로 가장 왼족, 위에 가다 */
position:absolute;
top:50%;
left: 50%;
transform:translate(-50%,-50%);
background:white;
height:50px;
width:400px;
/* div 안에 fontawesome과 input tag가 있다, space-between 으로 양끝 정렬, align-item으로 가로정렬 */
display:flex;
justify-content:space-between;
align-items:center;
border-radius: 5px;
transition: all 0.5s ease;
}
.field-name i,
.field-email i,
.field-password i,
.field-finish i{
    padding:10px;
    cursor:pointer;
}
.field-name input,
.field-email input,
.field-password input{
    background:none;
    border:none;
    /* 양쪽 fontawesome 들은 기본값을 가지고 flex 1 인 input 은 최대로 늘어나다 */
    flex:1;
    height:100%;
    outline:none;
}
/* 위치변경  */
 div.innactive{
    opacity:0;
    pointer-events:none;
    transform:translate(-50%,50%);
} 
 div.active{
    opacity:1;
    pointer-events:all;
    transform:translate(-50%,-50%);
} 
@keyframes shake{
0%{
    transform:translate(-50%,-50%) rotate(0deg);
}
50%{
    transform:translate(-50%,-50%) rotate(10deg);
}
100%{
    transform:translate(-50%,-50%) rotate(0deg);
}

}
.js

function animatedForm() {
    const arrows = document.querySelectorAll(".fa-arrow-down"); //fontAwesome 태그를 담습니다
    console.log(arrows); //모든 fa-arrow-down 태그들이 담깁니다 
    arrows.forEach(arrow => {
        arrow.addEventListener('click', () => {//각 화살표가 클릭이 되면 실행됩니다.
            const input = arrow.previousElementSibling;//바로 전 태그를 반환하다 
            const parent = arrow.parentElement;//arrow의 부모태그의 정보를 담습니다
            const nextForm = parent.nextElementSibling;//현재 가장위에 있는 태그의 다음 형제 태그를 담습니다 -> div email 태그
            console.log(input);
            console.log(parent);
            console.log(nextForm);

            //Check for validation
            if (input.type === "text" && validateUser(input)) {//input 속성중 type 이 text 이고 validateUser(input)을 던져 true 가 나오면 실행 input 에는 화살표 전 태그입돠

                nextSlide(parent, nextForm); //nextSlide 함수 실행(parent,nextForm) parent arrow의 부모태그 -> div, nextForm 은 div username에서 div email 로 넘어갑니다

            } else if (input.type === 'email' && validateEmail(input)) {
                nextSlide(parent, nextForm);
            } else if (input.type === 'password' && validateUser(input)) {
                nextSlide(parent, nextForm);
            } else {
                parent.style.animation = "shake 0.5s ease";
            }
            parent.addEventListener("animationend", () => {
                parent.style.animation = "";
            })
        });

    });

}

function validateUser(user) { //input 태그가 왔습니다. type = text임돠

    if (user.value.length < 6) {//input 태그의 값 길이가 6보다 작으면 실행
        console.log("not enough characters");
        error('rgb(189,87,87)'); //에러 색상
    } else {
        error('rgb(87,189,130)'); //통과 색상

        return true;
    }
}
function validateEmail(email) {
    const validation = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (validation.test(email.value)) {
        error('rgb(87,189,130)'); //통과 색상
        return true;
    } else {
        error('rgb(189,87,87)'); //에러 색상
    }
}
function nextSlide(parent, nextForm) {
    parent.classList.add('innactive');//화살표를 누르면 username 태그에 innactive 가 붙어요 -> opacity :0 50% 아래로 내려갑니다
    parent.classList.remove('active');//username에 active 태그는 없어지고, 
    nextForm.classList.add('active');//다음 태그인 email 에 innactive 있고, active가 붙습니다 태그에 innactive가 붙어서 50%내려가 있었는데, -50%가 active에 있어서 올라 옵니다
}
function error(color) {
    document.body.style.backgroundColor = color;

}
animatedForm();
profile
건물주가 되는 그날까지

0개의 댓글