[코드 리뷰] GS Elevator 클론 코딩

Carrie·2024년 1월 31일
0
post-thumbnail

1. CSS에서 SCSS로의 전환 - HTML 구조 유지하며 SCSS로 반응형 구현하기

반응형 디자인을 더욱 쉽게 구현하기 위해 기존 CSS에서 SCSS로 전환을 결정하였다. SCSS 도입으로 코드의 효율성과 재사용성을 높이고, 보다 쉽게 다양한 화면 크기에 유연하게 대응하는 반응형 웹페이지를 제작할 수 있었다.

믹스인 설정

먼저, 미디어 쿼리 및 자주 사용되는 디자인 패턴을 믹스인으로 정의하여 프로젝트 전체에서 재사용할 수 있도록 하였다.

/* 텍스트 오버플로우 스타일 정의 */
@mixin ellipse($line:1) {
    overflow: hidden;
    text-overflow: ellipsis;
    word-break: keep-all;
    word-wrap: break-word;
    @if($line > 1) {
        display: -webkit-box;
        -webkit-box-orient: vertical;
        -webkit-line-clamp: $line;
    } @else {
        white-space: nowrap;
    }
}

/* 미디어 쿼리 믹스인을 사용하여 반응형 디자인 구현을 단순화 */
@mixin desktop() {
    @media (max-width: 1539px) {
        @content;
    }
}
@mixin desktop-small() {
    @media (max-width: 1399px) {
        @content;
    }
}
@mixin laptop() {
    @media (max-width: 1199px) {
        @content;
    }
}
@mixin tablet() {
    @media (max-width: 1023px) {
        @content;
    }
}
@mixin mobile() {
    @media (max-width:767px) {
        @content;
    }
}

반응형 구현 예시

또한, HTML 구조 변경 없이 display: flexdisplay: grid를 활용하여 SCSS 코드만으로 레이아웃을 조정하여 반응형 디자인을 구현해냈다.

.sc-solution .solution-list {
  display: flex; /* 기본으로 flex 디스플레이 사용 */
  width: 100%;
  @include tablet() {
    display: grid; /* 태블릿 사이즈에서 grid로 변경하여 레이아웃 조정 */
    grid-template-columns: repeat(2, 1fr);
    grid-row-gap: 64px;
  }
  @include mobile() {
    display: flex; /* 모바일 사이즈에서 다시 flex 사용하되, 방향 변경 */
    flex-direction: column;
  }
}

SCSS 도입 후, 반응형 디자인 구현 시간을 줄일 수 있었으며, 스타일 시트 유지 관리도 좀 더 간편해졌다. 이러한 과정에서 코드의 모듈화와 재사용성의 중요성을 깊히 이해하게 되었고, 더욱 체계적이고 효율적인 방법으로 스타일을 관리하는 방법을 배울 수 있었다.

2. GSAP 활용하여 비디오 프로그레스바 구현하기

비디오 진행률에 따른 프로그레스바 구현 중 몇가지 문제에 직면했다. 아래에 그 해결 과정을 기록해보고자 한다.

문제1🧨

.sc-intro .control-area .progress-area #progress-bar {
  display: block;
  width: 0;
  height: 100%;
  background-color: #fff;
  transition: width 0.3s linear;
}

프로그레스 바 진행 시 부드러운 움직임을 위해 transition을 사용했는데, 이는 비디오 재생 시에는 원활하게 동작했으나, 비디오가 끝나고 처음으로 돌아갈 때 즉, 너비가 100%에서 0%로 돌아가는 과정에서도 transition이 적용되어 부자연스러운 동작을 유발했다.

문제2🧨

var introVideo = document.getElementById("intro-video");
var videoBtn = document.getElementById("video-btn");
var progressBar = document.getElementById("progress-bar");

videoBtn.addEventListener("click", function () {
  if (introVideo.paused) {
    introVideo.play();
    videoBtn.classList.remove("play");
  } else {
    introVideo.pause();
    videoBtn.classList.add("play");
  }
});

introVideo.addEventListener("timeupdate", function () {
  var progress = (introVideo.currentTime / introVideo.duration) * 100;
  progressBar.style.width = progress + "%";

프로그레스바의 진행도와 비디오의 실제 진행시간이 정확히 일치하지 않는 문제가 발생했다. timeupdate가 비디오 재생 중 일정한 간격으로 발생하기 때문에, 프로그레스바의 업데이트 주기와 비디오의 실제 재생 시간이 완벽히 동기화되지 않아서 발생한 문제였다.

해결🥳

introVideo.addEventListener("loadedmetadata", function () {
  const barMotion = gsap.to("#progress-bar", introVideo.duration, {
    repeat: -1, // 무한 반복
    width: "100%",
    paused: true,
    ease: "none",
  });

  introVideo.play();
  barMotion.play();

  videoBtn.addEventListener("click", function () {
    if (introVideo.paused) {
      introVideo.play();
      barMotion.play();
      videoBtn.classList.remove("play");
    } else {
      introVideo.pause();
      barMotion.pause();
      videoBtn.classList.add("play");
    }
  });
});

이러한 문제를 해결하기 위해 GSAP의 타임라인 기능을 활용했다. loadedmetadata 이벤트 리스너 내부에서 gsap.to를 사용하여 프로그레스바의 너비를 0%에서 100%까지 변화시키는 애니메이션을 정의하고, 이를 비디오의 duration과 동기화하여 비디오 재생과 일치하게 만들었다.

위와 같이 수정함으로써 비디오 재생이 끝나고 처음으로 돌아갈 때의 transition 문제도 해결할 수 있었다.

💡loadedmetadata란?
loadedmetadata 이벤트는 <audio><video> 요소가 메타데이터(예: 지속 시간, 차원, 텍스트 트랙 등)를 완전히 로드하고 사용할 준비가 되었을 때 발생한다.
예를 들어, 비디오 플레이어를 구현할 때, loadedmetadata를 활용하면 미디어의 총 재생 시간을 알아내거나, 미디어의 원본 크기 같은 정보를 기반으로 UI를 조정할 수 있다. 또한, 이 이벤트를 사용하여 미디어가 재생될 준비가 되었는지 확인한 후에 사용자에게 재생 컨트롤을 제공할 수도 있다.

3. 스크롤바 커스텀하기

웹사이트의 전체적인 디자인과의 조화를 위해 사용자가 많이 접하는 부분 중 하나인 헤더의 드롭다운 메뉴에 커스텀 스크롤바를 적용했다.

.sub-nav::-webkit-scrollbar {
  width: 4px; /* 스크롤바 너비 설정 */
}
.sub-nav::-webkit-scrollbar-track {
  background: #fff; /* 스크롤바 배경색 설정 */
}
.sub-nav::-webkit-scrollbar-thumb {
  background: #bfc6d2; /* 스크롤바의 움직이는 부분 색상 설정 */
  border-radius: 4px;
}

위와 같이 커스텀함으로써, 디자인의 일관성을 유지하고 기본 스크롤바와 차별화된 디자인으로 사용자에게 더 나은 경험을 제공할 수 있게 되었다.

4. Lenis를 이용한 부드러운 스크롤 애니메이션 구현하기

웹사이트의 사용자 경험을 향상시키는 중요한 요소 중 하나는 스크롤 동작이 얼마나 부드러운지이다. 이번 프로젝트에서는 Lenis 라이브러리를 도입하여 'Top 버튼' 클릭 시, 최상단으로 부드럽게 이동하는 기능을 구현했다.

💡Lenis 소개
Lenis는 스크롤 퍼포먼스를 개선하고 사용자에게 부드러운 스크롤 경험을 제공하기 위해 설계된 자바스크립트 라이브러리이다. 이 라이브러리는 스크롤 이벤트를 최적화하고, 다양한 애니메이션과의 통합을 용이하게 한다.

구현 과정

const lenis = new Lenis(); // lenis 객체 생성

lenis.on("scroll", (e) => { // 스크롤 이벤트 리스너 등록
  
});

lenis.on("scroll", ScrollTrigger.update);

gsap.ticker.add((time) => { // gsap의 ScrollTrigger와 lenis 스크롤 이벤트 동기화
  lenis.raf(time * 1000); // lenis 애니메이션 프레임 업데이트
});

gsap.ticker.lagSmoothing(0); // 애니메이션 지연 최소화

.
.
.

document.querySelector(".top-btn").addEventListener("click", function () {
  lenis.scrollTo(0); // top-btn 클릭 시, 최상단으로 부드럽게 이동
});

Lenis를 활용한 'Top 버튼'을 구현함으로써, 사용자가 보다 쉽게 페이지의 최상단으로 돌아갈 수 있도록 하였다. 사용자에게 부드러운 스크롤 애니메이션을 제공하여 만족도를 높이고 웹사이트의 전반적인 사용자 경험을 개선하였다.

profile
Markup Developer🧑‍💻

0개의 댓글