Skip to content

기술공유 07. 반응형 Slide, 반응형 Canvas 만들기

이미림 edited this page Dec 18, 2019 · 10 revisions

반응형 Slide, 반응형 Canvas 만들기 👩🏻‍🎨

슬라이드 이미지 크기에 영향을 주는 MainSlide 컴포넌트 구조

// 컴포넌트 구조 (왼쪽 컴포넌트가 오른쪽 컴포넌트의 부모 컴포넌트이다.)
Channel > Slide> SlideViewer > MainSlide
  • 슬라이드 이미지의 부모 컴포넌트인 MainSlide는 너비와 높이 모두 100% 입니다.
  • SlideViewr 컴포넌트의 너비는 94%, 높이는 100%이고, SlideViewChannel 컴포넌트는 모두 높이가 100%의 스타일 속성을 갖고 있는 컴포넌트입니다.
  • 각 컴포넌트에는 MainSlide 컴포넌트를 제외하고, 모두 display: flex; 속성을 갖고 있습니다.
  • 즉, 슬라이드 이미지를 렌더링 할 컴포넌트의 부모 컴포넌트 모두 이미 어느 정도 반응형으로 구현되어 있었고, 사용자에게 너비/높이 비율이 원본의 이미지 슬라이드와 일치하도록 보여주기 위해서는 이미지 슬라이드가 원본의 이미지 비율을 유지하면서 화면크기에 따라 변화하는 반응형으로 구현해야 했습니다.. 😭

dropy 화면 기획서의 캔버스에 대한 기획

  • dropy를 개발하기 이전에 기획했던 화면 기획서의 모습입니다.
  • 슬라이드 위에서만 필기도구를 이용한 필기가 가능할 수 있도록 구현해야 했습니다.
  • 즉, 반응형 슬라이드 이미지의 크기와 동일하도록, 반응형 캔버스를 구현해야 했습니다... 😭

채널 내 슬라이드 이미지와 캔버스를 반응형으로 구현해야 한다! 😱

  • 각 슬라이드 이미지가 웹 화면의 크기와 상관없이 원래 이미지의 비율을 유지면서, 화면의 크기에 맞게 사용자에게 보이도록 해야 합니다.
  • 캔버스의 크기와 위치가 슬라이드 이미지와 동일해야 합니다.
    • 스피커는 슬라이드 이미지 위에서만 마우스를 이용해 그림을 그릴 수 있어야 한다.

구현하기 전에 고려했던 점 3가지

  • 슬라이드 원본의 이미지 비율을 저장하고 관리하는 방법
  • 화면의 너비와 높이에 따라 반응형 이미지 슬라이드를 렌더링 하는 방법
  • 반응형 이미지 슬라이드의 크기와 동일한 캔버스를 렌더링 하는 방법

참고: 아래에 나오는 모든 비율값은 모두 너비/높이 입니다!

1. 슬라이드 원본의 이미지 비율을 저장하고 관리하는 방법

  • dropy는 1개의 슬라이드 파일을 여러 장의 이미지 슬라이드로 변환할 때, 일부 기능(이미지 변환 작업)만을 gm을 이용한 컨버터 모듈을 사용하고 있습니다.

  • 컨버터 서버가 슬라이드 파일을 순차적으로 이미지로 변환할 때마다 gmsize() api를 이용해 이미지의 너비와 높이를 구하고, 너비/길이 이미지 슬라이드 비율을 DB에 저장하였습니다.

  • 각 이미지 슬라이드 비율을 DB에 channel의 slideRatioList 필드에 모두 저장하고, Channel 컴포넌트 내부에서는 위 정보를 Channel Context에 저장하고, 비율 값이 필요할 때 slideRatio 배열에서 각 page들의 너비/길이 값을 얻을 수 있습니다.

  • 사용자가 채널 페이지에서 page를 이동할 때마다 각 슬라이드 이미지의 비율 값을 slideRatioList에서 가져와 렌더링 될 슬라이드 이미지의 너비와 높이 값을 계산해줍니다.

2. 화면의 너비와 높이에 따라 반응형 이미지 슬라이드를 렌더링하는 방법

  • 슬라이드 이미지 컴포넌트의 부모 컴포넌트 SlideWrapper를 만들어서 높이와 너비를 모두 100%로 지정해 주었습니다. 따로 Wrapper를 만들어 준 이유는 슬라이드의 크기를 계산 할 때, 기준으로 쓸 fitHeight(SlideWrapper의 크기 비율과 이미지 슬라이드 크기 비율 대소비교 값)여부를 계산하기 위함입니다.

fieHeight란 ?

  • MainSlie 컴포넌트가 렌더링 되면, SlideWrapper의 dom element가 wrapperEl에 담깁니다.

    • useRef 리액트 훅을 이용했습니다.
  • window.getComputedStyle()을 이용해 SlideWrapper의 너비와 높이 css 속성값을 구하고, 이를 이용해 SlideWrapper 컴포넌트의 너비/높이(비율)을 구합니다.

  • SlideWrapper 컴포넌트의 비율과 이미지 컨버팅 과정에서 미리 저장했던 이미지 슬라이드의 비율을 비교하여 fitHeight(boolean값) 값을 구합니다.

  • fitHeight가 true인 경우

    • wrapperRatio의 값이 slideRatio의 값보다 클 경우입니다.
    • 즉, SlideImg 컴포넌트의 높이가 SlideWrapper의 높이와 동일해야 하는 경우입니다.
    • 사용자가 가로로 긴 화면을 보고 있는 상황입니다.
  • fieHeight가 false인 경우

    • wrapperRatio의 값이 slideRatio의 값보다 작을 경우입니다.
    • 즉, SlideImg 컴포넌트의 너비가 SlideWrapper의 너비와 동일해야 하는 경우입니다.
    • 사용자가 세로로 긴 화면을 보고 있는 상황입니다.

fitHeight 값을 이용해서 슬라이드 이미지 사이즈 정하기

  • fitHeight가 true인 경우(가로로 긴 화면)

    • 슬라이드 이미지의 높이를 SlideWrapper의 높이와 동일하도록 설정해주고, 넓이는 auto로 지정해줍니다.
    • 이와 같이 한다면, SlideCanvas 컴포넌트의 높이는 SlideWrapper와 동일해지고, SlideCanvas 컴포넌트의 너비는 이미지의 비율에 맞게 자동으로 설정됩니다.
  • fitHeight가 false인 경우(세로로 긴 화면)

    • 슬라이드 이미지의 너비를 SlideWrapper의 너비와 동일하도록 설정해주고, 높이는 auto로 지정해줍니다.
    • 이와 같이 한다면, SlideCanvas 컴포넌트의 너비는 SlideWrapper와 동일해지고, SlideCanvas 컴포넌트의 높이는 이미지의 비율에 맞게 자동으로 설정됩니다.

3. 반응형 이미지 슬라이드의 크기와 동일한 캔버스를 렌더링하는 방법

  • 슬프게도 canvas는 직접 너비와 높이를 지정해주어야 합니다.
  • 하지만, 이미 알고 있는 정보를 이용하여, 원하는 값을 계산할 수 있습니다.
    • SlideImg컴포넌트를 감싸고 있는 SlideWrapper의 너비와 높이
    • 이미지 슬라이드 원본 비율
    • 사용자가 화면을 어떻게 보고 있는 지에 대한 정보 (fitHeight 여부)

fitHeight가 true 인 경우 (가로로 긴 화면)

  • 캔버스의 높이가 SlideWrapper의 높이와 같아야 하는 상황입니다. 때문에 캔버스의 높이를 SlideWrapper의 높이와 같도록 설정해줍니다.
  • 너비를 계산하는 것이 조금 복잡합니다.
  • 알고 있는 정보
    • slidRatio - 슬라이드 이미지의 너비/높이 비율
    • SlideWrapper의 너비, 높이
    • SlideWrapper의 높이 = 캔버스의 높이
  • 이 경우는 SlideWrapper의 높이와 캔버스의 높이가 같은 상황입니다.
// (o) 알고 있는 값을 의미하고, (x)는 아래 식을 이용해 구해야 하는 값입니다.
캔버스 너비(x) / 캔버스의 높이(o) = slidRatio(o)

fitHeight가 false인 경우 (세로로 긴 화면)

  • 슬라이드 이미지의 너비가 SlideWrapper의 너비와 같아야 하는 상황입니다. 때문에 캔버스의 너비를 SlideWrapper의 너비와 같도록 설정해줍니다.
  • 이때는 너비를 계산하는 것이 복잡해집니다.
    • slidRatio - 슬라이드 이미지의 너비/높이 비율
    • SlideWrapper의 너비, 높이
    • SlideWrapper의 너비 = 캔버스의 너비
  • 이 경우는 SlideWrapper의 너비와 캔버스 너비가 같은 상황입니다.
// (o) 알고 있는 값을 의미하고, (x)는 아래 식을 이용해 구해야 하는 값입니다.
캔버스 너비(o) / 캔버스의 높이(x) = slidRatio(o)

캔버스 크기는 반응형인데.. 아직 반응형 캔버스 구현은 끝나지 않았다..🤯

  • 캔버스는 너비와 높이가 변경될 때, 캔버스 내부 content를 유지 않습니다. 하지만 dropy 서비스는 필기를 할 수 있는 이미지 슬라이드의 크기가 유동적으로 변경됩니다. 즉, 캔버스의 크기가 변경될 때, 필기들이 사라지는 문제가 있습니다.
  • 또한, 화면의 크기에 따라서 그렸던 그림이 화면의 크기에 비례적으로 커지고, 작아져야 합니다. (즉, 캔버스 내부 content를 유지해야 합니다.)
  • 또한.. 각 슬라이드마다 다른 필기 내용을 유지해야 합니다.
    • 페이지를 이동하면, 이전에 필기했던 내용은 삭제되고 이동한 페이지에 그렸었던 필기 내용이 화면에 그려져야 합니다.

위 문제들을 어떻게 해결했는지에 대한 내용은 이후 기술 공유 글로 남기겠습니다. 긴 글 읽어주셔서 감사합니다. 다음 기술 공유는 더 좋은 내용으로 작성할 수 있도록 노력하겠습니다. 글에 대한 피드백은 언제나 환영입니다. 🥰

Clone this wiki locally