본문 바로가기

JavaScript

Transition & Animation 이벤트

Transition

자바스크립트의 클릭 이벤트를 사용해서 클릭한 위치를 확인할 수 있다. 

window.addEventListener("click", function (e) {
  console.log(e.clientX, e.clientY);
});

 

클릭한 위치에 동그란 오브젝트를 이동시키는 애니메이션을 만들려면 어떻게 해야할까? 

우선 동그란 오브젝트를 먼저 만들어주자면 다음과 같이 만들 수 있다. 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Event</title>

    <style>
      .ball {
        position: absolute;
        top: 0;
        left: 0;
        
        width: 30px;
        height: 30px;

        border-radius: 50%;
        background: red;

        transition: 1s;
      }
    </style>
  </head>
  <body>
    <div class="ball"></div>
    <script src="./event1.js"></script>
  </body>
</html>

너비와 높이가 30px인 붉은 공이다. 

그리고 애니메이션이 발생했을 때 진행되는 속도는 1초로 설정해두었다. 

const ballElem = document.querySelector(".ball");

window.addEventListener("click", function (e) {
  ballElem.style.transform = `translate(${e.clientX}px, ${e.clientY}px)`;
});

애니메이션은 자바스크립트로 화면을 클릭했을 때 클릭한 곳의 x축과 y축을 공의 transform을 통해서 설정해주었다. 

생각했던 애니메이션이 동작하는 것을 확인할 수 있다. 하지만 한가지 공의 중심이 마우스 포인트가 아니라 

좌측 상단을 기준으로 애니메이션이 동작한다. 

 

이것을 해결하기 위해서 tranform 값을 수정해주면 된다.

window.addEventListener("click", function (e) {
  ballElem.style.transform = `translate(${e.clientX - 15}px, ${
    e.clientY - 15
  }px)`;
});

오브젝트의 크기가 30px * 30px이기 때문에 절반인 15px을 빼주면 가운데로 포커스가 잡힌다. 

 

이벤트 중에는 재밋는 이벤트가 있는데, transitionend라는 이벤트다. 

이름 그대로 transition 이벤트가 끝났을 때 발동하는 이벤트이다. 반대인 transitionstart도 있다. 

...
      .end {
        background: blue;
      }
... 

## ===

ballElem.addEventListener("transitionend", function (e) {
  ballElem.classList.add("end");
});

transition 이벤트가 끝날 때 오브젝트에 end 클래스를 주게 설정했다. 

이벤트 객체에는 알아두면 의미있는 속성이 있는데, propertyName과 elapsedTime 속성이다. 

propertyName은 해당 이벤트가 발생한 원인이 되는 요소를 반환한다. 

transform과 background-color를 확인할 수 있는데, 오브젝트를 이동시키는 click 이벤트와 transitionend 이벤트를 통해서 오브젝트의 색상을 변경하는 이벤트에서 각각 호출되는 것을 확인할 수 있다. 

 

elapsedTime은 해당 요소에서 설정된 transition-delay를 나타낸다. css를 통해 transition: 1s를 설정했기 때문에 1이 반환된다. 

 

Animation 

<!DOCTYPE html>
<html lang="en">
  <head>
    // ...
    
    <style>
      @keyframes ball-ani {
        from {
          transform: translate(0, 0);
        }
        to {
          transform: translate(200px, 200px);
        }
      }

      .ball {
        position: absolute;
        top: 0;
        left: 0;

        width: 30px;
        height: 30px;

        border-radius: 50%;
        background: red;

        animation: ball-ani 1s 3;
      }

      .end {
        background: blue;
      }
    </style>
  </head>
  // ...
</html>

애니메이션 ball-ani를 만들고 오브젝트에게 0,0 위치에서 200px, 200px 위치로 이동시키는 애니메이션을 1초동안 실행하고 3번 반복하도록 값을 줬다. 

 

transition과 마찬가지고 animation도 시작할 때와 종료될 때 이벤트를 줄 수 있다. 

const ballElem = document.querySelector(".ball");

ballElem.addEventListener("animationend", function (e) {
  ballElem.classList.add("end");
});

사용 방법도 유사하다. 뒤에 end 또는 start를 넣어주면 애니메이션이 종료 & 시작될 때 호출된다. 

3번 애니메이션이 반복하고 오브젝트의 색상이 파란색으로 변경되는 것을 확인할 수 있다. 

애니메이션은 추가적으로 이벤트가 하나 더 있는데, animationiteration이라는 이벤트이다. 

ballElem.addEventListener("animationiteration", function (e) {
  console.log("반복중");
});

이름을 보면 알 수 있듯, 애니메이션이 반복될 때 호출되는 이벤트이다. 

앞서 css를 통해 애니메이션이 3번 반복되도록 설정했기 때문에 반복이 될 때마다 콘솔에 찍히는 것을 확인할 수 있다. 

 

3번 실행되기 때문에 콘솔은 반복을 하는 시점인 2번째부터 콘솔이 찍혀서 총 2개의 콘솔이 나온다. 

 

이처럼 transition과 animation은 단순 사용하는 것이 아닌 사용 전 후에 이벤트를 통해서 컨트롤이 가능하기 때문에 더 다양한 이펙트를 만들 수 있다. 

반응형

'JavaScript' 카테고리의 다른 글

Scope Chain과 Closure, HOF  (2) 2024.10.16
RequestAnimationFrame  (6) 2024.10.12
스크롤 위치에 따른 오브젝트 조작  (1) 2024.09.29
얕은 복사 & 깊은 복사  (3) 2024.09.25
Object  (1) 2024.09.21