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, } from '../state'; import { drawCursor, drawDebugEntities, drawEntities, drawGrips, drawHelpers, drawSnapPoint, } from './draw-functions'; import { getClosestSnapPoint } from './get-closest-snap-point'; import { isPointEqual } from './is-point-equal'; import { drawScene } from './scene-cache'; /** * 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); 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()) { drawCursor(drawController); getInputController().draw(drawController); } }