requestAnimationFrame()

김혜성·2021년 7월 23일
0

프론트엔드

목록 보기
14/17

requestAnimationFrame()

: 브라우저에게 수행하기를 원하는 애니메이션을 알리고 다음 리페인트가 진행되기 전에 해당 애니메이션을 업데이트하는 함수를 호출

  • 최적화하여 애니메이션을 부드럽게 처리하는 기술
  • 캔버스에서 많이 사용
  • 인터랙티브 웹 개발에 필요

코드

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=<device-width>, initial-scale=1.0">
    <title>requestAnimationFrame</title>

    <style>
        html {
            height: 100%;
        }

        body {
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100%;
            margin: auto;
        }

        .jh {
            position: absolute;
            width: 100px;
            left: 50%;
            bottom: 0;
            margin-left: -50px;
        }

        .value {
            margin-top: -5rem;
            font-size: 7rem;
            font-weight: 100;
            text-align: center;
        }
    </style>
</head>

<body>
    <img class="jh" src="../requestAnimationFrame/jannabi.jpg" alt="잔나비">
    <div class="value">requestAnimationFrame</div>

    <script>
        const jh = document.querySelector(".jh");
        const value = document.querySelector(".value");

        /*
        requestAnimationFrame(() => {
            console.log(0);
        });
        console.log(1);
        */
        let yPos = 0;
        let rafId;
        function render() {
            value.innerHTML = yPos;
            jh.style.transform = `translateY(${-yPos}px)`;//컴퓨터그래픽에서는 위로 올라갈 때 -이다
            yPos += 10;

            rafId = requestAnimationFrame(render); //초당 60번반복(60프레임)

            if (yPos > 500) {
                cancelAnimationFrame(rafId);
            }
            //console.log(rafId);
        }
        render();
        window.addEventListener('click', () => {//클릭시 멈춤
            cancelAnimationFrame(rafId);
        });
    </script>
</body>

</html>

출력화면


y좌표가 500을 넘으면 cancelAnimatioFrame이 실행되는 모습

500을 넘기 전에도 화면을 클릭하면 cancelAnimationFrame이 실행되는 모습

흠냐

click했을 때 애니메이션이 멈추도록은 했는데, resume할 수도 있도록 해보고 싶었다. 그런데
window.addEventListner('click')으로 아래에 다른 코드를 쓰면 click 한 번으로 click에 해당하는 모든 이벤트가 다 수행이 되어 발동하지 않았다. 한번 click했을 때는 위의 cancelAnimationFrame()이, 다음 click에는 render()이 되도록 어떻게 할지 더 고민해봐야겠다.

당장은 click대신 keypress로 대체하여 클릭하면 멈추고 아무 키를 누르면 재개하도록 하였다

이 때에도 render()안에는 if문때문에 애니메이션이 멈추게 되어 if문을 제외한 코드들을 resume이라는 함수에 넣어서 이를 실행하도록 하였다

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=<device-width>, initial-scale=1.0">
    <title>requestAnimationFrame</title>

    <style>
        html {
            height: 100%;
        }

        body {
            display: flex;
            align-items: center;
            justify-content: center;
            height: 100%;
            margin: auto;
        }

        .jh {
            position: absolute;
            width: 100px;
            left: 50%;
            bottom: 0;
            margin-left: -50px;
        }

        .value {
            margin-top: -5rem;
            font-size: 7rem;
            font-weight: 100;
            text-align: center;
        }
    </style>
</head>

<body>
    <img class="jh" src="../requestAnimationFrame/jannabi.jpg" alt="잔나비">
    <div class="value">requestAnimationFrame</div>

    <script>
        const jh = document.querySelector(".jh");
        const value = document.querySelector(".value");
        //document.querySelector: 제공한 선택자와 일치하는 문서 내 첫 element 반환




        let yPos = 0;
        let rafId;
        function render() {
            value.innerHTML = yPos;
            jh.style.transform = `translateY(${-yPos}px)`;//컴퓨터그래픽에서는 위로 올라갈 때 -이다
            yPos += 10;

            rafId = requestAnimationFrame(render); //초당 60번반복(60프레임)
            //리미트
            if (yPos > 600) {
                cancelAnimationFrame(rafId);
            }



            //console.log(rafId);
        }
        function resume() {
            value.innerHTML = yPos;
            jh.style.transform = `translateY(${-yPos}px)`;//컴퓨터그래픽에서는 위로 올라갈 때 -이다
            yPos += 10;

            rafId = requestAnimationFrame(resume); //초당 60번반복(60프레임)
        }
        render();
        //클릭시 멈추도록
        window.addEventListener('click', () => {
            cancelAnimationFrame(rafId);
        });

        window.addEventListener('keypress', () => {
            resume();
        });


    </script>
</body>

</html>

2상

출처

https://www.youtube.com/watch?v=9XnqDSabFjM

profile
똘멩이

0개의 댓글