Thumbnail Maker

Bam·2023년 6월 29일
0

projects

목록 보기
3/4
post-thumbnail

리액트 프로젝트

🎨기획의도🎨

블로그를 3년 이상 운영해 오면서 한 가지 느낀점이 있었습니다.
예전에도 언급했지만 글을 쓸 때 이미지가 있으면 개행 효과와 함께 글의 집중력을 높여준다고 느꼈기에 썸네일을 글 상단에 넣기 시작했습니다.

확실히 글에 생기를 불어주는 역할을 하고 있지만, 한 가지 문제점이 있었습니다. 바로 썸네일 제작이 쉽지는 않다는 것이었습니다.

저는 그래픽 툴을 다룰 줄 모르기 때문에 썸네일을 만드는게 어려웠었습니다. 그래서 저는 두가지 방식을 선택했습니다.

  • 그림판에 그려서 만들기
  • 파워포인트를 이용하기

이 두 방식은 간단한 썸네일을 쉽게 만들 수 있었지만 그림판은 가운데 정렬이 힘들었고, 파워포인트는 이미지화 시키는 방식이 번거로웠습니다. 그래서 이런 경험에 비추어 누구나 간단하게 심플한 디자인의 썸네일을 만들 수 있는 웹 페이지를 제작할 수 있도록 만들어진 것이 Thumbnail Maker 프로젝트입니다.

이 프로젝트는 다음과 같은 분들에게 추천합니다.

  • 심플한 디자인의 썸네일을 사용하고 싶으신 분.
  • 썸네일을 만들고 싶은데, 디자인 감각이 부족하거나 디자인툴을 다루기 어려우신 분.

🎨프로젝트🎨

결과물


사용 기술 🔧

  • CSS + SCSS: SCSS를 사용해서 스타일 시트를 작성했습니다.
  • styled-components: 컴포넌트 스타일링에 사용했습니다.
  • React.js: 리액트를 활용한 웹 페이지입니다.
  • React Colorful: Color Picker를 제작하는데 사용했습니다.
  • html2canvas: 완성된 썸네일을 다운받는데 사용했습니다.
  • 이 외에 react-icons, prettier를 사용했습니다.

기능 소개 ✍

상세 코드는 리포지토리에서 확인하실 수 있습니다.

state

프로젝트에서 사용한 상태들은 배경색, 폰트색, 폰트 크기, 폰트, 텍스트, width, height입니다. 즉, 썸네일을 구성하는 구성요소들이 우리가 관리할 상태가 됩니다.

이 프로젝트는 단일 페이지이고, 그다지 복잡한 상태가 아니기 때문에 Context API를 활용해서 상태들을 관리했습니다.

const ThumbnailContentsContext = createContext({
  state: {
    width: '',
    height: '',
    text: '',
    textColor: '',
    fontSize: '',
    fontFamily: '',
    backgroundColor: '',
  },
  actions: {},
});

PreviewPalette.jsx

아래에서 작성할 폼요소의 입력을 토대로 배너를 미리보기할 수 있는 컴포넌트입니다.

사용자에겐 단순히 미리보기의 역할을 하지만, 내부적으로는 이 미리보기를 div로 잘라내어 다운로드 하도록 작동하고 있습니다.

		<Preview
          id={'thumbnail'}
          className={'thumbnail'}
          ref={previewRef}
          spellCheck={false}
          height={height}
          suppressContentEditableWarning={true}
          style={{
            width: `${width}px`,
            height: `${height}px`,
            backgroundColor: backgroundColor,
            backgroundSize: 'cover',
            backgroundPosition: 'center',
            color: textColor,
            fontSize: `${fontSize}px`,
            fontFamily: fontFamily,
            lineHeight: `${height}px`,
          }}>
          {text}
        </Preview>

style 속성에 lineHeightheigth state와 동일하게 맞춤으로써, 글자가 배너의 정중앙에 위치하도록 만들었습니다. 그리고 각 요소들은 입력한 상태들을 받아와서 스타일이 적용되게 하고 있습니다.

썸네일 다운로드

  const capturingThumbnail = () => {
    html2canvas(document.getElementById('thumbnail'), {
      width: width,
      height: height,
      scale: 1,
    })
      .then((canvas) => {
        saveImg(canvas.toDataURL('image/jpg'), 'image.jpg', text);
      })
      .catch(e => {
        console.error(e);
      });
  };

만들어진 썸네일을 캡쳐하고 다운로드하는 코드입니다. 여기서는 html2canvas라이브러리를 통해서 PreviewPalette의 요소를 캡쳐만 하고 실질적인 다운로드 과정은 saveImg()함수가 수행합니다.

export const saveImg = (uri, filename, text) => {
  let link = document.createElement('a');

  document.body.appendChild(link);

  link.href = uri;
  link.download = `${text.split(' ').join('_')}.png`;
  link.click();

  document.body.removeChild(link);
};

사용자가 입력한 텍스트가 썸네일 이미지 파일의 이름이 되고, 다운로드하게 동작합니다.

색상 선택

색상 선택은 폰트 색상과 배경색 두 가지로 나뉘어 집니다. 두 컴포넌트 동작원리는 같습니다.

export const ColorPicker = ({ buttonType }) => {
  const [selectedColor, setSelectedColor] = useState();
  const { actions } = useContext(ThumbnailContentsContext);

  const changeColor = (color) => {
    setSelectedColor(color);

    if (buttonType === 'background') {
      actions.setBackgroundColor(selectedColor);
    } else {
      actions.setTextColor(selectedColor);
    }
  };

  return (
    <ColorPickerBox className={'color-picker-box'}>
      <HexColorPicker
        color={selectedColor}
        onChange={changeColor}
      />
    </ColorPickerBox>
  );
};

Color Picker에서 선택된 색상의 값을 버튼 타입에 맞는 state에 업데이트합니다.

문제점

앞으로의 계획

  • 타입스크립트를 공부해서 js 코드를 ts화
  • 배경에 이미지도 첨부할 수 있는 기능
  • 디자인을 좀 더 개선

소감

좋았던 점 👍

  • 내가 필요로 한 기능들을 구현하면서 상당히 즐겁게 코딩했다.
  • 실제로 사람들이 사용할 것을 염두에 두고 개발했더니, 디자인이라던가 컴포넌트의 동작 등 여러가지를 생각하면서 개발하는 계기가 되었다.
  • 상태관리에 대한 이해가 늘었다.
  • 기존에 목표했던 1달이라는 시간보다 빠르게 제작할 수 있었다. (3주 소요)

반성할 점 👎

  • TextInput 컴포넌트가 입력, 폰트 크기, 폰트 종류 세 가지의 일을 한다. 한 가지의 일만 하도록 분리하는 리팩토링을 수행해야할 것 같다.

총평 ✍

처음으로 누군가가 진짜 사용하길 바라며 만들어본 프로젝트였다. 거기에 내가 필요로로 하기 때문에 제작한 프로젝트기도 해서 진행하는 내내 이것저것 연구하고 코드를 작성해본 것이 매우 즐거웠다. 대학생부터 지금까지 약 5년간 프로그래밍을 해오면서 가장 즐겁게 진행했던 것 같다.

이 프로젝트는 1차 완성이 아닌 배포 이후가 진짜라고 생각한다. 타입스크립트 코드로 마이그레이션한다는 계획을 갖고 있기에 새로운 도전이 될 것이고, 나의 성장에 큰 밑거름이 된 프로젝트라고 생각한다.

0개의 댓글