본문 바로가기
JS

VanillaJS로 웹서비스 만들기 - 중간 검토1

by 케찹이 2024. 3. 3.

HTML, CSS3, Javascript ES6까지 기본적인 개념을 배우고, 토이프로젝트까지 진행하였지만 구글링 그리고 여러 자료를 통해서 CSS  JS의 탄탄한 기본 개념이 신입을 뽑을 때 보는 중요한 요소라고 하여 이제까지 배운 바닐라JS으로만 하나의 괜찮은 서비스를 만들어보기로 하였다.

 

막상 프로젝트를 하다 보니 구현하고 싶은 기능들도 많고 해서 제작 기간이 점점 늘어나고 있지만 그만큼 많이 배우고 완성도 있는 프로젝트를 만들 수 있다고 생각이 든다.

 

주제

일단 이번 프로젝트의 주제는 축구 퀴즈 사이트이다. 지난 1년동안 재미있는 퀴즈 사이트가 많이 생겼다고 생각이 든다. 평소에 유튜브를 보면 재미있는 퀴즈 사이트를 통해 방송을 하는 유튜버들도 많았고 실제로 플레이해봤을 때 재미있는 경험을 했다. 나는 평소에 축구를 즐겨보기 때문에 축구에 집중된 퀴즈 사이트를 만들어보고 싶어하였기 때문에 이번에 축구 퀴즈 사이트를 주제로 잡고 프로젝트를 시작했다.

 

진행 상황

- 대문 구조, navbar 구현

- 대문 animation 구현

- 반응형 navbar 구현

- 프론트에서의 라우팅 구현

 

지금까지 진행한 상황에 대해서 좋았던 점을 먼저 되돌아보자면 이전 토이 프로젝트를 진행하면서 display나 position을 사용했을 때의 어려움을 겪어서 다시 학습을 하고 해당 프로젝트를 진행했는데 효과가 있었다. 해당 프로젝트에서 display, position과 같은 레이아웃을 구현할 때에 크게 겪은 어려움은 없었다. 덕분에 대문 구조와 navbar정도는 빠른 시간안에 구현할 수 있었다.

 

animation 구현

 

그 다음으로 구현했던 것은 대문 animation이다. 지금까지 좋은 디자인의 사이트를 배워보려고 다양한 사이트를 참고했었는데 와우... 정말 말도 안되는 animation들이 있었다. 그렇기 때문에 animation을 많이 사용해봤었고 내가 직접 제작했던 첫 애니메이션 효과는 사용자들이 퀴즈를 풀고 싶게 하는 문구들이 일정 속도로 화면 왼쪽에서 오른쪽으로 지나가는 효과이다.

 

 

위 효과를 구현하면서 배운것을 생각해보면 일단 첫번째로 CSS의 custom properties에 대해서 알았다. 사실 custom properties의 원래 의도대로 사용한것은 아니긴 하다.

원래의 의도는 자주 사용하는 값, 예를 들어서 배경 색깔의 값은 대부분 복잡한 숫자 형태이기 때문에 자주 쓰는 색상인 경우 custom properties으로 마치 변수처럼 값을 저장해서 꺼내쓰는 걸로 알고 있다. 

그치만 내가 이번에 해당 속성을 사용하게 된 이유는 움직이는 문장이 딱 페이지의 오른쪽에 닿는 그 순간 사라지기 위해서 계산을 하기 위해서 사용하였다.

 

@keyframes move {
  0% {
    transform: translateX(0);
    opacity: 0;
  }
  40% {
    opacity: 1;
  }
  80% {
    transform: translateX(calc(100vw - var(--span-width, 900px)));
    opacity: 0;
  }
  100% {
    transform: translate(0, 0);
    opacity: 0;
  }
}

 

위 코드는 해당 애니메이션을 적용한 css이다. 80%일때의 값을 보면 calc라는 함수 안에 100vw에다가 var(--span-width)만큼 빼고 x축으로 이동하라고 설정을 한것이다. 이때 var(--span-width)가 custom속성이고 해당 값이 존재하지 않으면 옆의 900px이 넣어진다. 그리고 --span-width는 움직이는 문장의 width이다. 

이 계산을 하는 이유는 정확하게 계산하지 않을 경우 애니메이션이 적용된 문장이 보이는 창을 뚫고 지나간다, 그러면 화면 밑에 없던 스크롤바가 생기는데 그게 굉장히 눈에 거슬리다.

 

사실 위의 애니메이션에는 작은 fake가 있는데 바로 100%일때의 상황이다. translate(0,0) 그리고 opacity: 0. 바로 문장이 투명해지고 0, 0의 위치로 이동한다는 것. 즉! 문장이 끝에 가면 실제로 사라지는 것이 아니고 투명도만 활성화하고 계속 존재한다는 것이다. 그렇기 때문에 조금 브라우저에 어떤 복잡한 일만 해도 애니메이션이 버벅거리는 현상이 나타난다. 이 부분은 꼭 추후에 수정할 예정이다.

 

그 다음으로 해당 애니메이션을 만드면서 느꼈던 점은 바로 javascript 활용 능력을 늘릴 수 있었다. 해당 애니메이션을 구현할때 또 하나의 고민했던 것은 어떻게 해야지 해당 문장들이 같은 자리가 아닌 매번 다른 위치에서 애니메이션을 시작할 수 있게 할까? 였다. 그 부분을 구현하기 위해서 javascript을 적극 활용했어야 했다. 

이때 해당 element의 위치를 가져오고 style의 속성을 고치고 Math.random()을 활용하여 top에서 부터 얼만큼 떨어지게 하는지를 구현할 수 있었고 또 그외에도 animation-delay를 설정하고, addEventListener에서는 'animationIteration'이 일어날때 설정값을 변하게 하는 함수를 정해야 한다는 것도 알수 있었다.

 

수정해야 하는 부분은 문장들이 중복되는 경우이다. 해당 애니메이션을 잘 살펴보면 서로 겹치는 때가 있다. 처음에는 해당 문제를 너무 간단하게 생각해서 애니메이션의 바로 전후와의 y축 위치를 고려해서 높이를 설정하였는데 delay가 되는 문장같은 경우는 중복이 되어버렸다. 해당 문제도 추후에 수정해야할 사항이다.

 

반응형 navbar

여기는 사실 거의 90프로 유튜브의 반응형 navbar를 참고했기 때문에 딱히 할말이 없긴하다. 다만 이전까지 반응형을 구현하지 않은 이유는 반응형을 구현하는게 좀 많이 복잡하다고 생각이 들었기 때문이다. 어느 정도 사실은 맞겠지만 이번 구현을 통해서 해당 부분에서도 자신감을 얻게 되었다. 그리고 언제 적절한 크기 단위를 써야 하는지도 알게 된것 같다. 대문의 타이틀에 처음에 단순 px로 설정하였는데 당연스럽게 반응형을 적용하면서 em으로 단위를 바꿨다. 

 

 

프론트에서의 라우팅 구현

사실 이 부분이 여태까지 제일 고민을 많이 했던 부분이다. 기술적으로 배우는데에도 많이 시간이 쓰였지만 이 프로젝트를 여기서 멈출까하게 되는 부분이었다. 물론 지금도 배우기는 했고 구현을 하기는 했지만 100프로 이해하고 아무 참고없이 구현할 수 있을 정도는 아니다.

 

원래 처음에 알고 있는 라우팅 방법은 그저 단순히 새로운 html파일을 a태그로 불러오는 것이다. 근데 리액트JS이든 VueJS이든 해당 프레임워크에서는 절대로 절대로 이런 단순한 방식을 사용하지 않는다. 그래서 지금 라우팅은 거의 다 Single Page Application방식을 사용하고 말 그대로 하나의 페이지에서 모든 변화가 일어난다고 이해하면 된다.

 

SPA의 방식은 앞서 말한 가장 클래식한 방법외에 ajax, hash, 그리고 pjax방식이 있으며 리액트JS에서는 pjax방식으로 라우팅을 구현해놓았다고 하고 실제로 구현의 난이도를 제외하고 pjax는 ajax와 hash의 장점은 흡수하고 단점을 없앴다. pjax는 ajax방식에 History API인 pushState, popState를 사용한 것이라고 한다. 

 

그래서 일단 최대한 코드를 이해하면서 라우팅 부분까지 구현해 놓은 상태이다.

 

앞으로 할거

앞으로 할거를 몇가지 계획해 놓았다.

1. 서버 구현 (백엔드)

2. 문제 만들기 페이지 구현

3. 문제 풀기 페이지 구현

4. 편의 검색 기능 구현

5. 문의 페이지 구현

6. 배포

 

일단 pjax가 잘 작동하는지 확인을 할려면 백엔드 코드가 필요하다. 그래도 나는 백엔드를 다뤄본 경험이 있어서 빠른 시간에 학습해서 구현해볼 수 있을 것 같다.

 

문제 만들기 페이지와 문제 풀기 페이지를 구현하는게 꽤 어려울 듯하다. 사실 축구 퀴즈 중에는 포메이션을 참고하고 문제를 푸는 경우가 굉장히 많다고 생각해서 포메이션의 위치를 정형화하면 사용자가 문제를 쉽게 만들수 있을 것 같다라고 생각이 들었고 또 나중에 db에 문제를 저장할 때에는 어떤 식으로 저장할 지에 대한 고민을 하고 있고 그 저장한 문제를 db에서 어떻게 꺼내올지 이러한 모든 것들을 기획하고 구현하는데 시간이 꽤 걸릴 수 있을 것 같다.

 

다음으로는 편의 검색 기능이다. 기존 퀴즈 사이트의 문제들은 엄격한 답변 시스템이다. 주관식의 문제일 경우 해당 시스템에 등록되어있는 답이 아닐 경우 답으로 인정되지 않는다. 그렇기 때문에 단순한 철자나 아니면 외국인의 이름 같은 경우는 발음은 비슷하지만 관리자가 등록하지 않은 답변일 경우 오답처리가 되어 좋지 않은 사용자 경험을 할 수 있다고 생각이 되어 이러한 점을 해소할 수 있는 편의 검색 기능을 제공하여 시스템에 저장되어있는 답을 사용자의 의도되로 답변할 수 있게 도와주는 기능이다. 

 

문의 페이지 같은 경우는 간단한 이메일으로 연락이 올 수 있는 기능을 구현하면 된다.

 

배포 같은 경우는 사실 개발자로 배우면서 한번도 제대로 배워본 적이 없는 부분이기 때문에 조금 공부가 필요하다고 생각이 든다.

 

리액트JS를 현재 배우고 있지만 바닐라JS에 대한 이해도를 높이는 것이 먼저라고 생각되는 동시에 리액트JS나 그 이후의 내용들도 빨리 배우고 싶다는 생각이 든다. 그치만 제일 중요한 것은 불안해하지 않고 꾸준히 개발을 하는 것이라고 생각이 든다. 이번 프로젝트는 꼭 끝까지 배포하면서 마무리해보고 싶다. 이태까지 아쉬웠던 부분들도 많고 구현하고 싶은 부분들도 많다, 한번 열심히 해보자.

댓글