Project

[메이플 사진관] 디자인 시스템 도입과 리뉴얼 적용기

SpiralMoon 2025. 2. 4. 16:57
반응형

디자인 시스템 도입과 리뉴얼 적용기

이 글의 내용중 일부는 일반인이 이해하기 힘든 내용이 포함되어 있을 sudo 있습니다.

안녕하세요. 메이플 사진관을 1인 개발한 7년차 서버 개발자 SpiralMoon 입니다.

오늘은 메이플스토리 관련 서비스인 메이플 사진관의 디자인 시스템 도입과 컴포넌트 개발 과정, 그리고 리뉴얼이 진행된 웹사이트 요소에 대해 기록을 하려 합니다. 개발보다는 디자인 위주로 개선한 내용이 포함되어 있습니다.

 

 

메이플 사진관 - 메이플 프로필, 포토샵 서비스

메이플 포토샵이 출시되었어요!

maplestudio.app


시리즈

2024.09.06 - [Project] - [메이플 사진관] 프로젝트 기획부터 서비스 공개까지

2024.11.25 - [Project] - [메이플 사진관] 기능 업데이트와 유저 이벤트 진행 후기


디자인 시스템과 공용 컴포넌트의 부재로 인한 부채

메이플 사진관은 1인 프로젝트고 제 커리어는 대부분 백엔드 경력이기 때문에 아무것도 없는 상태에서 만들어나갈 UI를 상상하는 것이 매우 힘들었습니다. 그래서 생성형 AI를 통해 작성된 UI 코드를 그대로 사용하고 있었습니다. 그러나 서비스에 기능이 추가되면서 문제점이 나타납니다.

 

1. 생성형 AI가 이전 입력 내용을 까먹고 디자인을 맘대로 바꿔버림 (color, padding 등)

2. 보일러 플레이트 코드 발생

 

위 문제점은 통일되지 않은 디자인, 유지보수 비용 증가라는 결과로 이어집니다.

 

이미 현업 시절에 앱개발자, 기획자, 디자이너와 팀프로젝트를 진행하면서 디자인 시스템의 중요성을 잘 알고 있었기 때문에 곁눈질로 배운 figma로 디자인 시스템을 간단하게 만들고 이것을 기반으로 컴포넌트를 정의하여 문제를 해결하기로 하였습니다.

 

마 그냥 1인 개발하는김에 figma까지 해봅시다.


디자인 시스템 - 색상 정의

여러분은 사진관이라는 단어에서 어떤 색이 떠오르시나요? (퍼스널 컬러 말고...)

아마 대부분은 무채색이나 우드톤처럼 차분한 계열을 떠올리실겁니다.

 

indigo

메이플 사진관은 기존에 어두운 indigo를 메인 컬러로 사용했습니다. 그러나 메이플스토리 IP는 발랄하기 때문에 컨셉이 충돌하여 메인 컬러 변경이 필요했습니다.

 

그렇다면 메이플다운 색은 도대체 무엇일까요? 메이플스토리가 현재 어떤 방향으로 디자인되는지 간략하게 알아봅시다.

 

메이플스토리를 대표하는 마스코트들 (저 사진중 둘은 이미 성인이다.)

넥슨은 메이플스토리는 게임 내에 등장하는 몬스터로 마스코트를 만들고 IP 사업 진행시 마스코트의 테마 색상을 활용한 디자인을 하고 있습니다. 이들 마스코트에게는 공통점이 있는데요.

 

핑크빈 (기존)
핑크빈 (신규)

IP 사업을 진행하기 이전에 디자인 개편을 진행했다는 점입니다.

디자인 개편이 진행되면서 공통적으로 오래된 픽셀 아트의 느낌을 줄이고 더 캐주얼하고 파스텔톤에 가까운 색상으로 변경되었습니다.

 

디자인의 변화는 마스코트 뿐만이 아닙니다.

 

옛날 캐시템과 요즘 캐시템 (오른쪽 출처 : https://blog.naver.com/44alice/223693331059)

이미 몇년 전부터 게임 내에서는 캐릭터 치장 아이템도 쨍한 컬러에서 점점 파스텔톤 위주로 출시되고 있는 상황입니다.

 

메이플다운 색이란 마스코트파스텔톤이 주요 키워드인 것 같습니다.

 

이블아이, 주황버섯, 슬라임, 돌의 정령, 와일드카고
디자인 시스템 - Color

해당 키워드에 착안하여 메이플스토리를 대표하는 몬스터를 파스텔톤이 포함된 컬러셋으로 정의했고, 주황버섯을 서비스의 Primary Color로 지정했습니다.

채도는 보통 9단계로 나누지만 모든 단계가 필요하진 않으므로 4단계로 정의했습니다.

 

디자인 시스템 - Color

추가로 시스템 컬러도 정의했습니다. 이 부분은 메이플스토리가 아닌 다른 가이드를 참고하였습니다.


디자인 시스템 - 컴포넌트 설계

메이플 사진관은 사용자로부터 커스터마이징 요소를 입력받기 위해 Input과 Button을 적극적으로 사용하고 있습니다.

 

그러나 앞서 말했듯이 디자인 시스템이 없는 상태에서 AI가 소스코드를 생성하다보니 모양이 조금씩 달라지는 문제가 있었는데요. 그래서 자주 사용되는 컴포넌트의 디자인을 정의했습니다.

디자인 시스템 - Input
디자인 시스템 - Button
디자인 시스템 - Radius

예시로 가져온 Input과 Button입니다. 상태에 따라 컴포넌트 외형에 변경을 주어 사용자가 쉽게 인지할 수 있도록 유도했습니다.


개발 - 컴포넌트 구현

디자인 시스템으로 설계한 컴포넌트를 코드로 구현했습니다.

 

디자인 시스템을 1순위로 따르되 사용하는 쪽에서 className 병합을 통해 디자인을 overwrite 할 수 있도록 구성했습니다.

그리고 UX를 개선하기 위해 인터랙션을 부드럽게 하는 애니메이션 속성을 미리 ANIMATION_CLASS 상수로 정의 및 적용했습니다.

 

// 파라미터 정의
type InputProps = {
  id?: string;
  className?: string;
  type?: 'text' | 'number';
  disabled?: boolean;
  value?: string;
  placeholder?: string;
  rounded?: 'full' | 'half';
  onChange?: ChangeEventHandler<HTMLInputElement>;
  onFocus?: FocusEventHandler<HTMLInputElement>;
  onBlur?: FocusEventHandler<HTMLInputElement>;
  onKeyDown?: KeyboardEventHandler<HTMLInputElement>;
};

// <Input> 컴포넌트 정의
export const Input = ({
  id,
  className,
  type = 'text',
  disabled,
  value,
  placeholder,
  rounded,
  onChange,
  onFocus,
  onBlur,
  onKeyDown,
}: InputProps) => {
  return (
    <input
      id={id}
      type={type}
      className={classNames(
        'block text-gray-600 text-base px-6 py-4 border-[1px] border-gray-300 focus:border-gray-600 focus:outline-0 placeholder:text-gray-300 disabled:bg-gray-200 disabled:text-gray-400 disabled:border-0',
        getRoundedClassName(rounded),
        ANIMATION_CLASS,
        className
      )}
      disabled={disabled}
      value={value}
      placeholder={placeholder}
      onChange={onChange}
      onFocus={onFocus}
      onBlur={onBlur}
      onKeyDown={onKeyDown}
    />
  );
};

// ----------

// 사용 예시
export default function Page() {
  const [value, setValue] = useState('');
  const onChange = (e: ChangeEvent<HTMLInputElement>) => {
    setValue(e.target.value);
  };

  return (
    <div className="flex h-screen w-full items-center justify-center">
      <Input value={value} placeholder={'Please input here.'} rounded="half" onChange={onChange} />
    </div>
  );
}

 

Input 동작 영상
// 파라미터 정의
type ButtonProps = {
  id?: string;
  className?: string;
  disabled?: boolean;
  rounded?: 'full' | 'half';
  children?: ReactNode;
  onClick?: MouseEventHandler<HTMLButtonElement>;
};

// <PrimaryButton> 컴포넌트 정의
export function PrimaryButton({ id, className, children, rounded, disabled, onClick }: ButtonProps) {
  return (
    <button
      id={id}
      className={classNames(
        `text-white text-base px-6 py-4 bg-primary-3 hover:bg-primary-2 active:bg-primary-3 disabled:bg-gray-200 disabled:text-gray-400`,
        getRoundedClassName(rounded),
        ANIMATION_CLASS,
        className
      )}
      onClick={onClick}
      disabled={disabled}
    >
      {children}
    </button>
  );
}

// ----------

// 사용 예시
export default function Page() {
  const [count, setCount] = useState(0);
  const onClick = () => {
    setCount((prev) => {
      return prev + 1;
    });
  };

  return (
    <div className="flex h-screen w-full items-center justify-center">
      <PrimaryButton rounded="half" onClick={onClick}>
        {`Primary Button. ${count}`}
      </PrimaryButton>
    </div>
  );
}

 

PrimaryButton 동작 영상

React로 작성한 컴포넌트 목록

 

디자인 시스템 적용 이후로 Input, Button 외에도 컴포넌트를 적극적으로 구현 & 활용하고 있습니다.


개발 - 웹사이트 리뉴얼

이제까지 위에서 정의한 디자인을 실제로 적용했습니다.

Header 개선 전/후
Footer 개선 전/후

 

컴포넌트 적용 전/후 1

 

컴포넌트 적용 전/후 2
컴포넌트 적용 전/후 3

 

Header와 Footer의 디자인도 변경하였고 텍스트 표현도 일관성있게 변경했습니다.

 

통일성있고 전반적으로 어두운 분위기에서 밝은 분위기로 바뀌었으며, 소스코드 내적으로는 라인 수가 상당히 줄었고 유지보수하기 편해졌습니다.


개발 - 감사하는 마음을 담아

메이플 사진관을 이용해주신 용사님들에게 고마움을 표현하기 위해 다녀간 캐릭터를 좀 더 메인에 예쁘게 전시하기로 했습니다.

(이 과정에서는 넥슨의 공식 서비스인 메이플스토리 AI Style Finder의 디자인을 참고했습니다.)

다녀간 캐릭터 목록 수정 전/후

왼쪽 사진처럼 기존에는 메인페이지 하단에 캐릭터 목록을 좌우로 나열하기만 했기에 방치되고 있는 느낌이 들었습니다. (그저 박제에 가깝다는 느낌이...)

 

이미지 포커스를 캐릭터 얼굴에 집중하고 배경에 파스텔톤 컬러가 들어가도록 구현했습니다. 그리고 웹사이트에 접속했을 때 캐릭터가 바로 보여지도록 상단으로 옮겼습니다.

 

 

추가로 좌우로 스크롤되는 애니메이션 효과를 적용했습니다.


마무리하며

백엔드를 오래 했지만 프론트엔드 개발자의 시선으로 접근해보는 즐거운 시간이었습니다. 이번 작업을 진행하면서 몇가지 수확을 얻었습니다.

  1. 프론트엔드 개발자들이 어느 부분에서 어려움을 겪는지 직접 느꼈고 프로젝트를 바라보는 시야가 확장되었습니다.
  2. 현업에서 근무할 때는 Figma를 Viewer로만 사용했었는데 조금은 Editor로도 사용할 수 있게 되었습니다.
  3. 스스로 UI 구현 실력이 없는 줄 알았는데 원인은 디자인 시스템의 부재였다는 점 (내 능력이 부족한게 아니었다!)

그리고 서비스의 분위기가 밝아진 점이 제일 맘에 듭니다.

리뉴얼 전
리뉴얼 후

 

부채를 해결했으니 앞으로도 추가될 재밌는 기능들을 기다려주세요!

 

읽어주셔서 감사합니다.

 

7년차 서버 개발자 SpiralMoon

반응형