퍼블리싱/html, css, javascript

CSS 애니메이션으로 404 에러페이지 제작하기

연지쁨 2023. 11. 8. 13:48
반응형
목차
1. 404코드란?
2. CSS 애니메이션 이론
3. 베지어 곡선이란?
4. CSS 애니메이션을 이용한 404 페이지

 

 

 

 

 

404 코드란?

 

 

 

서버와 통신할 수는 있지만 요청한 바를 찾을 수 없다는 것을 가리키는 HTTP 표준 응답 코드

 

 

 

 

 

CSS 애니메이션 이론

 

  • animation-delay : 로드 이후 언제 시작할지 
  • animation-direction : (종료 후) 정방향 / 역방향 진행
  • animation-duration : 얼마에 걸쳐 진행될지
  • animation-iteration-count : 몇 번 반복될지 (infinite : 무한)
  • animation-name : 중간 상태를 지정
  • animation-play-state : 멈춤/재생 상태 지정
  • animation-timing-function : 어떤 시간간격으로 진행할지
  • animation-fill-mode : 시작 전/애니메이션 종료 후 스타일
  • matrix : 모든 메소드 한번에 적용 matrix (scaleX, skewY, skewX, scaleY, translateX, translateY)
  • translate : 이동 
  • scale : 확대, 축소 
  • rotate : 회전 
  • skew : 기울임
  • Keyword values ease : 애니메이션 중간까지 속도가 올라가고 중간 이후 느려짐
  • cubic-bezier(0.25, 0.1, 0.25, 1.0) ease-in : 천천히 시작해 끝날때까지 빨라짐
  • cubic-bezier(0.42, 0, 1.0, 1.0) ease-out : 빨리 시작해 점점 느려짐
  • cubic-bezier(0, 0, 0.58, 1.0) ease-in-out : 천천히 시작했다 빨라지고 다시 느려지며 끝남
  • cubic-bezier(0.42, 0, 0.58, 1.0) linear : 등속 cubic-bezier(0.0, 0.0, 1.0, 1.0)

 

 

@keyframes appearFromBottom {
  from {
    transform: translateY(1000px); /* 시작 지점: 아래 방향으로 1000px만큼 이동 */
  }
  50% {
    transform: translateY(300px); /* 중간 지점: 아래 방향으로 300px만큼 이동 (애니메이션 중간 지점) */
  }
  to {
    transform: translateY(0); /* 종료 지점: 아래 방향으로 이동하지 않고 0으로 유지 (애니메이션 종료) */
  }
}

 

 

반응형

 

베지어 곡선이란?

 

 컴퓨터 그래픽 등에서 사용되는 매개변수 곡선

4개의 포인트 (P0, P1, P2, P3)로 정의

 

 

 

 

 

CSS 애니메이션 404 에러페이지 소스

 

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

<head> 
  <link rel="stylesheet" href="./index.css"> <!-- 외부 CSS 파일을 연결 -->
  <meta charset="UTF-8"> <!-- 문자 집합을 UTF-8로 설정 -->
  <meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- IE 호환성 설정 -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- 모바일 뷰포트 설정 -->
  <title>404 Page</title> <!-- 웹 페이지 제목 설정 -->
</head>

<body>
  <svg id="ufo-image" viewBox="0 0 2303 1630" fill="none" xmlns="http://www.w3.org/2000/svg"> <!-- UFO 이미지를 나타내는 SVG 요소 -->
    <!-- 다양한 그래픽 요소들로 UFO를 구성 -->
  </svg>

  <script>
    // 애니메이션 상태를 전환하는 JavaScript 함수들
    const setZeroAndBeamAppear = () => {
      // 'number-0-soaking' 요소의 애니메이션이 종료되면 호출하는 함수
      document.getElementById('number-0-soaking').removeEventListener("animationend", setZeroAndBeamAppear)

      // 'number-0-soaking' 요소의 ID를 'number-0'로 변경
      // 'UFO-beam-disappearing' 요소의 ID를 'UFO-beam'으로 변경
      document.getElementById('number-0-soaking').setAttribute("id", "number-0")
      document.getElementById('UFO-beam-disappearing').setAttribute("id", "UFO-beam")

      // 'number-0' 요소의 애니메이션이 종료되면 다시 'setZeroAndBeamDisappear' 함수 호출
      document.getElementById('number-0').addEventListener("animationend", setZeroAndBeamDisappear)
    }

    const setZeroAndBeamDisappear = () => {
      // 'number-0' 요소의 애니메이션이 종료되면 호출하는 함수
      document.getElementById('number-0').removeEventListener("animationend", setZeroAndBeamDisappear)

      // 'number-0' 요소의 ID를 'number-0-soaking'으로 변경
      // 'UFO-beam' 요소의 ID를 'UFO-beam-disappearing'으로 변경
      document.getElementById('number-0').setAttribute("id", "number-0-soaking")
      document.getElementById('UFO-beam').setAttribute("id", "UFO-beam-disappearing")

      // 'number-0-soaking' 요소의 애니메이션이 종료되면 다시 'setZeroAndBeamAppear' 함수 호출
      document.getElementById('number-0-soaking').addEventListener("animationend", setZeroAndBeamAppear)
    }

    // 초기 상태로 'setZeroAndBeamDisappear' 함수 호출
    document.getElementById('number-0').addEventListener("animationend", setZeroAndBeamDisappear)
  </script>

</html>

 

body {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100vw;
  height: 100vh;
  overflow: hidden;
  background-color: #24145E; /* 배경색 설정 */
}

/* 'rotation' 키프레임: 요소를 360도 회전시키는 애니메이션 */
@keyframes rotation {
  to {
    transform: rotateZ(360deg);
  }
}

/* 'shrinkAndGrow' 키프레임: 요소를 축소하고 확대하는 애니메이션 */
@keyframes shrinkAndGrow {
  0% {
    transform: scale(0);
  }
  25% {
    transform: scale(0.5);
  }
  50% {
    transform: scale(0);
  }
  75% {
    transform: scale(1);
  }
  100% {
    transform: scale(0);
  }
}

/* 'expandHorizontal' 키프레임: 요소를 수평으로 확장하는 애니메이션 */
@keyframes expandHorizontal {
  from {
    transform: scaleX(0);
  }
  to {
    transform: scaleX(1);
  }
}

/* 'appearFromBottom' 키프레임: 요소를 아래에서 위로 나타나게 하는 애니메이션 */
@keyframes appearFromBottom {
  from {
    transform: translateY(1000px);
  }
  to {
    transform: translateY(0);
  }
}

/* 'shakingUpAndDown' 키프레임: 요소를 위아래로 흔들어주는 애니메이션 */
@keyframes shakingUpAndDown {
  from {
    transform: translateY(0);
  }
  25% {
    transform: translateY(5px);
  }
  50% {
    transform: translateY(-5px);
  }
  75% {
    transform: translateY(5px);
  }
  to {
    transform: translateY(0);
  }
}

/* 'soaking' 키프레임: 요소를 위로 이동하고 크기를 축소하는 애니메이션 */
@keyframes soaking {
  to {
    transform: translateY(-250px) scale(0);
  }
}

/* 'shrinkHorizontal' 키프레임: 요소를 수평으로 축소하는 애니메이션 */
@keyframes shrinkHorizontal {
  to {
    transform: scaleX(0);
  }
}

/* 아래는 요소들에 애니메이션을 적용하는 부분 */

#planet_2 {
  animation-name: rotation; /* 'rotation' 키프레임을 사용하여 회전 애니메이션 적용 */
  animation-duration: 4s; /* 애니메이션 지속 시간 설정 */
  animation-iteration-count: infinite; /* 무한 반복 설정 */
  transform-box: fill-box;
  transform-origin: center;
}

#planet_1 {
  animation-name: rotation; /* 'rotation' 키프레임을 사용하여 회전 애니메이션 적용 */
  animation-duration: 3s; /* 애니메이션 지속 시간 설정 */
  animation-timing-function: linear; /* 애니메이션 타이밍 함수 설정 */
  animation-iteration-count: infinite; /* 무한 반복 설정 */
  transform-box: fill-box;
  transform-origin: center;
}

#star_6 {
  animation: shrinkAndGrow 4s infinite; /* 'shrinkAndGrow' 애니메이션을 사용하여 크기 조절 애니메이션 적용 */
  transform-box: fill-box;
  transform-origin: center;
}

#star_3 {
  animation: shrinkAndGrow 2s infinite; /* 'shrinkAndGrow' 애니메이션을 사용하여 크기 조절 애니메이션 적용 */
  transform-box: fill-box;
  transform-origin: center;
}

#star_5 {
  animation: shrinkAndGrow 6s infinite; /* 'shrinkAndGrow' 애니메이션을 사용하여 크기 조절 애니메이션 적용 */
  transform-box: fill-box;
  transform-origin: center;
}

#star_7 {
  animation: shrinkAndGrow 9s infinite; /* 'shrinkAndGrow' 애니메이션을 사용하여 크기 조절 애니메이션 적용 */
  transform-box: fill-box;
  transform-origin: center;
}

#star_8 {
  animation: shrinkAndGrow 11s infinite; /* 'shrinkAndGrow' 애니메이션을 사용하여 크기 조절 애니메이션 적용 */
  transform-box: fill-box;
  transform-origin: center;
}

#UFO-beam {
  animation: expandHorizontal 3.5s; /* 'expandHorizontal' 애니메이션을 사용하여 수평 확장 애니메이션 적용 */
  transform-box: fill-box;
  transform-origin: center;
}

#number-0 {
  animation: appearFromBottom 3s; /* 'appearFromBottom' 애니메이션을 사용하여 아래에서 위로 나타나는 애니메이션 적용 */
  animation-timing-function: cubic-bezier(.79,1.31,.82,-0.36); /* 애니메이션 타이밍 함수 설정 */
}

#alien_hand-R, #alien_hand-L {
  animation: shakingUpAndDown 1s infinite; /* 'shakingUpAndDown' 애니메이션을 사용하여 흔들리는 애니메이션 적용 */
  animation-timing-function: cubic-bezier(.35,.28,.82,.87); /* 애니메이션 타이밍 함수 설정 */
}

#number-0-soaking {
  animation: soaking 2s; /* 'soaking' 애니메이션을 사용하여 위로 이동하고 크기 축소하는 애니메이션 적용 */
  transform-box: fill-box;
  transform-origin: center;
}

#UFO-beam-disappearing {
  animation: shrinkHorizontal 2s; /* 'shrinkHorizontal' 애니메이션을 사용하여 수평으로 축소하는 애니메이션 적용 */
  transform-box: fill-box;
  transform-origin: center;
}
반응형