인프런 커뮤니티 질문&답변

camellip님의 프로필 이미지

작성한 질문수

인터랙티브 웹 개발 제대로 시작하기

전진! 3D 스크롤 26

키다운-업 연속 시 캐릭터에 .running class

작성

·

275

0

안녕하세요 강사님.

26강까지 다 듣고, 강사님이 주신 원본이랑 비교까지 다 했는데도 궁금한 점이 있어서요!

다름이아니라,

제 파일에서 키다운 이벤트 시, 키코드 37번과 39번은 문제없이 작동하는데, 위 아래 키보드를 클릭하면 running클래스가 랜덤하게 작동합니다.

1. forward 시에 running클래스 정상작동, 얼마 안가서 backward시 running이 붙지 않고, 돌아옵니다.

2. forward로 끝까지 갔다가 backward시에는 running이 붙었다가 중간에 또 forward와 backward를 반복하면 running이 붙지 않은채 움직입니다.

원본 파일에서 개발자 코드를 켜놓고 character 클래스를 볼 때도, forward에는 running이 붙다가 backward에는 running이 붙지 않고 돌아오는데, 이 부분 해결방법 여쭤봅니다.

저는 크롬이랑, 웨일에서 개발자도구를 실행시켰습니다.

감사합니다!

답변 6

0

1분코딩님의 프로필 이미지
1분코딩
지식공유자

네 스크롤은 원래 위아래 키를 누르면 자동으로 동작하는거라서 동시에 발생을 합니다.
아참 수강평도 감사드려요 camellip님! ^^

0

camellip님의 프로필 이미지
camellip
질문자

넵! 감사합니다. keypress로 해보겠습니다.

강사님 하나만 더 여쭤볼게 있는데요.

원래 키다운 이벤트는 ← → 두 키만 window.addEventListener('keydown', ...)적용하고,

위 아래 키다운은 스크롤 이벤트에 같이 포함되어 적용되는거 맞지요?

왼쪽 오른쪽은 키다운이벤트에 문제가 없는데, 위아래만 계속 오류가 나서요 ㅠㅠ

0

1분코딩님의 프로필 이미지
1분코딩
지식공유자

아.. 아니면 'keydown' 대신 'keypress'로 해보시겠어요?
키보드 이벤트가 환경이나 브라우저에 따라 조금씩 차이가 있어서 그런 문제일 수도 있을 것 같습니다.
여러 환경에서 테스트를 거친 코드이긴 한데, 제가 체크하지 못한 경우가 있을 수도 있으니..
현재는 제가 테스트 할 수 있는 환경에서는 딱히 문제가 없어서,
저도 다른 곳에 갈 때 웨일 브라우저에서도 돌려보고 하면서 테스트를 좀 해보겠습니다~

0

camellip님의 프로필 이미지
camellip
질문자

제가 크롬이랑 웨일 브라우저에서 테스트 진행 중인데, 제 브라우저 환경이 이상한건지 강사님 파일 그대로 내려받아서 [index.html] 실행해도 키-업, 키-다운 이벤트(앞서 말씀드린 것과 같은) 오류가 발생합니다ㅠㅠㅠ

0

camellip님의 프로필 이미지
camellip
질문자

Character.js 파일 드립니다.

//생성자 함수
function Character(info) {
    this.mainElem = document.createElement('div');
    this.mainElem.classList.add('character');
    this.mainElem.innerHTML = ''
        + '<div class="character-face-con character-head">'
            + '<div class="character-face character-head-face face-front"></div>'
            + '<div class="character-face character-head-face face-back"></div>'
        + '</div>'
        + '<div class="character-face-con character-torso">'
            + '<div class="character-face character-torso-face face-front"></div>'
            + '<div class="character-face character-torso-face face-back"></div>'
        + '</div>'
        + '<div class="character-face-con character-arm character-arm-right">'
            + '<div class="character-face character-arm-face face-front"></div>'
            + '<div class="character-face character-arm-face face-back"></div>'
        + '</div>'
        + '<div class="character-face-con character-arm character-arm-left">'
            + '<div class="character-face character-arm-face face-front"></div>'
            + '<div class="character-face character-arm-face face-back"></div>'
        + '</div>'
        + '<div class="character-face-con character-leg character-leg-right">'
            + '<div class="character-face character-leg-face face-front"></div>'
            + '<div class="character-face character-leg-face face-back"></div>'
        + '</div>'
        + '<div class="character-face-con character-leg character-leg-left">'
            + '<div class="character-face character-leg-face face-front"></div>'
            + '<div class="character-face character-leg-face face-back"></div>'
        + '</div>';
    
    document.querySelector('.stage').appendChild(this.mainElem);
    
    //console.log(info.xPos);
    this.mainElem.style.left = info.xPos + '%';
    this.scrollState = false; //스크롤 중인지 아닌지
    this.lastScrollTop = 0; //바로 이전(마지막) 스크롤 위치
    this.xPos = info.xPos;
    this.speed = info.speed;
    this.direction;
    this.runningState = false; //좌우 이동중인지
    this.rafId;
    this.init();
    
};

Character.prototype = {
    constructer : Character,
    init : function () { //init함수 다시 공부하기 <스크롤 20강의>
        const self = this;
        
        window.addEventListener('scroll', function () {
            clearTimeout(self.scrollState);
            
            if (!self.scrollState) {
                self.mainElem.classList.add('running');
                //console.log('running!')
            }
            
            self.scrollState = setTimeout(function () {
                self.scrollState = false;
                self.mainElem.classList.remove('running');
            }, 500);
            
            //console.log(self.lastScrollTop + '!');
            //console.log(pageYOffset);
            
            //이전 스크롤 위치와 현재 스크롤 위치를 비교
            if (self.lastScrollTop > pageYOffset) {
                //이전 스크롤 위치가 크다면: 스크롤 올림
                self.mainElem.setAttribute('data-direction', 'backward');
            } else {
                //현재 스크롤 위치가 크다면: 스크롤 내림
                self.mainElem.setAttribute('data-direction', 'forward');
            }
            
            self.lastScrollTop = pageYOffset;
        });
        
        window.addEventListener('keydown', function (e) {
            //키다운이 반복실행되어 캐릭터가 가속되는 것을 방지하기 위해
            if (self.runningState) return;
            console.log(self.runningState);
            //console.log('키다운');
            if (e.keyCode == 37) {
                //왼쪽
                self.direction = 'left';
                self.mainElem.setAttribute('data-direction', 'left');
                self.mainElem.classList.add('running');
                self.run(self);
                self.runningState = true;
                console.log(self.runningState);
                
                //**기존**
                //속도라는 변수를 만들어서 xPos의 %값을 키보드를 누를 때마다 속도만큼 반영시킴
//                self.xPos -= self.speed;
                
                //현재 좌표를 다시 대입
//                self.mainElem.style.left = self.xPos + '%';
            } else if (e.keyCode == 39) {
                //오른쪽
                self.direction = 'right';
                self.mainElem.setAttribute('data-direction', 'right');
                self.mainElem.classList.add('running');
                self.run(self);
                self.runningState = true;
                console.log(self.runningState);
            }
        });
        
        window.addEventListener('keyup', function (e) {
            self.mainElem.classList.remove('running');
            cancelAnimationFrame(self.rafId);
            self.runningState = false;
            console.log(self.runningState);
        });
    },
    //requestAnimationFrame : 바로 키다운 이벤트에 함수를 넣으니, 캐릭터가 뚝뚝 끊기면서 이동하는 오류가 있어서 사용
    //해결방법
    run : function (self) {        
        if (self.direction == 'left') {
            self.xPos -= self.speed;
        } else if (self.direction == 'right') {
            self.xPos += self.speed;
        }
        
        if (self.xPos < 2) {
            self.xPos = 2;
        } else if (self.xPos > 88) {
            self.xPos = 88;
        }
 
        self.mainElem.style.left = self.xPos + '%';
        
        self.rafId = requestAnimationFrame(function () {
            self.run(self);
        });
    }
    
};

0

1분코딩님의 프로필 이미지
1분코딩
지식공유자

이 부분은 코드를 보아야 알 수 있을 것 같습니다^^
코드 올려주시면 한번 살펴볼게요!

camellip님의 프로필 이미지

작성한 질문수

질문하기