[패스트캠퍼스] 프론트엔드 취업 완성 과정 3기 - 오버워치 클론 프로젝트 회고

JYROH·2022년 9월 23일
1

이번주에 CSS강의를 다 마쳤습니다. 제대로 공부해본적이 한번도 없고 그때그때 인터넷에 떠돌던 코드를 복붙해와서 사용하던 저였는데 이번기회를 통하여 한번 제대로 깊게 파본것같아 뿌듯한 기분이 듭니다. 그러나 역시 공부는 이론으로만 하는게 아니죠. 무언가를 만들어봐야 그것을 제걸로 만들수 있는것 같습니다.

클론 프로젝트


본 글에서 나오는 오버워치 클론 프로젝트의 출처는 모두 박영웅 강사님의 "초격자 패키지: 한번에 끝내는 프론트엔드 개발" 입니다.
클론 프로젝트라는 말은 개발분야에서 자주 쓰이는것 같습니다. 표절과 저작권에 예민했던 학교 과제에서는 한번도 본적이 없었습니다. 그러나 HTML/CSS 나아가 JS까지 웹에서 실제로 어떻게 사용되는지 이해를 하기 위해서는 굉장히 좋은 공부 방법이라고 들었습니다.

저는 코드 따라치기를 좋아하지 않습니다. 솔직히 말하면 굉장히 싫어합니다. 물론 처음 배우는 입장에서 어느정도 강사님께서 말해주시는 것들을 그대로 따라 칠 수 밖에없겠지만 그것을 자신의 것으로 만드려면 무조건 맨땅에 헤딩하는 느낌으로 처음부터 끝까지 작성해봐야 한다고 생각합니다.

그런의미에서 박영웅 강사님의 "Overwatch 캐릭터 선택 예제" 또한 최대한 제가 직접 원본사이트와 비교하며 만들어보려고 노력했습니다. 세세한 코드 구현들을 설명하기 보다는 어디에서 막혔고 이럴때는 어떠한 속성을 사용하는게 좋은지와 같이 트러블슈팅위주로 설명을 해볼 예정입니다.

프론트엔드를 처음하는 사람으로서 정말 기본 완성 그림만 보고 클론을 하기는 쉽지 않은것 같습니다. 강사님 말씀으로는 어느정도는 "개발자도구"를 활용하여 구조와 모델에 대한 힌트를 얻고 Vanilla HTML/CSS로 최적화된 구조를 고민해보는것이 좋다는 답변을 들었습니다.

목표



목표는 위와 같은 화면단을 똑같이 구성하기만 하면 됩니다. 이 완성된 결과물에서 저희가 알아야할것은 프로젝트의 전체적인 큰구조입니다. 큰 틀에서의 HTML구조를 정확하고 효율적이게 잡아놔야 CSS를 잘 사용하여 적용시킬수 있습니다.

구조

Vanilla HTML/CSS에서는 최대한 구조를 단순하게 잡는것이 맞습니다(JS가 쓰이지않기때문이죠). 따라서 단순히 생각해보자면

  1. 32개의 영웅들을 담고있는 큰 컨테이너
  2. 각 영웅들의 사진을 담고있는 32개의 작은 item

이게 전부인 것입니다. 따라서 html의 큰 구조를 잡자면
body > container > heroes > hero 로 구성을 하면 될것 같습니다(heores를 제외해도 상관은 없을것 같습니다. 여기에서는 heroes가 중간 컨테이너 역할을 합니다). 우선 기본적인 큰 구조는 이렇게 잡고 수정해 나가겠습니다.

영웅들 칸 만들어주기


hero들이 들어갈 전체적인 칸들을 만들어주었습니다.

.container .heroes {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  margin-top: 30px;
  max-width: 660px;
  margin: 0 auto;
}
.container .hero {
  background-color: gray;
  margin: 6px;
  width: 80px;
  height: 84px;
  border: 3px solid white;
}

여기서 핵심은 heroes들의 flex특성일것 같습니다. display:flex를통하여 가로 배치후 flex-wrap:wrap을 사용해주어 자동 줄바꿈을 해주었습니다. 나머지 값들은 결과물에 맞게 적당히 값을 넣어주었습니다. 제가 이 과정에서 헤맨 것이 있는데 바로 margin: 0 auto였습니다. 해당 속성이 가운데 정렬을 할때 쓰인다는 것을 잘 알고있었으나 계속 justify-content:center를했는데 왜 뷰포트 가운데로 안오지? 와 같이 생각을 하고있었습니다. 뷰포트 가운데 정렬을 위해서는 heroes container자체를 가운데로 옮겨줘야했기에 margin 0 auto를 사용해야했습니다.


약간의 수정을 거쳐 조금 더 결과물에 가까운것을 볼 수있습니다. transform:skewX(-14deg)속성으로 14도씩 기울어줬고 border-radius:10px를 통하여 모서리를 부드럽게 처리를 해주었습니다. 또한 제가 놓쳤던 부분은 바로 hero의 가로 세로 수치를 결과물과 동일하게 설정해주었는데도 박스의 크기 차이가 발생했던 것입니다. 이유를 찾아보니 바로 box-sizing: border-box속성을 안해주어서 였습니다. 요소의 크기를 계산할때 border를 넣는지 안넣는지 보는것이죠. 이 설정을 통하여 요소의 크기는 조금 더 줄어들게 되었습니다. 그에 따라서 flex item들의 위치도 자연스럽게 조정된것을 확인 할 수있습니다.

영웅 이미지 삽입

이정도로 영웅들의 칸은 전부 완성이 된것 같습니다. 이번에는 각 칸에 알맞는 영웅들의 이미지를 삽입해줘야 합니다. 이때, 결과물을 보면 알다싶이 회색 바탕위에 영웅들의 사진들이 위에 떠있는것을 볼 수 있습니다. 따라서 background-image 속성을 사용하여 회색 바탕위에 영웅들을 띄워줘야 합니다. 그러나 현재 html구조로는 hero class에 background-color가 있는데 background-image까지 삽입이 불가능합니다. 따라서 추가적인 div image class를 각각 만들어주어 거기에 background-image로 영웅들을 올려야 할것 같습니다. 이러면 html 구조는 body > container > heroes > hero > image가 되겠네요.

그러면 32개의 image를 추가해주고 각자에 알맞는 img url을 삽입해주었습니다. 이때 CSS 선택자를 유념히 봐야하는데요 .container .heroes .hero:nth-child(1) .image 와 같이 사용하였습니다. 32개의 hero중에 ~번째에 알맞는 nth-child를 해주고 최종적으로 image태그를 지칭하는 것입니다. 이렇게 32개의 작업을 해주었습니다.

그러나...


여전히 이미지들이 표시되지 않습니다. 그도 그럴것이 background-image면 background에 대한 크기가 우선 선언이 되야합니다. 저는 이 부분을 놓쳤었습니다. 그래서 background크기를 height: 100%를 통하여 부모의 세로길이를 가져왔습니다. 가로부분은 자동으로 늘어나기 때문에 필요가 없습니다.


이번엔 이미지가 잘려서 나옵니다. 이를 해결할 방법은 저희가 알고있습니다. background속성을 다루는 것이죠.

.container .heroes .hero .image {
  height: 100%;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

위와같이 속성을 부여하고 나니 이제는 그래도 얼추 비슷해진것 같습니다.

그러나 저기 바스티온을 보면 뭔가 어색하죠. 고개가 너무 오른쪽으로 돌아가있네요. 왜 그런가 생각을해보니 저희가 hero 칸들을 14도씩 회전을 해주었기 때문입니다. 따라서 background-image도 당연히 돌아가겠네요. 이것을 고치려면 transform: skewX(14deg)로 반대로 14도 돌려주면 되겠습니다.


드디어 고개가 돌아왔네요. 그러나 조금씩 칸을 삐져나오는 모습입니다. 부모요소(hero)에 overflow:hidden을 부여하여 숨겨줍시다.

이제 이미지 삽입이 완벽해진것 같습니다. 영웅들이 알맞게 잘 배치되었네요.

애니메이션 효과 삽입

원본을 보면 마우스를 각 영웅들에 갖다가 대면 두가지 효과가 일어납니다.

  1. 영웅의 크기가 커진다
  2. 배경색이 주황색으로 변경된다

마우스를 올렸을때 작동하는것은 저희가 잘 알고 있습니다. 바로 가상 클래스 선택자 :hover이죠. 이를 사용하여 특정한 경우에 애니메이션 효과를 주면 될것 같습니다.

.container .heroes .hero:hover {
  background-color: orange;
  transform: scale(1.3) skewX(-14deg);
  z-index: 1;
}

hover 가상 클래스 선택자를 활용하여 마우스가 올라갔을때만 으로 설정을 해주었고 색상 바꾸기와 크기 키우기, 또한 hover시에는 원래의 skewX가 풀리길래 다시 원래대로 회전시켜주었습니다. 마지막으로 scale로 크기가 커지게 되면 옆의 그림에 가려지는 경우가 있어 z-index값을 1을 부여하여 항상 위에 올수있도록(안가리도록) 설정해주었습니다.

.container .heroes .hero {
  transition: transform 0.1s;
  transition: background-color 0.3s;
  transition-timing-function: ease;
}

hover까지만 해도 동작은 하지만 전혀 부드럽지않고 갑작스럽습니다. 따라서 transition을 통하여 특정 속성마다 동작시간을 설정해주었고 timing-function에 ease를 부여하여 부드럽게 해주었습니다. transition속성으로 다른 속성을 select할수있는것을 몰랐기에 이번기회에 제대로 배웠습니다.

이제 애니메이션도 잘 동작합니다. transition과 transform에 대해서 제대로 배워볼만한 예제였던것 같습니다.

배경과 로고 삽입

이제 전체화면을 포함하는 배경을 넣어줘야합니다. 따라서 body태그에 background-image를 주면 될것같습니다. 이때, 제가 아까도 했던 실수인, 배경을 줄때는 항상 크기가있어야한다는 것을 명심해야합니다. height:100vh를 부여하여 전체 뷰포트크기를 관장하도록 했습니다. 또한 뷰포트 크기에 따라 배경화면 스크롤이 발생하지않도록 고정을 해주어야 하고 반복도 없애야합니다.

body {
  height: 100vh;
  background-image: url("https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/bg.jpg");
  background-attachment: fixed;
  background-repeat: no-repeat;
}

마지막으로 로고만 삽입하면 될것 같습니다. 로고는 background-image가 아닌 img태그로 넣어주어야하기에 html을 다루어야합니다. 이때, img의 위치를 잘 조정해주기 위하여 img를 포함하는 container도 하나가 필요합니다. 따라서 logo class container를 만들어주겠습니다.

<div class="logo">
        <img
          src="https://raw.githubusercontent.com/ParkYoungWoong/overwatch-hero-selector-vanilla/master/images/logo_overwatch.png"
          alt="오버워치 로고"
        />
</div>

컨테이너의 크기를 정해주고 margin 0 auto로 가운데 정렬을 잘해주니 끝이났습니다.

마치며


정말 재밌게 클론코딩 한것 같습니다. 이렇게 휙휙 눈에 보이는게 역시나 프론트엔드의 매력이지 않을까요... 그리고 이런건 최대한 강의는 보지않고 직접 짜봐야 재밌는것 같습니다. 강의는 그저 정답과 해설로 생각하고 조금 완성도를 높이는 정도라 생각을 해야할것 같습니다.

저희조는 다음주까지 각자 어렵지않은 웹사이트 하나를 클론코딩 해오기로 했습니다. 저는 최대한 개발자도구와 vanilla html/css만을 사용하여 만들어볼 예정입니다!

profile
안녕하세요 노준영입니다.

0개의 댓글