캔버스의 영역과 범위에 관한 기술적 고민[Konva]

강지수·2025년 5월 3일
0

최종 프로젝트 Uuno

목록 보기
2/6

Uuno 에디터 개발 중 캔버스 범위 설정에 관한 고민과 해결 과정 공유.
미리캔버스나 다른 캔버스 기반 편집 툴과 우리 프로젝트의 차이점.

문제 발생

캔버스 기본 틀을 작성하는 도중 캔버스 내부에는 html태그가 안 먹힌다는 사실을 발견. 원래 의도는 캔버스를 전체 화면으로 두고 그 위에 html로 사이드 바, 툴 바 배치할 의도. 그러한게 불가능하다는 걸 알게 되면서 문제 발생

Konva의 구조 이해

canvas라이브러리인 konva의 구조를 이해해야함.

  • Stage : 전체 작업 공간으로 사용자가 보는 뷰 포인트
  • Layer : Stage 내부에 있는 투명한 캔버스로 여러 요소들을 그룹화하는 역할
  • Rect, Text, Image 등 : 실제 사용자가 조작하는 요소들로 Layer 위에 배치됨

이러한 구조는 계층적으로 Stage > Layer > 요소 의 형태를 가짐

미리캔버스와 우리 프로젝트의 차이점

미리캔버스나 많은 캔버스 툴들은 화면 전체가 캔버스처럼 보임. 하지만 실제로는 브라우저 화면이 모두 캔버스인 것이 아니라 화면 전체를 차지하는 컨테이너 안에 캔버스가 있는 구조라서, 사용자는 전체가 캔버스처럼 느껴짐.

왜 캔버스 크기를 명시적으로 지정해야 하는가?

프로젝트에서 캔버스의 넓이와 높이를 직접 계산해야 했던 이유는 다음과 같다.

사이드바와의 동적 상호작용

가장 중요한 이유는 사이드바가 열리고 닫힐 때 캔버스 영역을 동적으로 조절하기 위함. 사이드바가 열리면 캔버스 영역이 줄어들고, 닫히면 다시 늘어나야 하는데, 이를 위해서는 캔버스 크기를 정확히 계산하고 명시적으로 지정할 필요가 있었다.

실제 구현 방식

'use client';

import EditorCanvas from '@/components/editor/editor-canvas';
import EditorBottomTab from '@/components/editor/editor-ui/bottomTab/editor-bottom-tab';
import EditorSideBar from '@/components/editor/editor-ui/sidebar/editor-sidebar';
import EditorTopbar from '@/components/editor/editor-ui/topbar/editor-topbar';
import { sideBarStore } from '@/store/editor.sidebar.store';
import { useEffect, useRef, useState } from 'react';
const EditPage = () => {
  const containerRef = useRef<HTMLDivElement>(null);
  const sidebarStatus = sideBarStore((state) => state.sidebarStatus);
  const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 });

  useEffect(() => {
    const updateSize = () => {
      if (containerRef.current) {
        const { width, height } = containerRef.current.getBoundingClientRect();
        setCanvasSize({ width, height });
      }
    };
    updateSize();

    window.addEventListener('resize', updateSize);

    return () => window.removeEventListener('resize', updateSize);
  }, [sidebarStatus]);

  return (
    <div className='flex h-[calc(100vh-64px)] flex-row overflow-hidden'>
      <EditorSideBar />
      <div
        ref={containerRef}
        className='flex flex-1 flex-col bg-slate-400'
      >
        <EditorTopbar />
        <EditorCanvas canvasSize={canvasSize} />
        <EditorBottomTab />
      </div>
    </div>
  );
};

export default EditPage;

이 방식으로 사이드바가 열리고 닫힐 때마다 캔버스의 크기를 동적으로 조절할 수 있었다. 사이드바가 열리면 캔버스 영역이 줄어들고, 닫히면 다시 늘어나는 방식으로 작동한다.

최종 결론

미리캔버스와 같은 전문 디자인 툴은 사용자에게 "전체 화면이 캔버스"라는 경험을 제공하지만, 실제로는 정교한 UI 설계와 캔버스 관리 로직을 통해 이런 경험을 만들낸다.

이 프로젝트에서는:

  1. 사이드바 상태에 따라 컨테이너 크기를 감지하고 Stage 크기를 동적으로 계산
  2. 실제 편집 영역은 중앙에 배치된 Rect로 명확히 구분

캔버스 기반 애플리케이션을 개발할 때는 단순히 기술적 구현뿐만 아니라, 사용자 경험을 어떻게 설계할지, 그리고 UI 요소와 캔버스가 어떻게 상호작용할지에 대한 고민도 중요하다는 것을 깨닫게 되었다.

profile
프론트엔드 잘하고 싶다

0개의 댓글