-
Notifications
You must be signed in to change notification settings - Fork 8
두 Client간의 canvas화면 동기화 방법
changgunyee edited this page Dec 21, 2019
·
2 revisions
- 다양한 도구 지원 - 펜 뿐만 아니라 선, 원, 직사각형 등의 도구를 지원
- 움짤 기능을 위한 캔버스 데이터 저장 기능
움짤 기능을 사용하기 위해서는 데이터 파싱 기능을 가진 패키지가 필요하였습니다.
많은 캔버스를 이용한 패키지가 있었습니다.
그 중에서도 캔버스의 내용을 객체 단위로 관리하고 효과적인 데이터 파싱 기능을 가진 Fabric.js를 선택하게 되었습니다.
클라이언트 간의 캔버스를 동기화하는 것은 성공! but....
나름 좋은 성능을 자랑하는 것 같으나 캔버스에 그림이 많으면 데이터량이 너무 큽니다.(이럴 필요가 있을까?)
-> 좌표, 선 색과 같은 꼭 필요한 데이터만 보내서 동기화를 시켜보자
실시간 동기화가 필요한 펜 같은 경우에는 좌표들만을 받아 만든 점들을 하나의 선, Object로 만드는 것이 Fabric에서 지원하는 API만으로 구현이 불가능하였습니다.
왼쪽은 출제자가 그린 선이고 오른쪽은 비출제자가 좌표 데이터를 받아 Point로 객체를 만든 경우입니다.
돌아가서 raw한 캔버스API를 이용하여 도구를 직접 만드는 것 또한 방법입니다. 하지만 돌아가기엔 너무 늦었습니다. 이렇게 된 이상 패키지를 분석해 어떻게 Fabric은 Object를 구성하는지를 분석해보았습니다.
- mouseDown이 되면 _points를 모으기 시작합니다.
- mouseMove동안 생긴 Point를 _points에 추가합니다.
- mouseUp이 되면 _points를 string으로 변환한 후 Path를 새로만들어 Fabric에 넣어줍니다.
_captureDrawingPath(pointer) {
const pointerPoint = new fabric.Point(pointer.x, pointer.y);
return this._addPoint(pointerPoint);
}
onMouseDown(pointer) {
this._captureDrawingPath(pointer);
},
onMouseMove(pointer) {
//_points에 Point객체 추가
},
onMouseUp() {
this._finalizeAndAddPath();
},
_finalizeAndAddPath() {
const pathData = this.convertPointsToSVGPath(this._points).join('');
const path = this.createPath(pathData);
this.canvas.add(path);
}
Fabric에서는 해당 기능들을 내부적으로(closure로 감싸서) 사용하고 있습니다. 따라서 해당 코드를 직접 저희 canvas의 툴의 기능에 넣어주어 구현하였습니다.
Fabric내부의 방식에 따라 비출제자의 캔버스에 그려주었더니 완벽한 동기화가 구현되었습니다.