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, isDrawingReadOnly, 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) — 겹판이라 저장 · 인쇄 안 됨 // 보기 전용 · 확정 도면은 그립 없음(H2 — 집지도 못함) if (!isViewOnly() && !isDrawingReadOnly()) 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); } }