From 2ec337433378f6c161f01e59b4e8fc4a294d220a Mon Sep 17 00:00:00 2001 From: Mark Tolmacs Date: Thu, 3 Oct 2024 14:09:44 +0200 Subject: [PATCH] Add visual debug support for arc --- excalidraw-app/components/DebugCanvas.tsx | 36 ++++++++++++++++++++++- packages/excalidraw/visualdebug.ts | 18 ++++++++++-- packages/math/arc.ts | 17 ++++++++++- 3 files changed, 67 insertions(+), 4 deletions(-) diff --git a/excalidraw-app/components/DebugCanvas.tsx b/excalidraw-app/components/DebugCanvas.tsx index 9606d4e3ff..7243551abb 100644 --- a/excalidraw-app/components/DebugCanvas.tsx +++ b/excalidraw-app/components/DebugCanvas.tsx @@ -12,7 +12,13 @@ import { TrashIcon, } from "../../packages/excalidraw/components/icons"; import { STORAGE_KEYS } from "../app_constants"; -import { isSegment, type GlobalPoint, type Segment } from "../../packages/math"; +import type { Arc } from "../../packages/math"; +import { + isArc, + isSegment, + type GlobalPoint, + type Segment, +} from "../../packages/math"; const renderLine = ( context: CanvasRenderingContext2D, @@ -29,6 +35,26 @@ const renderLine = ( context.restore(); }; +const renderArc = ( + context: CanvasRenderingContext2D, + zoom: number, + a: Arc, + color: string, +) => { + context.save(); + context.strokeStyle = color; + context.beginPath(); + context.arc( + a.center[0] * zoom, + a.center[1] * zoom, + a.radius * zoom, + a.startAngle, + a.endAngle, + ); + context.stroke(); + context.restore(); +}; + const renderOrigin = (context: CanvasRenderingContext2D, zoom: number) => { context.strokeStyle = "#888"; context.save(); @@ -56,6 +82,14 @@ const render = ( el.color, ); break; + case isArc(el.data): + renderArc( + context, + appState.zoom.value, + el.data as Arc, + el.color, + ); + break; } }); }; diff --git a/packages/excalidraw/visualdebug.ts b/packages/excalidraw/visualdebug.ts index 21b027d740..3213b9de1d 100644 --- a/packages/excalidraw/visualdebug.ts +++ b/packages/excalidraw/visualdebug.ts @@ -1,4 +1,4 @@ -import type { Segment } from "../math"; +import type { Arc, Segment } from "../math"; import { isSegment, segment, pointFrom, type GlobalPoint } from "../math"; import { isBounds } from "./element/typeChecks"; import type { Bounds } from "./element/types"; @@ -15,10 +15,24 @@ declare global { export type DebugElement = { color: string; - data: Segment; + data: Segment | Arc; permanent: boolean; }; +export const debugDrawArc = ( + a: Arc, + opts?: { + color?: string; + permanent?: boolean; + }, +) => { + addToCurrentFrame({ + color: opts?.color ?? "blue", + permanent: !!opts?.permanent, + data: a, + }); +}; + export const debugDrawLine = ( segment: Segment | Segment[], opts?: { diff --git a/packages/math/arc.ts b/packages/math/arc.ts index 4e58f4fc31..47d2434f4f 100644 --- a/packages/math/arc.ts +++ b/packages/math/arc.ts @@ -5,7 +5,7 @@ import { ellipseLineIntersectionPoints, ellipseSegmentInterceptPoints, } from "./ellipse"; -import { pointFrom, pointDistance } from "./point"; +import { pointFrom, pointDistance, isPoint } from "./point"; import type { GenericPoint, Segment, Radians, Arc, Line } from "./types"; import { PRECISION } from "./utils"; @@ -135,3 +135,18 @@ export function arcLineInterceptPoints( : a.startAngle <= candidateAngle || a.endAngle >= candidateAngle; }); } + +export function isArc(v: unknown): v is Arc { + return ( + v != null && + typeof v === "object" && + Object.hasOwn(v, "center") && + Object.hasOwn(v, "radius") && + Object.hasOwn(v, "startAngle") && + Object.hasOwn(v, "endAngle") && + isPoint((v as Arc).center) && + typeof (v as Arc).radius === "number" && + typeof (v as Arc).startAngle === "number" && + typeof (v as Arc).endAngle === "number" + ); +}