-
Notifications
You must be signed in to change notification settings - Fork 7
4. 라이브러리 없이 Canvas 구현하기
D.Joung edited this page Dec 5, 2024
·
6 revisions
Canvas API는 HTML Element를 통해 화면에 그리기를 할 수 있는 JavaScript 도구들을 제공합니다. 주로 2D 그래픽에 중점을 두고 있으며 CanvasRenderingContext2D
객체로 2D 비트맵 이미지를 그릴 수 있습니다.
- 프로젝트 주요 구현 주제 중 하나인 실시간 드로잉 기능을 구현하기 위해서는, 플레이어들이 그림을 그려갈 캔버스를 구현해야 했습니다.
- 캔버스를 구현할 수 있는 다양한 라이브러리들이 있지만,
캔버스에 대한 깊은 이해
와외부 의존성 최소화
를 도전 과제로 삼고 라이브러리 없이 Canvas API만을 활용해 구현해보기로 했습니다. - 이를 위해 Canvas API를 직접 다뤄보는 것은 처음이었기에 작동 원리와 기초 사용법에 대한 학습이 선행되어야 했습니다.
Important
- 팀원들과 상의해 캔버스 기능을 아래와 같이 구현하기로 정했습니다.
- 펜 툴 : 마우스의 경로를 따라 선을 드로잉
- 페인트 툴 : 픽셀 잔여량 만큼 클릭한 좌표를 중심으로 색을 채움
- 색상 선택 툴 : 색상을 변경할 수 있음
- 두께 조절 툴 : 펜 툴의 선 두께를 변경할 수 있음
- Undo / Redo : 내가 그린 선 한정으로 캔버스 상태를 뒤로가기 및 복구
- 픽셀 잔여량 표시 : 사용 가능한 잔여 픽셀량을 표시
- MouseEvent 및 TouchEvent를 활용해 사용자와 상호작용 하였고, 구현 과정에서 아래와 같은 이슈 & 구현 과제가 발생했습니다.
- 캔버스 터치 시 화면이 같이 움직임 (화면 스크롤링이 활성화)
- MouseEvent와 TouchEvent가 제공하는 좌표 속성이 다름
- 캔버스 페인트 툴 기능 구현
Important
-
Undo & Redo 제외한 캔버스의 기본 기능이 모두 구현된 후, 사용자 경험을 헤칠 수 있는 두 가지 이슈가 발생했습니다.
- 빠르게 그렸을 때 캔버스 모서리에서 선이 끊김
- 선을 그릴 때 (샘플링 좌표 기준으로) 각이 짐
- 선이 마우스를 조금 늦게 따라옴
-
1, 2번 이슈는 드로잉 로직에 보간법을 추가해 해결하였습니다.
-
하지만 보간법은 드로잉 로직과 관련이 있고, 드로잉 로직은 CRDT 및 소켓 연결과 관련이 있었기에, CRDT 작업이 완료되기까지 병합이 연기되었습니다.
-
모든 기능이 구현된 6주 차,
빠르게 그렸을 때 캔버스 모서리에서 선이 끊김
이슈는 CPU 작업량 문제로 지연이 발생해 적용을 미루게 되었고,선을 그릴 때 (샘플링 좌표 기준으로) 각이 짐
이슈 개선 내용만 적용하게 되었습니다.
Important
- Undo & Redo 구현은 1인용 캔버스에서는 구현이 매우 단순했지만, 동시 편집 캔버스에서는 난이도가 상승했습니다.
- 또한, Undo & Redo는 CRDT 로직과도 연관이 있어, Canvas 단에서는 이후 CRDT 로직 구현 시 참고할만한 기능 프로토타입을 먼저 만들어보기로 했습니다.
- 이후 Undo & Redo 구현 로직은 CRDT 로직 구현과 병행 작업되어,
stroke 단위 관리
로 구현되었다가, 다시path 단위 관리
로 변경되어 최종 구현 되었습니다.
Important
- 4-5주차에는
윈도우에서 그리면 렉이 심해지는
이슈가 발생했습니다. - 해당 이슈는 CRDT 로직 단에서 주요하게 수정해야할 점들이 있었지만, 캔버스 측에서도 최적화 할 수 있는 방안을 몇 가지 시도해보았습니다.
- 아래 세 가지 측면에서의 최적화를 시도하였고, 결과적으로 시작 페이지의 캔버스에만 requestAnimationFrame 및 throttle을 추가하였습니다.
- requestAnimationFrame으로 좌표 전송 및 드로잉 주기 최적화 (시작 페이지)
- throttle로 좌표 샘플링 주기 최적화 (시작 페이지)
- OffScreenCanvas로 GPU 단에서의 렌더링 (미적용)
-
캔버스 배경화면에 들어갈 패턴 이미지를 제작해야했는데, 캔버스에서 랜덤한 위치에 패턴을 찍은 후 export 하였습니다.
-
또한, 꼬리가 길게 이어지는 모양의 커스텀 커서를 제작했습니다.
-
커스텀 커서는 게임 캔버스에서도
선이 마우스를 조금 늦게 따라오는
사용성 이슈를 해결하기 위해 적용되었습니다.
Important
- 1. 개발 환경 세팅 및 프로젝트 문서화
- 2. 실시간 통신
- 3. 인프라 및 CI/CD
- 4. 라이브러리 없이 Canvas 구현하기
- 5. 캔버스 동기화를 위한 수제 CRDT 구현기
- 6. 컴포넌트 패턴부터 웹소켓까지, 효율적인 FE 설계
- 7. 트러블 슈팅 및 성능/UX 개선
- WEEK 06 주간 계획
- WEEK 06 데일리 스크럼
- WEEK 06 주간 회고