three.JS를 공부하며 새로 배우게 된 requestAnimationFrame
함수에 대해서 정리해두려고 한다!
MDN에서는 아래와 같이 설명되어 있다!
📎 MDN 참고
window.requestAnimationFrame()
메서드는
브라우저에게 수행하기를 원하는 애니메이션을 알리고
다음 리페인트 바로 전에 브라우저가 애니메이션을 업데이트할 지정된 함수를 호출하도록 요청합니다.
이 메서드는 리페인트 이전에 호출할 인수로 콜백을 받습니다.
간단하게 말하자면 브라우저가 애니메이션을 작업 할 때 매번 화면을 그리게 되는데
변화된 화면을 그릴 준비가 완료가 되었을 때 딱! 그려준다고 생각하면 된다.
이미지를 최적화 해서 애니메이션을 부드럽게 처리할 수 있는 기술이라고 보면 된다.
이와 비슷한 기능으론 setInterval
기능이 있는데 setInterval
은
프레임 유실이나 모바일 기기에서 배터리 절약이 안되는 단점이 있어서
requestAnimationFrame
를 더 많이 쓰게되었다!
코드를 들어가기 전에 requestAnimationFrame
의 경우에는
전역에서 바로 사용할 수 있는 함수이며, window
의 메서드입니다.
( 예시: alert, setTimeout, document )
전역 스코프에서는 window.를 생략해도 자동으로 참조되므로 아래와 같이 코드를 작성해도 된다.
<img class="rocket" src="./rocket.img" alt="로켓이미지">
<div class="value">requestAnimationFrame</div>
<script>
const rocket = document.querySelector('.rocket');
const value = documnet.querySelector('.value');
requestAnimationFrame.(()=>{
console.log(0); ⭐️
})
console.log(1); ⭐️
</script>
위의 코드에서 두개의 콘솔⭐️ 있는데 이와 같이 작성하게 되면
콘솔창에서는 1이 먼저 노출되고 그 다음에 0이 나타난다.
여기서 알 수 있는 건 requestAnimationFrame
는 지연효과가 있는 것으로 확인된다!
<img class="rocket" src="./rocket.img" alt="로켓이미지">
<div class="value">requestAnimationFrame</div>
<script>
const rocket = document.querySelector('.rocket');
const value = documnet.querySelector('.value');
let yPos = 0;
function render(){
value.innerHTML = yPos;
yPos++;
}
render();
</script>
yPos라는 0이라는 값을 가진 변수를 선언하고, render함수를 생성해
value에 yPos를 innerHtml을 사용하여 추가한다. 그리고 yPos의 값은 1씩 추가되도록 한다.
그러고 페이지를 확인하면 .value의 값이 0으로 변환된 모습이 확인 가능하다.
1씩 추가되지 않은 건 render 함수가 반복 실행이 되지 않았기 때문인데
이제 이 render 함수를 빠르게 반복시키기 위해 requestAnimationFrame
를 사용하자!
<script>
const rocket = document.querySelector('.rocket');
const value = documnet.querySelector('.value');
let yPos = 0;
function render(){
value.innerHTML = yPos;
yPos++;
requestAnimationFrame(render);⭐️
}
render();
</script>
이렇게 requestAnimationFrame
에 render라는 함수를 실행!
웹페이지에서 보면 0에서 빠르게 숫자가 1씩 더해지는걸 볼 수 있다!
requestAnimationFrame
는 초당 60번을 목표로 하고있다
컴퓨터의 상황이나 성능에 따라 속도는 상이하게 나타날 수 있다!
<script>
const rocket = document.querySelector('.rocket');
const value = documnet.querySelector('.value');
let yPos = 0;
function render(){
value.innerHTML = yPos;
rocket.style.transform = 'translateY(${-yPos}px)'; ⭐️
yPos += 10; ⭐️
requestAnimationFrame(render);
}
render();
</script>
일단 yPos값을 1씩하면 너무 애니메이션이 눈에 띄지 않기에 10으로 변경,
rocket의 스타일 transform에서 translateY 값을 yPos로 지정!
코드에서 ${-yPos}처럼 사용하는 이유는 문자열 안에서 변수를 값처럼 삽입하기 위해서다.
이 문법은 템플릿 리터럴(Template Literal)이라고 부르고, 자바스크립트의 문자열 처리 방식 중 하나이다.
이 처럼 코드를 실행하면 로켓트가 위로 슈우우우웅 하고 올라가는걸 확인 가능하다!
requestAnimationFrame
를 멈추게 하는 메서드
<script>
const rocket = document.querySelector('.rocket');
const value = documnet.querySelector('.value');
let yPos = 0;
function render(){
value.innerHTML = yPos;
rocket.style.transform = 'translateY(${-yPos}px)';
yPos += 10;
let cancel = requestAnimationFrame(render);⭐️
console.log(cancel);
if(yPos > 500){
cancelAnimationFrame(cancel);⭐️
}
}
render();
</script>
requestAnimationFrame
가 특정 높이가 되었을 때 멈추게 하고싶다!
일단 cancel이라는 변수를 만들어 requestAnimationFrame(render);
를 옮겨 넣는다!
requestAnimationFrame();
자체가 어떠한 리턴값을 갖고 있는 상황이니까 cancel이라는 변수를 사용하여 사용성을 높여준것!
그 후에 콘솔로 cancel를 확인해보면 동일하게 콘솔창에 숫자가 0에서 1씩 값이 증가하는걸 볼 수가 있다!
이제 조건문을 사용해서 yPos값이 500보다 커지게 된다면
requestAnimationFrame
가 작동되지 않도록 하고싶다!
그때 사용하는 것이 바로 cancelAnimationFrame
이다!!
cancelAnimationFrame
메서드에 cancel이라는requestAnimationFrame
변수를 넣어준다면!
yPos값이 500이 되는 시기때 transform 기능이 정지된다!
아래와 같이 클릭 이벤트를 실행할 때 cancelAnimationFrame
기능을 사용케도 가능!
<script>
window.addEventListener('click',() => {
cancelAnimationFrame(cancel);
})
</script>
📎 참고 유투브를 보고 작성한 것으로,
이해가 어렵다면 유투브를 보면 더 이해하기가 쉽다!