이 프로젝트는 본부 내 프로젝트에서 사용되는 공통 CANVAS 라이브러리입니다.
npm install @deepnoid/canvas이 프로젝트는 본부 내 프로젝트에서 사용되는 공통 CANVAS 라이브러리입니다.
Canvas 기반 이미지 annotation 라이브러리로, TypeScript Engine + React Host 구조로 설계되었습니다.
- Engine (TS): Canvas 조작, 상태 관리, 이벤트 처리 등 핵심 로직
- React: UI 렌더링, DOM ref 관리, Engine 생명주기 관리
- ✏️ Rectangle annotation 그리기/편집
- 👁️ Viewer 모드 지원 (읽기 전용)
- 🔍 Pan & Zoom 지원
- ↩️ Undo/Redo 기능
- ⌨️ 단축키 지원
- 🎨 커스터마이징 가능한 스타일링
``bash`
npm install deepnoid-canvas
`tsx
import { AnnotationEditor } from 'deepnoid-canvas';
function App() {
const [annotations, setAnnotations] = useState([]);
return (
annotations={annotations}
setAnnotations={setAnnotations}
drawing={{
mode: 'RECTANGLE',
color: '#FF4136',
lineSize: 2,
}}
options={{
panZoomEnabled: true,
zoom: { min: 0.5, max: 4, step: 0.9 },
}}
enableHotkeys
/>
);
}
`
Editor 모드로 annotation을 생성하고 편집할 수 있습니다.
| Prop | Type | Required | Description |
| ---------------- | ------------------------------------- | -------- | -------------------------------- |
| image | string | ✅ | 이미지 URL |drawing
| | AnnotationCanvasDrawing | ✅ | 그리기 모드 및 스타일 설정 |annotations
| | Annotation[] | - | Annotation 목록 |setAnnotations
| | (annotations: Annotation[]) => void | - | Annotation 변경 시 호출되는 콜백 |options
| | AnnotationCanvasOptions | - | 줌/팬 및 기타 옵션 |events
| | AnnotationCanvasEvents | - | 이미지 로드 관련 이벤트 핸들러 |enableHotkeys
| | boolean | - | 단축키 활성화 여부 |
Viewer 모드로 annotation을 읽기 전용으로 표시합니다.
| Prop | Type | Required | Description |
| --------------- | -------------------------------------------------------------------------- | -------- | ------------------------------ |
| image | string | ✅ | 이미지 URL |drawing
| | Pick | ✅ | 렌더링 스타일 설정 (mode 제외) |annotations
| | Annotation[] | - | 표시할 Annotation 목록 |options
| | AnnotationCanvasOptions | - | 줌/팬 및 기타 옵션 |events
| | Pick | - | 이미지 로드 관련 이벤트 핸들러 |enableHotkeys
| | boolean | - | 단축키 활성화 여부 |
`jsx
import { AnnotationViewer } from 'deepnoid-canvas';
function App() {
const [annotations] = useState([{ type: 'RECTANGLE', x: 100, y: 100, width: 200, height: 150 }]);
return (
annotations={annotations}
drawing={{
lineSize: 2,
applyStyle: (params) => {
// 커스텀 스타일 적용
},
}}
options={{
panZoomEnabled: true,
}}
/>
);
}
`
`typescript
type AnnotationCanvasDrawing = {
mode?: 'RECTANGLE' | 'POLYGON' | 'NONE'; // 그리기 모드 (Editor 전용)
color?: string; // Annotation 색상 (HEX)
lineSize: number; // 선 두께
label?: Label; // Annotation에 표시할 라벨
applyStyle: ApplyAnnotationStyle; // 커스텀 스타일 함수
};
type Label = {
id: number;
name: string;
type: string;
};
type ApplyAnnotationStyle = (params: {
variant: 'drawRect' | 'drawText';
context: CanvasRenderingContext2D;
annotation: Annotation;
drawLineSize: number;
zoom: number;
}) => void;
`
`typescript`
type AnnotationCanvasOptions = {
panZoomEnabled?: boolean; // 줌/팬 기능 활성화 (기본: false)
zoom?: {
min?: number; // 최소 줌 배율 (기본: 0.1)
max?: number; // 최대 줌 배율 (기본: Infinity)
step?: number; // 줌 단계 (기본: 0.9)
};
ZoomButton?: ComponentType; // 커스텀 줌 버튼 컴포넌트
resetOnImageChange?: boolean; // 이미지 변경 시 줌 리셋 여부
};
`typescript`
type AnnotationCanvasEvents = {
onImageLoadSuccess?: () => void; // 이미지 로드 성공 시
onImageLoadError?: (error: Error) => void; // 이미지 로드 실패 시
};
| 키 | 기능 |
| -------------- | ----------------------------- |
| Delete | 선택한 annotation 삭제 |Ctrl+Z
| | Undo |Ctrl+Shift+Z
| | Redo |X
| | 선택한 annotation만 보기 토글 |
``
React Component
↓
AnnotationEngine (Facade)
↓ ↓ ↓ ↓ ↓
│ │ │ │ └─ History (Undo/Redo)
│ │ │ └─── PanZoomController
│ │ └───── InteractionController
│ └─────── Renderers
└───────── Annotation Controllers
```
src/
├─ engine/ # TypeScript Engine (순수 로직)
│ ├─ annotation/ # Annotation 타입별 로직
│ ├─ interaction/ # 이벤트 처리
│ ├─ pan-zoom/ # 줌/이동 기능
│ ├─ public/ # 외부 공개 API
│ └─ renderer/ # Canvas 렌더링
│
└─ react/ # React 컴포넌트
├─ hooks/
└─ AnnotationCanvas.tsx
1. 관심사 분리: Engine(로직) ↔ React(UI) 완전 분리
2. 확장성: 새로운 annotation 타입 추가 용이
3. 성능 최적화: 레이어별 redraw 제어