import type { EditorState } from "@editor/state"; import { clearScreenRect } from "./clear-rect"; import type { WebGlRendererContext } from "./types"; const previewColor = [1, 0.18, 0.24, 0.95] as const; export function renderMaskShapePreview(context: WebGlRendererContext, editor: EditorState) { const session = editor.maskShapeSession; const points = session?.shape === "rectangle" && session.points.length > 1 ? rectanglePoints(session.points[0]!, session.points[1]!) : session?.points; if (!points || points.length === 0) return; const screenPoints = points.map((point) => ({ x: context.canvas.width / 2 + (point.x - editor.viewport.center.x) * editor.viewport.zoom, y: context.canvas.height / 2 + (point.y - editor.viewport.center.y) * editor.viewport.zoom, })); const closed = screenPoints.length > 2 ? [...screenPoints, screenPoints[0]!] : screenPoints; for (let index = 1; index < closed.length; index += 1) { const from = closed[index - 1]!; const to = closed[index]!; const distance = Math.max(1, Math.hypot(to.x - from.x, to.y - from.y)); const steps = Math.max(1, Math.ceil(distance / 3)); for (let step = 0; step <= steps; step += 1) { const amount = step / steps; clearScreenRect(context, { x: from.x + (to.x - from.x) * amount - 1.5, y: from.y + (to.y - from.y) * amount - 1.5, w: 3, h: 3 }, previewColor); } } } function rectanglePoints(start: { x: number; y: number }, end: { x: number; y: number }) { return [start, { x: end.x, y: start.y }, end, { x: start.x, y: end.y }]; }