현재 모바일 반응형은 준비중에 있습니다.

데스크탑에서 확인해주세요.

화면 넓이는 768px 이상이어야 합니다.


Scroll Down Or Click

Project

Portfolio

Period

2024.11 ~ 2024.12

Role

Front-End(100%)

Team

FE - 1

Description

개인 포트폴리오 페이지입니다. 원하는 만큼 인터랙션을 듬뿍 넣어봤습니다. GSAP을 활용하여 인터랙션, 애니메이션을 구현하였습니다. 해당 프로젝트에서 사용한 Lenis 라이브러리의 자동완성 정렬 문제를 issue로 제기해 해결했습니다.

Skill

Next.js @14.2.15

가장 익숙한 스택을 선정했습니다. 또한 Meta Tag를 쉽게 설정할 수 있고, 리액트의 기능을 활용하기위해사용했습니다.

SASS @1.80.3

전처리기 CSS를 한 번도 사용해보지 않아 학습을 위해 사용했습니다. 변수, each, mixin 등의 기능을 사용했습니다.

GSAP @3.1.15

순차적 애니메이션과 스크롤 트리거를 통한 컴포넌트 고정, 애니메이션을 구현하기위해 도입했습니다.

lenis @1.1.17

GSAP Smooth Scroll 대신 효과를 구현하고 스크롤을 조절하기위해 도입했습니다.

highlight.js @11.11.0

코드블럭을 사용하기위해 도입했습니다.

Vercel

파이프라인, CI/CD 구축에 따른 공수를 줄이기 위해 도입했습니다.

Problem Solving

Lenis 라이브러리 자동완성 이슈 해결 경험

문제 상황

Lenis 라이브러리 사용 중 IDE에서 자동완성 기능이 Readme와 다르게 동작하는 문제가 발생했습니다. 정상적인 import 경로 대신 /dist 폴더의 경로가 우선적으로 추천되었습니다.

원인 분석

package.json의 exports 설정에서 문제가 발생했습니다.

// package.json
{
  "exports": {
    ".": {
      "types": "./dist/lenis.d.ts",
      "default": "./dist/lenis.mjs"
    },
    "./dist/*": "./dist/*",  // 문제가 되는 부분
    "./react": {
      "types": "./dist/lenis-react.d.ts", 
      "default": "./dist/lenis-react.mjs"
    }
    // ... 기타 설정들
  }
}

./dist/* 와일드카드 설정이 다른 경로들보다 상위에 위치하여, 모든 자동완성 추천에서 /dist 경로가 우선적으로 추천되는 문제가 발생했습니다.

해결 방법

1. 문제점을 파악하여 라이브러리의 GitHub 이슈로 제기
2. 컨트리뷰터들이 이슈를 통해 exports 설정의 우선순위 조정 필요성 확인
3. 수정 사항이 반영되어 이슈 해결
링크 https://github.com/darkroomengineering/lenis/issues/414

결과

exports 설정의 우선순위가 조정되어 의도한 대로 자동완성이 동작하게 되었습니다. 이를 통해 라이브러리가 1.1.17로 업데이트된 부분에 해당 코드 수정이 포함되어 개선되었습니다. 오픈소스 프로젝트에 기여하는 좋은 기회가 되었으며, 패키지의 exports 설정이 자동완성에 미치는 영향을 이해하는 계기가 되었습니다.


GSAP을 활용한 애니메이션 구현

라이브러리 선정 배경

인터랙션과 애니메이션 구현에 예전부터 관심을 가지고 있었고, 포트폴리오를 웹페이지로 구현하면서 기술을 적용하며 학습하고자 도입했습니다. GSAP과 프레이머 모션 중 커뮤니티가 좀 더 많고 널리 사용되고 있는 GSAP으로 선택했습니다.
복잡한 순차 애니메이션과 스크롤 트리거를 활용한 인터렉션을 주로 활용 했습니다.

주요 기능 구현

Scroll Trigger를 이용해 Project List를 구현하였습니다.
Scroll Trigger의 pin 기능을 이용해 프로젝트 섹션을 뷰포트에 고정시켰습니다. 또한 슬라이더 형식처럼 다음 화면으로 자연스럽게 넘어갈 수 있도록 snap 기능을 이용해 다른 프로젝트가 일부만 스크롤 되어도 자동으로 다음 프로젝트로 부드럽게 전환되도록 구현했습니다.

useGSAP(() => {
  const tl = gsap.timeline({
    scrollTrigger: {
      trigger: '#project-grid-section',
      start: 'top top',
      end: '+=300%',
      pin: true,
      scrub: true,
      snap: {
        snapTo: 1 / 3,
        duration: 0.5,
        ease: 'none',
      },
    },
  });

  tl.fromTo(
    `#${projectList[0].title}`,
    {
      // 초기 상태
    },
    {
      // 애니메이션 상태
    },
  ).fromTo(
    // 다음 애니메이션...
  );
}, []);

SASS - CSS 전처리기 사용

라이브러리 선정 배경

인터랙션과 애니메이션 구현에 예전부터 관심을 가지고 있었고, 포트폴리오를 웹페이지로 구현하면서 기술을 적용하며 학습하고자 도입했습니다. GSAP과 프레이머 모션 중 커뮤니티가 좀 더 많고 널리 사용되고 있는 GSAP으로 선택했습니다.
복잡한 순차 애니메이션과 스크롤 트리거를 활용한 인터렉션을 주로 활용 했습니다.

주요 기능 구현

다양한 스타일링 도구를 사용해본 경험이 있습니다. 순수 CSS부터 Tailwind와 같은 유틸리티 라이브러리, 그리고 CSS-in-JS까지 폭넓게 활용해왔습니다. 하지만 CSS 전처리기인 SCSS 계열은 사용해본 적이 없었기에, 학습 목적으로 도입하게 되었습니다.
SCSS를 통해 변수 지정과 each, mixin을 활용한 클래스 자동 생성 등의 기능을 주로 사용해 스타일링의 효율성을 높였습니다.

$typography-scale: (
  // Body sizes
  'body': (
      '10': (size: 1rem, line-height: 1.2em),
      ...
  ),

  // Headings
  'heading': (
      'h1': (size: 18rem, line-height: 1em),
      ...
  )
);

// Font Size
@each $category, $variants in $typography-scale {
  @each $variant, $style in $variants {
      $prefix: if($category == "body", "fs-", "");
      .#{$prefix}#{$variant} {
          font-size: map-get($style, size);
          line-height: map-get($style, line-height);
      }
  }
}

// Font Size Mixins
@mixin typography($category, $variant) {
  @if map-has-key($typography-scale, $category) {
      $category-map: map-get($typography-scale, $category);
      @if map-has-key($category-map, $variant) {
          $style: map-get($category-map, $variant);
          font-size: map-get($style, size);
          line-height: map-get($style, line-height);
      } @else {
          @error "Variant '#{$variant}' not found in #{$category} category";
      }
  } @else {
      @error "Category '#{$category}' not found in typography scale";
  }
}