Frontend / Graphics • 2026. 01. 18

Canvas API로 만드는 실시간 협업 드로잉 보드

디지털 협업의 핵심은 '생각의 시각화'입니다. 텍스트로만 이루어진 채팅 환경에서는 복잡한 구조나 직관적인 아이디어를 전달하는 데 한계가 있습니다. eleslog.work공유 캔버스 기능은 단순한 그림판을 넘어, 멀리 떨어진 사람들이 같은 화이트보드 앞에 서 있는 것과 같은 경험을 제공하기 위해 개발되었습니다.

브라우저라는 한정된 환경 내에서 어떻게 수천 개의 선을 부드럽게 그려내고, 이를 지연 시간 없이 전 세계 사용자들과 공유할 수 있을까요? 이번 포스팅에서는 웹 그래픽 기술의 정수인 Canvas API와 실시간 통신 기술의 결합 과정을 심도 있게 다뤄보겠습니다.

1. Canvas API의 기초: 웹 브라우저에 그리는 도화지

HTML5의 <canvas> 요소는 단순한 이미지 태그와 다릅니다. 이는 자바스크립트를 통해 픽셀 하나하나를 제어할 수 있는 '비트맵 도화지'입니다. 사용자가 마우스를 클릭하고 움직이는 순간, 브라우저는 발생한 좌표를 계산하여 실시간으로 경로(Path)를 생성합니다.

핵심 원리:
그림을 그린다는 것은 수학적인 점들의 연결입니다. 마우스가 움직일 때마다 '이전 좌표(Prev)'에서 '현재 좌표(Curr)'까지 아주 짧은 직선을 계속해서 그려나가는 과정이 우리가 보는 매끄러운 곡선의 실체입니다.

// 실시간 드로잉을 위한 렌더링 컨텍스트 설정
const canvas = document.getElementById("drawingCanvas");
const ctx = canvas.getContext("2d");

// 선의 스타일 정의 (굵기, 끝 모양, 색상)
ctx.lineWidth = 5;
ctx.lineCap = "round";
ctx.strokeStyle = "#8b5cf6";

// 실제 드로잉 수행 로직
function draw(prevX, prevY, currX, currY) {
  ctx.beginPath();       // 새로운 경로 시작
  ctx.moveTo(prevX, prevY); // 시작점으로 이동
  ctx.lineTo(currX, currY); // 현재점까지 선 연결
  ctx.stroke();          // 선을 화면에 렌더링
}
        

이 과정에서 중요한 것은 lineCap 속성입니다. 이를 'round'로 설정하지 않으면 선의 연결 부위가 거칠게 표현되어 사용자 경험을 저해할 수 있습니다. eleslog.work는 이러한 세밀한 디테일까지 고려하여 최적의 필기감을 구현했습니다.

2. 실시간 좌표 동기화: 지연 없는 협업의 비밀

혼자 그리는 그림판은 쉽지만, '공유'가 시작되는 순간 기술적 난이도는 급상승합니다. 내가 브라우저에 선을 긋는 순간, 그 데이터는 서버를 거쳐 상대방의 브라우저에도 똑같이 그려져야 합니다. 이를 위해 우리는 Websocket(Socket.io) 기술을 사용합니다.

하지만 단순히 모든 데이터를 전송하는 것은 비효율적입니다. 드로잉 데이터는 양이 방대하기 때문에 전송 데이터의 구조를 최적화해야 합니다. eleslog.workDelta(변화량) 전송 방식을 채택하여, 전체 그림 데이터가 아닌 '방금 그려진 짧은 선의 정보'만을 패킷에 담아 보냅니다.


// 드로잉 이벤트 발생 시 서버로 데이터 전송
function broadcastDrawing(data) {
  const payload = {
    x1: data.prevX,
    y1: data.prevY,
    x2: data.currX,
    y2: data.currY,
    c: data.color, // 데이터 압축을 위해 짧은 키 이름 사용
    w: data.width
  };
  socket.emit("draw_event", payload);
}
        

동기화 시 고려해야 할 요소

3. 성능 최적화: Throttling과 RequestAnimationFrame

컴퓨터 마우스는 초당 수백 번의 움직임 이벤트를 발생시킵니다. 이 모든 신호를 서버로 보내면 서버는 금방 마비될 것이고, 브라우저의 화면은 버벅거리기 시작할 것입니다. 이를 해결하기 위해 두 가지 핵심 최적화 기법을 적용했습니다.

쓰로틀링(Throttling)을 통한 트래픽 제어

쓰로틀링은 정해진 시간(예: 10ms) 동안 발생한 수많은 이벤트 중 마지막 하나만 처리하는 기술입니다. 이를 통해 사용자에게는 차이를 느끼지 못할 정도의 부드러움을 유지하면서도, 서버로 전송되는 데이터양은 70% 이상 절감할 수 있었습니다.

RequestAnimationFrame(rAF) 활용

브라우저의 주사율(보통 60Hz)에 맞춰 렌더링을 수행하는 requestAnimationFrame을 사용하여, 불필요한 그리기 작업을 줄이고 CPU 점유율을 최적화했습니다. 이는 특히 저사양 기기나 모바일 환경에서 웹 성능을 유지하는 데 결정적인 역할을 합니다.

최적화의 결과:
이러한 기법들을 통해 eleslog.work의 공유 캔버스는 동시 접속자가 10명을 넘어가더라도 프레임 드랍 없이 안정적인 드로잉 환경을 유지할 수 있게 되었습니다.

마치며: 시각적 소통의 미래

실시간 공유 캔버스는 단순한 기능을 넘어 사람과 사람을 잇는 새로운 대화 방식입니다. 코드로 도화지를 만들고, 수학으로 선을 잇고, 네트워크로 마음을 전달하는 이 과정은 현대 프론트엔드 개발이 지향해야 할 사용자 중심의 가치를 잘 보여줍니다.

현재 eleslog.work 시스템은 기본적인 선 그리기를 넘어 도형 그리기, 텍스트 입력, 그리고 그린 내용을 이미지 파일로 저장하는 기능까지 확장 중입니다. 다음 포스팅에서는 대규모 사용자가 접속했을 때 발생하는 동시성 충돌 해결(Conflict Resolution)과 캔버스 상태 보존 전략에 대해 심도 있게 다뤄보도록 하겠습니다.

기술의 벽을 넘어 더 자유로운 소통이 가능한 세상을 만드는 여정에 함께해주셔서 감사합니다.