-
Notifications
You must be signed in to change notification settings - Fork 3
기술공유 07. 반응형 Slide, 반응형 Canvas 만들기
// 컴포넌트 구조 (왼쪽 컴포넌트가 오른쪽 컴포넌트의 부모 컴포넌트이다.)
Channel > Slide> SlideViewer > MainSlide
- 슬라이드 이미지의 부모 컴포넌트인
MainSlide
는 너비와 높이 모두 100% 입니다. -
SlideViewr
컴포넌트의 너비는 94%, 높이는 100%이고,SlideView
와Channel
컴포넌트는 모두 높이가 100%의 스타일 속성을 갖고 있는 컴포넌트입니다. - 각 컴포넌트에는 MainSlide 컴포넌트를 제외하고, 모두
display: flex;
속성을 갖고 있습니다. - 즉, 슬라이드 이미지를 렌더링 할 컴포넌트의 부모 컴포넌트 모두 이미 어느 정도 반응형으로 구현되어 있었고, 사용자에게 너비/높이 비율이 원본의 이미지 슬라이드와 일치하도록 보여주기 위해서는 이미지 슬라이드가 원본의 이미지 비율을 유지하면서 화면크기에 따라 변화하는 반응형으로 구현해야 했습니다.. 😭
- dropy를 개발하기 이전에 기획했던 화면 기획서의 모습입니다.
- 슬라이드 위에서만 필기도구를 이용한 필기가 가능할 수 있도록 구현해야 했습니다.
- 즉, 반응형 슬라이드 이미지의 크기와 동일하도록, 반응형 캔버스를 구현해야 했습니다... 😭
- 각 슬라이드 이미지가 웹 화면의 크기와 상관없이 원래 이미지의 비율을 유지면서, 화면의 크기에 맞게 사용자에게 보이도록 해야 합니다.
- 캔버스의 크기와 위치가 슬라이드 이미지와 동일해야 합니다.
- 스피커는 슬라이드 이미지 위에서만 마우스를 이용해 그림을 그릴 수 있어야 한다.
- 슬라이드 원본의 이미지 비율을 저장하고 관리하는 방법
- 화면의 너비와 높이에 따라 반응형 이미지 슬라이드를 렌더링 하는 방법
- 반응형 이미지 슬라이드의 크기와 동일한 캔버스를 렌더링 하는 방법
참고: 아래에 나오는 모든 비율값은 모두 너비/높이 입니다!
-
dropy는 1개의 슬라이드 파일을 여러 장의 이미지 슬라이드로 변환할 때, 일부 기능(이미지 변환 작업)만을
gm
을 이용한 컨버터 모듈을 사용하고 있습니다. -
컨버터 서버가 슬라이드 파일을 순차적으로 이미지로 변환할 때마다
gm
의size()
api를 이용해 이미지의 너비와 높이를 구하고,너비/길이
이미지 슬라이드 비율을 DB에 저장하였습니다. -
각 이미지 슬라이드 비율을 DB에 channel의
slideRatioList
필드에 모두 저장하고, Channel 컴포넌트 내부에서는 위 정보를 Channel Context에 저장하고, 비율 값이 필요할 때 slideRatio 배열에서 각 page들의너비/길이
값을 얻을 수 있습니다. -
사용자가 채널 페이지에서 page를 이동할 때마다 각 슬라이드 이미지의 비율 값을 slideRatioList에서 가져와 렌더링 될 슬라이드 이미지의 너비와 높이 값을 계산해줍니다.
- 슬라이드 이미지 컴포넌트의 부모 컴포넌트
SlideWrapper
를 만들어서 높이와 너비를 모두 100%로 지정해 주었습니다. 따로 Wrapper를 만들어 준 이유는 슬라이드의 크기를 계산 할 때, 기준으로 쓸fitHeight(SlideWrapper의 크기 비율과 이미지 슬라이드 크기 비율 대소비교 값)
여부를 계산하기 위함입니다.
-
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가 true인 경우(가로로 긴 화면)
- 슬라이드 이미지의 높이를
SlideWrapper
의 높이와 동일하도록 설정해주고, 넓이는 auto로 지정해줍니다. - 이와 같이 한다면,
SlideCanvas
컴포넌트의 높이는SlideWrapper
와 동일해지고,SlideCanvas
컴포넌트의 너비는 이미지의 비율에 맞게 자동으로 설정됩니다.
- 슬라이드 이미지의 높이를
-
fitHeight가 false인 경우(세로로 긴 화면)
- 슬라이드 이미지의 너비를
SlideWrapper
의 너비와 동일하도록 설정해주고, 높이는 auto로 지정해줍니다. - 이와 같이 한다면,
SlideCanvas
컴포넌트의 너비는SlideWrapper
와 동일해지고,SlideCanvas
컴포넌트의 높이는 이미지의 비율에 맞게 자동으로 설정됩니다.
- 슬라이드 이미지의 너비를
- 슬프게도 canvas는 직접 너비와 높이를 지정해주어야 합니다.
- 하지만, 이미 알고 있는 정보를 이용하여, 원하는 값을 계산할 수 있습니다.
-
SlideImg
컴포넌트를 감싸고 있는SlideWrapper
의 너비와 높이 - 이미지 슬라이드 원본 비율
- 사용자가 화면을 어떻게 보고 있는 지에 대한 정보 (fitHeight 여부)
-
- 캔버스의 높이가
SlideWrapper
의 높이와 같아야 하는 상황입니다. 때문에 캔버스의 높이를SlideWrapper
의 높이와 같도록 설정해줍니다. - 너비를 계산하는 것이 조금 복잡합니다.
- 알고 있는 정보
-
slidRatio
- 슬라이드 이미지의 너비/높이 비율 -
SlideWrapper
의 너비, 높이 -
SlideWrapper
의 높이 =캔버스
의 높이
-
- 이 경우는
SlideWrapper
의 높이와 캔버스의 높이가 같은 상황입니다.
// (o) 알고 있는 값을 의미하고, (x)는 아래 식을 이용해 구해야 하는 값입니다.
캔버스 너비(x) / 캔버스의 높이(o) = slidRatio(o)
- 슬라이드 이미지의 너비가
SlideWrapper
의 너비와 같아야 하는 상황입니다. 때문에 캔버스의 너비를SlideWrapper
의 너비와 같도록 설정해줍니다. - 이때는 너비를 계산하는 것이 복잡해집니다.
-
slidRatio
- 슬라이드 이미지의 너비/높이 비율 -
SlideWrapper
의 너비, 높이 -
SlideWrapper
의 너비 =캔버스
의 너비
-
- 이 경우는
SlideWrapper
의 너비와 캔버스 너비가 같은 상황입니다.
// (o) 알고 있는 값을 의미하고, (x)는 아래 식을 이용해 구해야 하는 값입니다.
캔버스 너비(o) / 캔버스의 높이(x) = slidRatio(o)
- 캔버스는 너비와 높이가 변경될 때, 캔버스 내부 content를 유지 않습니다. 하지만 dropy 서비스는 필기를 할 수 있는 이미지 슬라이드의 크기가 유동적으로 변경됩니다. 즉, 캔버스의 크기가 변경될 때, 필기들이 사라지는 문제가 있습니다.
- 또한, 화면의 크기에 따라서 그렸던 그림이 화면의 크기에 비례적으로 커지고, 작아져야 합니다. (즉, 캔버스 내부 content를 유지해야 합니다.)
- 또한.. 각 슬라이드마다 다른 필기 내용을 유지해야 합니다.
- 페이지를 이동하면, 이전에 필기했던 내용은 삭제되고 이동한 페이지에 그렸었던 필기 내용이 화면에 그려져야 합니다.
위 문제들을 어떻게 해결했는지에 대한 내용은 이후 기술 공유 글로 남기겠습니다. 긴 글 읽어주셔서 감사합니다. 다음 기술 공유는 더 좋은 내용으로 작성할 수 있도록 노력하겠습니다. 글에 대한 피드백은 언제나 환영입니다. 🥰
© BoostCamp 김김이조.
Members
'김'도현 (happydhKim) | '김'재원 (load0ne) | '이'미림 (always-awake) | '조'애리 (aereeeee)
-
Plans
-
Rules
-
Style Guides
-
Sprint Meeting Logs