Files
Aislo/B07_DesignDetail/openwebcad/src/helpers/draw.ts
T
eomsangdonandClaude Opus 5.5 3e5b7cf21f feat(b07): 도면 작도 영역 가이드 선 · 숫자 칸 공용 부품 · 끌기 · 도각 편집 영역 저장 (169-1·169-3·169-4)
- 그림칸 = 양식 drawing_area 그대로(여백 2 % 없앰) · 도각 편집이 영역 싣고 [완료] 때 저장
- 도면 응답 guide(작도 영역 도면 좌표) · M02 구조물 도각 응답 area
- CAD 그리기 겹판 점선 사각형(저장 · DXF · 인쇄 제외) · 모서리 · 변 끌기(도각 편집 · M02 양식만)
- 숫자 칸 공용 부품(왼쪽 · 위 · 폭 · 높이 mm) — M02 양식 · B07 도각 편집 · 끌기와 한 벌
- B08 구조물도 · M02 도면 카드 = 얹은 도각 영역 가이드(보기만)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TNMXVCZXMpHpVvqmFkeChL
2026-10-10 08:35:31 +09:00

80 lines
2.6 KiB
TypeScript

import { compact } from 'es-toolkit';
import { HOVERED_SNAP_POINT_TIME } from '../App.consts';
import type { ScreenCanvasDrawController } from '../drawControllers/screenCanvas.drawController';
import {
getAngleGuideEntities,
getDebugEntities,
getEntities,
getGhostHelperEntities,
getHighlightedEntityIds,
getHoveredSnapPoints,
getInputController,
getSelectedEntities,
getShouldDrawCursor,
getSnapPoint,
getSnapPointOnAngleGuide,
isOriginMarker,
isViewOnly,
} from '../state';
import {
drawCursor,
drawDebugEntities,
drawEntities,
drawGrips,
drawHelpers,
drawOriginMarker,
drawSnapPoint,
} from './draw-functions';
import { getClosestSnapPoint } from './get-closest-snap-point';
import { isPointEqual } from './is-point-equal';
import { drawScene } from './scene-cache';
import { drawGuide } from '../integration/guide-area';
/**
* Hover highlight is excluded from the static scene cache (it changes every
* mouse move) — re-draw the few highlighted entities on top of the blit.
*/
function drawHighlightedEntities(drawController: ScreenCanvasDrawController) {
const highlightedIds = getHighlightedEntityIds();
if (!highlightedIds.length) return;
const idSet = new Set(highlightedIds);
drawEntities(
drawController,
getEntities().filter((entity) => idSet.has(entity.id))
);
}
export function draw(drawController: ScreenCanvasDrawController) {
drawController.clear();
// Static scene (all entities): cached bitmap blit, rebuilt only when needed.
drawScene(drawController, performance.now());
drawHighlightedEntities(drawController);
if (isOriginMarker()) drawOriginMarker(drawController);
drawGuide(drawController); // 작도 영역 점선(169-1) — 겹판이라 저장 · 인쇄 안 됨
drawGrips(drawController, getSelectedEntities());
drawHelpers(drawController, getAngleGuideEntities());
drawEntities(drawController, getGhostHelperEntities());
drawDebugEntities(drawController, getDebugEntities());
const { snapPoint: closestSnapPoint } = getClosestSnapPoint(
compact([getSnapPoint(), getSnapPointOnAngleGuide()]),
drawController.getWorldMouseLocation()
);
const isMarked =
!!closestSnapPoint &&
getHoveredSnapPoints().some(
(hoveredSnapPoint) =>
hoveredSnapPoint.milliSecondsHovered > HOVERED_SNAP_POINT_TIME &&
isPointEqual(hoveredSnapPoint.snapPoint.point, closestSnapPoint.point)
);
drawSnapPoint(drawController, closestSnapPoint, isMarked);
// 미리보기는 십자 커서 · 명령 안내 · 좌표 풍선을 그리지 않는다(손 모양 커서).
if (getShouldDrawCursor() && !isViewOnly()) {
drawCursor(drawController);
getInputController().draw(drawController);
}
}