web

[interactive web] 스크롤 다루기/ 이벤트- transition, animation/ 타이밍 제어

Jaaaay 2022. 8. 22. 17:47

스크롤 다루기

(function () {
        const outputElem = document.querySelector(".output");
        window.addEventListener("scroll", function () {
          outputElem.innerHTML = window.pageYOffset;
        });
      })();

window.pageYOffset 속성으로 페이지 Y축 픽셀 위치를 얻을 수 있다.

(function () {
        const outputElem = document.querySelector(".output");
        const ilbuniElem = document.querySelector(".ilbuni");

        window.addEventListener("scroll", function () {
          // outputElem.innerHTML = window.pageYOffset;
          // outputElem.innerHTML = ilbuniElem.offsetTop;
          outputElem.innerHTML = ilbuniElem.getBoundingClientRect().top;
        });
      })();

.getBoundingClientRect() 메서드를 통해 특정 엘리먼트의 위치를 파악할 수 있다.

(function () {
        const outputElem = document.querySelector(".output");
        const ilbuniElem = document.querySelector(".ilbuni");

        function showValue() {
          // outputElem.innerHTML = window.pageYOffset;
          // outputElem.innerHTML = ilbuniElem.offsetTop;
          let posY = ilbuniElem.getBoundingClientRect().top;
          outputElem.innerHTML = posY;

          if (posY < window.innerHeight * 0.2) {
            ilbuniElem.classList.add("zoom");
          }
        }

        window.addEventListener("scroll", function () {
          showValue();
        });
      })();

window.innerHeight 를 통해 현재 창의 높이를 알 수 있다.


Transition 이벤트

click 이벤트에서

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

e.clientX 와 e.clientY 속성으로 클릭 좌표를 알 수 있음.

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

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

특정 엘리먼트의 위치 변경하기

ballElem.addEventListener("transitionend", function (e) {
	ballElem.classList.add("end");
	console.log(e.elapsedTime); // transition-duration
	console.log(e.propertyName); // 바뀐 속성 출력
});

transitionend 또는 transitionstart 이벤트를 통해 트랜지션이 시작하거나 끝날 때 이벤트 리스너를 설정 가능하다.

Animation 이벤트

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

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

마찬가지로 animationend 또는 animationstart 이벤트를 통해 애니메이션이 시작하거나 끝날 때 이벤트 리스너를 설정 가능하다.

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

animationiteration 이벤트를 통해 애니메이션이 반복될 때마다 이벤트 리스너를 설정 가능하다.


타이밍 제어하기

setTimeout()

let timeId;
		const btn = document.querySelector('.btn');

		function sample() {
			console.log('sample!');
		}

		timeId = setTimeout(sample, 3000);

		btn.addEventListener('click', function () {
			clearTimeout(timeId);
		});

setTimeout 은 숫자로 된 반환값을 가진다.

이를 clearTimeout() 에 전달하면 동작을 취소할 수 있다.

setInterval()

let timeId;
		const btn = document.querySelector('.btn');

		function sample() {
			console.log('sample!');
		}

		timeId = setInterval(sample, 1000/60);

		btn.addEventListener('click', function () {
			clearInterval(timeId);
		});

마찬가지로 clearInterval() 을 통해 동작을 취소 가능하다.

requestAnimationFrame

setInterval의 단점을 보완

let timeId;
		let n = 0;
		const btn = document.querySelector('.btn');

		function sample() {
			n++;
			console.log(n);
			if (n > 200) {
				return;
			}

			timeId = requestAnimationFrame(sample);
		}

		sample();

		btn.addEventListener('click', function () {
			cancelAnimationFrame(timeId);
		});

마찬가지로 cancelAnimationFrame() 을 통해 취소 가능.

함수 실행을 1초에 60번 반복을 목표로 하므로 시간 조절을 원한다면

		function sample() {
			n++;
			if(n % 60) {
				console.log('1초 경과');
			}
			if (n > 200) {
				return;
			}

			timeId = requestAnimationFrame(sample);
		}

		sample();

이런 식으로 응용 가능하다.

또한 스택에 쌓이는 것이 아니라 tick 마다 실행되는 방식이다.