-
Notifications
You must be signed in to change notification settings - Fork 3
기술 공유 10. 반응형 Canvas에서 필기 유지하기 👩🏻🎨
이미림 edited this page Dec 21, 2019
·
3 revisions
- 캔버스는 width와 height 값이 변하면, 기존에 갖고 있었던 contents를 모두 삭제해 버립니다. 😱
- 캔버스의 크기가 굉장히 빈번하게 발생하는 dropy 서비스에서는 스피커가 필기한 내용이 화면이 변화해도 계속해서 유지되어야 합니다.
- 필기 내용에 대한 데이터가 소실되지 않고, 그대로 유지되어야 합니다.
- 캔버스의 크기가 변화할 때, 변화된 캔버스의 크기에 맞게 필기 내용이 비율에 맞게 커지고 작아져야 합니다.
- 많은 정보 탐색과 해결방법을 찾아보았지만, 캔버스의 특이한 본능(?) 때문에 반응형 캔버스에서 필기 데이터가 소실되지 않고, 원래의 필기 비율을 유지하도록 하기 위해서는 결국 캔버스가 resize되기 전에 캔버스 내부의 필기 데이터를 저장하고, 이후 resize가 된 캔버스 위에 이전에 저장해 두었던 필기 데이터를 이용해 다시 그리는 방법을 선택해야 했습니다.
- 이제 캔버스 resize 이전 데이터를 저장하고, 이를 resize가 된 캔버스에 그려주는 방식에 대해서 dropy🐣 팀원들의 의견을 물어보았습니다.
- 팀원들과 오랜 논의 끝에 채택한 방식은 좌표 시스템입니다.
- 말은 거창하지만, 사실 필기의 각 점 상대 좌표를 모두 저장해놓고, canvas의 사이즈가 변할 때, 저장되어 있었던 상대 좌표를 새로운 사이즈 속성 값을 갖는 canvas 위에 차례로 그려주는 방식입니다.
- 이 방식을 선택한 이유는 필기가 그려질 때 모든 좌표를 저장하는 방식이기 때문에 필기 데이터를 최대한 소실하지 않고, 저장할 수 있는 방식이라고 생각했습니다.
- 데이터를 저장하고, 다시 그려줘야 하는 번거로움은 있지만.. 😥
- DropyCanvas는 canvas에 대한 dropy 요구사항을 모두 가능하게 하는 모듈입니다.
- 상대 좌표 자동으로 저장하는 로직
- 상대 좌표 리스트를 input값으로 주면, 현재 canvas context에 다시 그려주는 로직 등
- 바닐라 자바스크립트로 모두 직접 구현한 모듈입니다.
- DrawingCanvas 모듈을 의존하고 있는 모듈이며, DrawingCanvas 모듈또한 바닐라 자바스크립트로 모두 직접 구현한 모듈입니다.
- DrawingCanvas 모듈은 실제로 cavnas context에 그림을 그려주고, 입력받은 상대 좌표 리스트를 기반으로 다시 그림을 그려주고, 캔버스의 content를 삭제해주는 로직과 같은 그리기 기능을 담당하고 있는 모듈입니다.
- 그림을 그리는 로직을 제외하고, canvas dom element에 이벤트를 추가해주는 로직, 특정 width, height를 갖고 있는 canvas를 렌더해주는 로직과 같은 그리기 기능 외 캔버스와 관련된 기능을 담당하고 있는 모듈입니다.
DropyCanvas 모듈의 함수들
- 마우스가 클릭된 채로 캔버스 위에서 움직일 때, event 객체의 offsetX, offsetY 값을 curPosition객체에 담아
addCanvasHistory
함수를 호출할 때, 매개변수로 전달해줍니다.
-
addCanvasHistory
함수는 curPosition, 현재 캔버스의 너비와 높이값을getRatioCoordinate
DropyCanvas 유틸함수의 매개변수로 전달하여, 상대 좌표를 구합니다.
-
getRatioCoordinate
함수는 캔버스의 너비를 x값(offsetX)값으로 나누어 상대 X 좌표(ratioX)를 구합니다. - 또한 캔버스의 너비를 Y값(offsetY) 값으로 나누어 상대 Y 좌표(ratioY)를 구합니다.
- 이와 같은 과정으로 구해진 ratioX, ratioY값을 history 배열에 저장하여, 특정 시점에 history 값을 데이터 베이스에 저장해 줍니다.
-
상대 좌표를 모두 저장했다면, resize가 완료된 캔버스에 상대 좌표를 이용해서 다시 그려줘야 합니다.
-
슬라이드 이미지의 크기가 변경되었을 때마다 변경된 캔버스 사이즈를
setSize
함수를 이용하여 설정해주고,reDrawContent
함수를 호출해줍니다.
-
reDrawContent
함수에 MouseMove 이벤트가 발생할 때마다 상대 좌표 데이터가 저장된 history 배열과 직전에setSize
함수로 설정해준 resize된 캔버스의 width와 height 값을 매개변수로 전달합니다.
-
DrawingCanvas 모듈의 reDrawContet는 상대 좌표 리스트(lineHistory)와 현재 resize가 완료된 canvasWidth, canvasHeight를 매개 변수로 받아 다시 그리기 로직을 처리합니다.
-
로직은 간단합니다. 예를 들어 [A,B,C,D] 상대 좌표가 있을 경우에는 lineHistory를 순회하면서,
- A 좌표로 moveTo, B 좌표로 lineTo, stroke();
- B 좌표로 moveTo, C 좌표로 lineTo, stroke();
- C 좌표로 moveTo, D 좌표로 lineTo, stroke();
-
이처럼 구현하게 된다면, 캔버스가 resize될 때, 기존의 필기 데이터가 resize된 캔버스에 비례하게 그려집니다.
-
기본 화면 사이즈 필기 화면
-
전체 화면 사이즈 필기 화면
- 페이지 별로 필기가 가능합니다
- 페이지를 이동할 때, 이전 페이지의 필기가 사라지고 새로운 페이지의 필기가 그려집니다. (이전에 필기 했던 내용이 있다면)
- 그림이 그려지면 데이터 베이스에 저장됩니다.
- 새로고침, 채널을 나갔다가 다시 들어와도 직접 필기를 지우지 않는 한 필기는 남아 있습니다.
- 이에 대한 기술공유도 빠른 시일 내에 작성하겠습니다! 기대해 주세요
긴 글 읽어주셔서 감사합니다. 다음 기술 공유는 더 좋은 내용으로 작성할 수 있도록 노력하겠습니다. 글에 대한 피드백은 언제나 환영입니다. 🥰
© BoostCamp 김김이조.
Members
'김'도현 (happydhKim) | '김'재원 (load0ne) | '이'미림 (always-awake) | '조'애리 (aereeeee)
-
Plans
-
Rules
-
Style Guides
-
Sprint Meeting Logs