HyunJun 기술 블로그

CSS Animation, transform, transition, @keyframes 본문

CSS

CSS Animation, transform, transition, @keyframes

공부 좋아 2023. 6. 16. 16:22
728x90
반응형

1. CSS Animation

1) transform

  • translate(); 해당 좌표만큼 이동
    • transform: translate(100px, 100px); 
    • transform: translateX(100px); 
    • transform: translateY(100px); 
    • transform: translateZ(100px);
  • rotate(); 해당 각도만큼 회전
    • transform: rotate(45deg); 
    • transform: rotateX(45deg); 
    • transform: rotateY(45deg); 
    • transform: rotateZ(45deg);
  • scale(); 크기 증가(배수)
    • transform: scale(2); 
    • transform: scaleX(2); 
    • transform: scaleY(2);

transform을 각각 적으면 마지막에 적힌 속성이 적용됨, 이때는 아래와 같은 형식으로 여러 개 사용 가능

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./index.css" />
  </head>
  <body>
    <div class="wrap">
      <div class="animation-original">원본</div>
      <div class="animation">애니메이션 적용</div>
    </div>
  </body>
</html>
.wrap {
  width: 500px;
  height: 500px;
  border: 1px solid black;
}

.animation {
  width: 100px;
  height: 100px;
  border: 1px solid black;
  transform: translate(100px, 100px) rotate(45deg) scale(2);
}

.animation-original {
  width: 100px;
  height: 100px;
  border: 1px solid black;
}
  • transform: translate(100px, 100px) rotate(45deg) scale(2);의 순서대로 효과가 적용된다.

이때 주의할 점은 transform에 들어가는 옵션이 앞에서부터 순서대로 적용되므로, 옵션의 순서마다 다른 결과가 나올 수 있다.

.animation {
  /*1번*/
  transform: scale(2) translate(100px, 100px) rotate(45deg);
  /*2번*/
  transform: rotate(45deg) scale(2) translate(100px, 100px);
}

(왼쪽) 1번, (오른쪽) 2번

2) transition

  • 위의 transform은 동적으로 변하는 애니메이션이 아닌 해당 효과를 다 적용시킨 후 결과만을 보여줬다.
  • transition을 활용해서 1px 등 수치가 있는 값에 대해서 시간을 적용하여 애니메이션 효과를 낼 수 있다.
    • 수치가 없이 상수로 정해져있는 값은 시간에 따른 효과 변경이 불가능하다.
  • transition은 anmation을 동작 시킬 요소가 필요하다.
    • animation을 적용시킬 요소에 transition을 작성하고, anmation을 동작시킬 요소에 변하는 값을 입력하면 된다.
.wrap {
  width: 500px;
  height: 500px;
  border: 1px solid black;
}

.animation {
  width: 100px;
  height: 100px;
  border: 1px solid black;
  transition: background-color 5s linear, border-radius 3s linear;
}

.animation:hover {
  background-color: yellow;
  border-radius: 50px;
}

.animation-original {
  width: 100px;
  height: 100px;
  border: 1px solid black;
}

mouse hover 시

  • border-radius가 50px로 변한다 -> transition에 border-radius가 3초에 linear 형식으로 값이 변하게 설정되어 있어서 애니메이션이 적용됨.
  • background-color도 yellow로 설정되어 있음 transition에 설정된 옵션에 따라 흰색에서 노란색으로 5초 안에 변경됨. 색깔은 rgb 값으로 수치가 있기 때문에 시간에 따른 변화가 가능하다.
    • transition을 hover 안에 넣어도 동작은 하나, hover 일 때에만 transition이 적용되므로, 해당 요소에서 마우스가 나오면 애니메이션이 수치값이 원상복구되면서 자연스럽게 풀리는 것이 아니라 바로 초기값으로 풀리게 되어 부자연스럽게 된다.

 

transition을 동작시킬 요소에 바로 넣었을 때

 

transition에는 변하는 값이라면 모든 속성값을 사용할 수 있다. transform을 활용할 수도 있다.

.animation {
  width: 100px;
  height: 100px;
  border: 1px solid black;
  transition: transform 3s linear;
}

.animation:hover {
  transform: translate(100px, 100px) rotate(45deg) scale(2);
}

 

transition을 사용 불가능한 경우

solid -> dotted는 숫자로 지정된 값이 없기 때문에 transition의 적용을 받지 않고 바로 변경됨.

.animation {
    width: 100px;
    height: 100px;
    border: 1px solid black;
    transition: border 3s linear;
  }

  .animation:hover {
    border: 10px dotted blue;
  }

 

all을 사용하여 모든 속성값에 일괄적으로 적용할 수 있다.

  .animation {
    width: 100px;
    height: 100px;
    border: 1px solid black;
    transition: all 3s linear;
  }

  .animation:hover {
    width: 50px;
    height: 50px;
    background-color: yellow;
  }

 

 

3) @keyframes

  • 단순히 second가 아닌 여러 단계별로 애니메이션을 구현할 수 있다.
  • 특정한 이벤트 없이 자동으로 애니메이션을 실행시킬 수 있다.
.animation {
  position: relative;
  width: 100px;
  height: 100px;
  border: 1px solid black;
  animation: left-right 3s linear infinite;
}

.animation-original {
  width: 100px;
  height: 100px;
  border: 1px solid black;
}

@keyframes left-right {
  0% {
    left: 0%;
  }
  50% {
    left: 80%;
  }
  100% {
    left: 0%;
  }
}

alternate(정방향, 역방향 => 0% ~ 100% 100% ~ 0%)와 infinite를 사용하면 위의 예제와 동일하게 동작한다.

.animation {
  animation: left-right 1.5s linear alternate infinite;
}


@keyframes left-right {
  0% {
    left: 0%;
  }
  100% {
    left: 80%;
  }
}

아래와 같이 속성 이름을 따로 지정하여 줄 수 있다.

.animation {
  animation-name: left-right;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-direction: alternate;
  animation-fill-mode: none;
  /* 애니메이션 루프를 3초 후 실행 */
  animation-delay: 3s;
  /* 애니메이션 실행 */
  animation-play-state: running;
}

 

keyframes의 %와 animation-direction 등을 잘 활용하면 여러 가지 형태로 애니메이션을 구현할 수 있다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <link rel="stylesheet" href="./index.css" />
  </head>
  <body>
    <div class="wrap">
      <div class="pointer"></div>
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
      <div class="item">4</div>
      <div class="item">5</div>

      <div class="item">6</div>
      <div class="item">7</div>
      <div class="item">8</div>
      <div class="item">9</div>
      <div class="item">10</div>

      <div class="item">11</div>
      <div class="item">12</div>
      <div class="item">13</div>
      <div class="item">14</div>
      <div class="item">15</div>

      <div class="item">16</div>
      <div class="item">17</div>
      <div class="item">18</div>
      <div class="item">19</div>
      <div class="item">20</div>

      <div class="item">21</div>
      <div class="item">22</div>
      <div class="item">23</div>
      <div class="item">24</div>
      <div class="item">25</div>
    </div>
  </body>
</html>
.wrap {
  background-color: beige;
  width: 500px;
  height: 500px;
  display: flex;
  flex-wrap: wrap;
  position: relative;
}

.item {
  width: 100px;
  height: 100px;
  background-color: rgba(0, 0, 0, 0.3);

  color: rgb(206, 100, 35);
}

.pointer {
  position: absolute;
  width: 100px;
  height: 100px;
  background-color: rgba(0, 145, 255, 0.3);
  animation: pointer 5s linear infinite alternate;
}

@keyframes pointer {
  0% {
    left: 0;
    top: 0;
  }
  4.15% {
    left: 100px;
    top: 0;
  }
  8.30% {
    left: 200px;
    top: 0;
  }
  12.45% {
    left: 300px;
    top: 0;
  }
  16.60% {
    left: 400px;
    top: 0;
  }
  20.75% {
    left: 400px;
    top: 100px;
  }
  24.90% {
    left: 300px;
    top: 100px;
  }
  29.05% {
    left: 200px;
    top: 100px;
  }
  33.20% {
    left: 100px;
    top: 100px;
  }
  37.35% {
    left: 0px;
    top: 100px;
  }
  41.50% {
    left: 0px;
    top: 200px;
  }

  45.75% {
    left: 100px;
    top: 200px;
  }
  49.90% {
    left: 200px;
    top: 200px;
  }
  54.05% {
    left: 300px;
    top: 200px;
  }
  58.20% {
    left: 400px;
    top: 200px;
  }
  62.35% {
    left: 400px;
    top: 300px;
  }
  66.50% {
    left: 300px;
    top: 300px;
  }
  70.65% {
    left: 200px;
    top: 300px;
  }
  74.80% {
    left: 100px;
    top: 300px;
  }
  78.95% {
    left: 0px;
    top: 300px;
  }
  83.10% {
    left: 0px;
    top: 400px;
  }
  87.25% {
    left: 100px;
    top: 400px;
  }
  91.40% {
    left: 200px;
    top: 400px;
  }
  95.55% {
    left: 300px;
    top: 400px;
  }
  100% {
    left: 400px;
    top: 400px;
  }
}

728x90
반응형
Comments