[JS] 인터랙티브 애니메이션과 requestAnimationFrame

·2022년 10월 26일
0

JavaScript

목록 보기
24/25
post-thumbnail
  • div 태그로 상자를 하나 만들고 키보드의 화살표 키를 눌러 왼쪽, 오른쪽으로 이동하도록 만들어 보세요.

    <style>
        .target {
            width:100px;
            height: 100px;
            background-color:cornflowerblue;
            margin: 0 auto;
            transition: 0.2s;
        }
    </style>
</head>
<body>

    <div class="target"></div>

    <script>

        const target = document.querySelector('.target');
        let posX = 0;
        let posY = 0;

        document.addEventListener('keydown', move);

        function move(event) {
            const keyName = event.key;
            // console.log(keyName);
            // 현재 무슨 키(프로퍼티)를 사용하는지 키네임에 저장된다 
            if (keyName === 'ArrowRight') {
                posX += 20;
                target.style.transform = `translateX(${posX}px) translateY(${posY}px)`;
            }
            if (keyName === 'ArrowLeft') {
                posX -= 20;
                target.style.transform = `translateX(${posX}px) translateY(${posY}px)`;
            }
            if (keyName === 'ArrowUp') {
                posY -= 20;
                target.style.transform = `translateX(${posX}px) translateY(${posY}px)`;
            }
            if (keyName === 'ArrowDown') {
                posY += 20;
                target.style.transform = `translateX(${posX}px) translateY(${posY}px)`;
            }
        }
    </script>
</body>

const target = document.querySelector('.target');
let posX = 0;
let posY = 0;

박스 위치를 나타낼 초기값 XY 따로 설정! 값이 변하니까 let

document.addEventListener('keydown', move);

우리가 문서 자체에서 키보드를 누르기 때문에 요소에만 넣어주는 게 아니라 도큐먼트 자체에 리벤트 리스너를 넣어준다
document는 문서 자체이고 window는 최상위 객체라 여기선 둘 다 적용해도 괜찮다
이벤트 리스너에는 두가지 인자가 필수! 이벤트, 리스너 함수(or 핸들러, 콜백함수... 너 어떤 이벤트 넣을거야?)

function move(event) {
const keyName = event.key;
if (keyName === 'ArrowRight') {
posX += 20;
target.style.transform = translateX(${posX}px) translateY(${posY}px);
}

event 이벤트가 일어날 때마다 자동적으로 저장되는 객체! e로도 많이 쓰는데 event 줄임말
이벤트 객체는 이벤트가 발생됐을 때 자동으로 리스너 함수의 첫번째 인자로 들어가게 된다
keydown이라면 keydown에 대한 이벤트객체를 가져오고 click이라면 click에 대한 이벤트객체를 가져온다~ 여기선 event에 keydown에 대한 이벤트 객체 들어간다

target.style.transform = translateX(${posX}px) translateY(${posY}px

돔에서 선택한 target이라는 애한테 스타일을 줄거야~ 그게 transform이라는 속성이야~ 그 값으로 이걸 넣어줄거야~
xy 둘 다 주는 이유?
y값이 없다면 오른쪽 버튼을 누르고 실수로 위아래 키를 누른다면 초기값으로 돌아가는 불상사 방지!
좌우만 하면 X 값만 넣고 상하만 하려면 Y 값만 넣어도 작동되는데 좌우상하 다 움직이려면 XY 다 줘야함! 막 움직이여야하니까 누적된 Y 값도 가져오자

requestAnimationFrame

간단하게 좌우로 박스를 움직이는 애니메이션을 requestAnimationFrame을 이용해 만들어보자!

왜? 소프트웨어 프로그래밍은 일단 동작하게 만들고(Make it work), 올바르게 동작하게 만들고(Make it right), 빠르게 동작하게 만든다(Make it fast)
이때 중요한 게 반응 시간! 사용자의 행동에 얼마나 빠르게 반응 하는가를 판단하는것~
requestAnimationFrame을 사용하면 애니메이션을 최적화할 수 있다.
- requestAnimationFrame : 브라우저가 애니메이션을 최적화 하도록 하고, 비활성 탭에서는 애니메이션이 동작하지 않도록 합니다.

window.requestAnimationFrame(callback);


<style>
    .target {
        width:100px;
        height: 100px;
        background-color:cornflowerblue;
        margin: 0 auto;
        /* 이 함수에서는 움직임이 트랜지션 있으면 오히려 방해됨! */
    }
</style>
<body>

    <div class="target"></div>

    <script>

        const target = document.querySelector('.target');
        let pos = 0;

        // 사용자가 누르는 키의 상태를 저장하는 객체
        let keys = {};
        // ArrowLeft: true; 같이 저장된다 ..?

        function move(event) {
            keys[event.key] = true;
        }

        function stop(event) {
            keys[event.key] = false;
        }

        document.addEventListener('keydown',move);
        document.addEventListener('keyup',stop); // 작동 중단 ~


        function play() {
            // console.log('play!'); 작동되는지 확인

            if(keys.ArrowRight) {
                pos += 2;
                target.style.transform = `translateX(${pos}px)`;
            }

            if(keys.ArrowLeft) {
                pos -= 2;
                target.style.transform = `translateX(${pos}px)`;
            }

            window.requestAnimationFrame(play);
        }

        window.requestAnimationFrame(play);

        // 콜백지옥..!! 근데 안정적이라서 가만히 놔둬도 됨~ 다른 창 갔다가 오면 멈췄다가 다시 실행됨
        // 게임에선 세계가 계속 살아움직여야하기 때문에 게임 만들때 실행시키는 함수 ... 
        // 이 함수가 어떤 대상의 정보를 계속 체크할 수 있다는 의미 : 사용자가 이벤트를 발생시켰을 때 보고 있다가 변화가 생기면 바로 대응할 수 있다는 것 

    </script>

</body>
function play() {
       console.log('play!'); 
       // 작동되는지 확인
 window.requestAnimationFrame(play);
        }

window.requestAnimationFrame(play);

콜백지옥..!!
근데 안정적이라서 가만히 놔둬도 된다
다른 창 갔다가 오면 멈췄다가 다시 실행됨
게임에선 세계가 계속 살아움직여야하기 때문에 게임 만들때 실행시키는 함수 ...
이 함수가 어떤 대상의 정보를 계속 체크할 수 있다는 의미
사용자가 이벤트를 발생시켰을 때 보고 있다가 변화가 생기면 바로 대응할 수 있다는 것 !

profile
주니어 프론트엔드 웹 개발자 🐛

0개의 댓글