2D: Bezier-Hilfslinien beim Editieren + Kreis kann zur Ellipse werden
Bezier: Anker→Griff-Verbindungen werden beim Editieren (Selektion) gestrichelt angezeigt, nicht nur während des Zeichnens — macht sichtbar, welcher Griff welchen Kurvenabschnitt steuert (wie bei üblichen Vektor-Editoren). Kreis: bekommt wie die Ellipse zwei Griffe (Ost/Nord). Zieht man einen davon unabhängig, wird der Kreis zur Ellipse (rotation 0); nähern sich die Halbachsen beim Ziehen wieder an, wird daraus wieder ein Kreis. Erstellen bleibt unverändert ein normaler Kreis — der Formwandel passiert nur beim Bearbeiten.
This commit is contained in:
@@ -1293,6 +1293,7 @@ export default function App() {
|
|||||||
// Auswahl — siehe state/useGripEditing.ts.
|
// Auswahl — siehe state/useGripEditing.ts.
|
||||||
const {
|
const {
|
||||||
grips,
|
grips,
|
||||||
|
gripHandleLines,
|
||||||
edgeGrips,
|
edgeGrips,
|
||||||
gripHandlers,
|
gripHandlers,
|
||||||
gripEdit,
|
gripEdit,
|
||||||
@@ -2800,6 +2801,7 @@ export default function App() {
|
|||||||
toolHandlers={toolHandlers}
|
toolHandlers={toolHandlers}
|
||||||
hudFields={hudFields}
|
hudFields={hudFields}
|
||||||
grips={grips}
|
grips={grips}
|
||||||
|
gripHandleLines={gripHandleLines}
|
||||||
edgeGrips={edgeGrips}
|
edgeGrips={edgeGrips}
|
||||||
selectedDrawingId={selectedDrawingId}
|
selectedDrawingId={selectedDrawingId}
|
||||||
selectedDrawingIds={selectedDrawingIds}
|
selectedDrawingIds={selectedDrawingIds}
|
||||||
|
|||||||
@@ -382,6 +382,12 @@ export interface PlanViewProps {
|
|||||||
* Auswahl-Werkzeug sichtbar/aktiv.
|
* Auswahl-Werkzeug sichtbar/aktiv.
|
||||||
*/
|
*/
|
||||||
grips?: Vec2[];
|
grips?: Vec2[];
|
||||||
|
/**
|
||||||
|
* Bezier-Hilfslinien (Anker → Kontrollpunkt-Griff) des selektierten
|
||||||
|
* Elements — gestrichelt gerendert, damit sichtbar bleibt, welcher Griff
|
||||||
|
* welchen Kurvenabschnitt steuert (s. `useGripEditing.ts`).
|
||||||
|
*/
|
||||||
|
gripHandleLines?: { a: Vec2; b: Vec2 }[];
|
||||||
/**
|
/**
|
||||||
* Kanten-/Seiten-Griffe (Edge Grips) des selektierten Elements: je Seite ein
|
* Kanten-/Seiten-Griffe (Edge Grips) des selektierten Elements: je Seite ein
|
||||||
* dreieckiger Anfasser am Kanten-Mittelpunkt, dessen Spitze nach AUSSEN zeigt.
|
* dreieckiger Anfasser am Kanten-Mittelpunkt, dessen Spitze nach AUSSEN zeigt.
|
||||||
@@ -499,6 +505,7 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
|
|||||||
showRulers = true,
|
showRulers = true,
|
||||||
hudFields,
|
hudFields,
|
||||||
grips,
|
grips,
|
||||||
|
gripHandleLines,
|
||||||
edgeGrips,
|
edgeGrips,
|
||||||
hairline,
|
hairline,
|
||||||
selectedDrawingId,
|
selectedDrawingId,
|
||||||
@@ -2581,6 +2588,21 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
|
|||||||
pointerEvents="none"
|
pointerEvents="none"
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{/* Bezier-Hilfslinien (Anker → Griff), gestrichelt — VOR den Griff-
|
||||||
|
Quadraten gezeichnet, damit die Griffe oben liegen (anklickbar). */}
|
||||||
|
{gripsActive &&
|
||||||
|
gripHandleLines &&
|
||||||
|
gripHandleLines.map((l, i) => (
|
||||||
|
<line
|
||||||
|
key={`gripline-${i}`}
|
||||||
|
className="plan-grip-line"
|
||||||
|
x1={toScreen(l.a).x}
|
||||||
|
y1={toScreen(l.a).y}
|
||||||
|
x2={toScreen(l.b).x}
|
||||||
|
y2={toScreen(l.b).y}
|
||||||
|
pointerEvents="none"
|
||||||
|
/>
|
||||||
|
))}
|
||||||
{/* Editier-Griffe des selektierten Elements (Wand-Enden / 2D-Vertices):
|
{/* Editier-Griffe des selektierten Elements (Wand-Enden / 2D-Vertices):
|
||||||
ziehbare Quadrate. Bildschirmkonstante Größe über die meet-Skala. */}
|
ziehbare Quadrate. Bildschirmkonstante Größe über die meet-Skala. */}
|
||||||
{gripsActive &&
|
{gripsActive &&
|
||||||
|
|||||||
@@ -40,9 +40,9 @@ beforeEach(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("drawingVertices — Kreis/Bogen", () => {
|
describe("drawingVertices — Kreis/Bogen", () => {
|
||||||
it("Kreis liefert einen Radius-Griff auf der Ost-Seite", () => {
|
it("Kreis liefert zwei Griffe (Ost/Nord) — wie eine Ellipse", () => {
|
||||||
const v = drawingVertices(circleDrawing);
|
const v = drawingVertices(circleDrawing);
|
||||||
expect(v).toEqual([{ x: 3, y: 3 }]);
|
expect(v).toEqual([{ x: 3, y: 3 }, { x: 2, y: 4 }]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Bogen liefert Start-/End-/Mittel-Winkel-Griffe", () => {
|
it("Bogen liefert Start-/End-/Mittel-Winkel-Griffe", () => {
|
||||||
@@ -55,8 +55,21 @@ describe("drawingVertices — Kreis/Bogen", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("moveGripOf — Kreis/Bogen", () => {
|
describe("moveGripOf — Kreis/Bogen", () => {
|
||||||
it("Kreis-Griff ziehen ändert nur den Radius, nicht das Zentrum", () => {
|
it("Kreis-Ost-Griff auf denselben Radius gezogen bleibt ein Kreis", () => {
|
||||||
getState().moveGripOf("d-circle", null, 0, { x: 5, y: 3 }); // 3m vom Zentrum
|
getState().moveGripOf("d-circle", null, 0, { x: 3, y: 3 }); // weiterhin 1m Ost
|
||||||
|
const g = getState().project.drawings2d.find((d) => d.id === "d-circle")!.geom;
|
||||||
|
expect(g).toMatchObject({ shape: "circle", center: { x: 2, y: 3 }, r: 1 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Kreis-Ost-Griff auf einen ANDEREN Radius gezogen wird zur Ellipse (Nutzer-Wunsch: Kreis kann beim Bearbeiten zur Ellipse werden)", () => {
|
||||||
|
getState().moveGripOf("d-circle", null, 0, { x: 5, y: 3 }); // 3m Ost statt 1m
|
||||||
|
const g = getState().project.drawings2d.find((d) => d.id === "d-circle")!.geom;
|
||||||
|
expect(g).toMatchObject({ shape: "ellipse", center: { x: 2, y: 3 }, rx: 3, ry: 1, rotation: 0 });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Ellipse-Griff zurück auf (fast) gleiche Halbachsen gezogen wird wieder zum Kreis", () => {
|
||||||
|
getState().moveGripOf("d-circle", null, 0, { x: 5, y: 3 }); // → Ellipse rx=3, ry=1
|
||||||
|
getState().moveGripOf("d-circle", null, 1, { x: 2, y: 6 }); // Nord-Griff auf ry=3
|
||||||
const g = getState().project.drawings2d.find((d) => d.id === "d-circle")!.geom;
|
const g = getState().project.drawings2d.find((d) => d.id === "d-circle")!.geom;
|
||||||
expect(g).toMatchObject({ shape: "circle", center: { x: 2, y: 3 }, r: 3 });
|
expect(g).toMatchObject({ shape: "circle", center: { x: 2, y: 3 }, r: 3 });
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1452,6 +1452,24 @@ function resizeGeom(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kreis, solange rx≈ry (relative Toleranz 0.5%) — sonst Ellipse (rotation 0).
|
||||||
|
* Trägt den Kreis-zu-Ellipse-Formwandel beim Griff-Ziehen (Nutzer-Wunsch:
|
||||||
|
* „Kreis wird wie bisher erstellt, kann beim Bearbeiten zur Ellipse werden");
|
||||||
|
* symmetrisch nutzbar auch für die Rückrichtung (Ellipse → Kreis, wenn man
|
||||||
|
* die Halbachsen wieder aneinander annähert).
|
||||||
|
*/
|
||||||
|
function ellipseOrCircle(
|
||||||
|
center: Vec2,
|
||||||
|
rx: number,
|
||||||
|
ry: number,
|
||||||
|
): import("../model/types").Drawing2DGeom {
|
||||||
|
if (Math.abs(rx - ry) <= 0.005 * Math.max(rx, ry)) {
|
||||||
|
return { shape: "circle", center, r: (rx + ry) / 2 };
|
||||||
|
}
|
||||||
|
return { shape: "ellipse", center, rx, ry, rotation: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
// ── Editier-Griffe (verschoben aus App.tsx, 1:1) ─────────────────────────────
|
// ── Editier-Griffe (verschoben aus App.tsx, 1:1) ─────────────────────────────
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1472,8 +1490,16 @@ export function drawingVertices(d: import("../model/types").Drawing2D): Vec2[] {
|
|||||||
{ x: g.min.x, y: g.max.y },
|
{ x: g.min.x, y: g.max.y },
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
// Kreis: zwei Griffe (Ost/Nord, wie bei der Ellipse) — zieht man EINEN der
|
||||||
|
// beiden unabhängig, wird der Kreis zur Ellipse (s. `moveGrip`). So bleibt
|
||||||
|
// ein Kreis ein Kreis, solange man ihn nicht gezielt verzerrt (Nutzer-
|
||||||
|
// Wunsch: „Kreis erstellen wie bisher, beim Bearbeiten kann er zur Ellipse
|
||||||
|
// werden").
|
||||||
if (g.shape === "circle") {
|
if (g.shape === "circle") {
|
||||||
return [{ x: g.center.x + g.r, y: g.center.y }];
|
return [
|
||||||
|
{ x: g.center.x + g.r, y: g.center.y },
|
||||||
|
{ x: g.center.x, y: g.center.y + g.r },
|
||||||
|
];
|
||||||
}
|
}
|
||||||
if (g.shape === "arc") {
|
if (g.shape === "arc") {
|
||||||
const mid = (g.a0 + g.a1) / 2;
|
const mid = (g.a0 + g.a1) / 2;
|
||||||
@@ -1569,10 +1595,14 @@ function moveGrip(
|
|||||||
}
|
}
|
||||||
// Text: der einzige Griff (Index 0) sitzt am Ankerpunkt → verschiebt ihn.
|
// Text: der einzige Griff (Index 0) sitzt am Ankerpunkt → verschiebt ihn.
|
||||||
if (g.shape === "text") return { ...d, geom: { ...g, at: pt } };
|
if (g.shape === "text") return { ...d, geom: { ...g, at: pt } };
|
||||||
// Kreis: der einzige Griff (Index 0) ändert nur den Radius.
|
// Kreis: Griff 0 (Ost) bzw. 1 (Nord) — zieht man die beiden Achsen
|
||||||
|
// unabhängig auseinander, wird der Kreis zur Ellipse (rotation 0);
|
||||||
|
// bleiben rx/ry (fast) gleich, bleibt es ein Kreis (s. `ellipseOrCircle`).
|
||||||
if (g.shape === "circle") {
|
if (g.shape === "circle") {
|
||||||
const r = Math.max(1e-3, Math.hypot(pt.x - g.center.x, pt.y - g.center.y));
|
const dx = pt.x - g.center.x, dy = pt.y - g.center.y;
|
||||||
return { ...d, geom: { ...g, r } };
|
const rx = index === 0 ? Math.max(1e-3, Math.abs(dx)) : g.r;
|
||||||
|
const ry = index === 0 ? g.r : Math.max(1e-3, Math.abs(dy));
|
||||||
|
return { ...d, geom: ellipseOrCircle(g.center, rx, ry) };
|
||||||
}
|
}
|
||||||
// Bogen: Griff 0/1 (Start-/End-Winkel, s. drawingVertices) ändert a0/a1;
|
// Bogen: Griff 0/1 (Start-/End-Winkel, s. drawingVertices) ändert a0/a1;
|
||||||
// Griff 2 (Bogenmitte) ändert nur den Radius (Winkel bleiben fest).
|
// Griff 2 (Bogenmitte) ändert nur den Radius (Winkel bleiben fest).
|
||||||
@@ -1592,8 +1622,13 @@ function moveGrip(
|
|||||||
const dx = pt.x - g.center.x, dy = pt.y - g.center.y;
|
const dx = pt.x - g.center.x, dy = pt.y - g.center.y;
|
||||||
const lx = dx * c + dy * s;
|
const lx = dx * c + dy * s;
|
||||||
const ly = -dx * s + dy * c;
|
const ly = -dx * s + dy * c;
|
||||||
if (index === 0) return { ...d, geom: { ...g, rx: Math.max(1e-3, Math.abs(lx)) } };
|
const rx = index === 0 ? Math.max(1e-3, Math.abs(lx)) : g.rx;
|
||||||
return { ...d, geom: { ...g, ry: Math.max(1e-3, Math.abs(ly)) } };
|
const ry = index === 0 ? g.ry : Math.max(1e-3, Math.abs(ly));
|
||||||
|
// Nur bei rotation 0 kann eine (fast) gleichseitige Ellipse wieder
|
||||||
|
// zum Kreis kollabieren — eine gedrehte Ellipse mit rx≈ry ist optisch
|
||||||
|
// bereits ein Kreis, „Drehung" wäre dann aber wieder bedeutungslos.
|
||||||
|
if (g.rotation === 0) return { ...d, geom: ellipseOrCircle(g.center, rx, ry) };
|
||||||
|
return { ...d, geom: { ...g, rx, ry } };
|
||||||
}
|
}
|
||||||
return d;
|
return d;
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -202,6 +202,26 @@ export function useGripEditing(opts: {
|
|||||||
return out;
|
return out;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
// Bezier-Hilfslinien (Anker → Kontrollpunkt-Griff), gestrichelt gerendert,
|
||||||
|
// damit sichtbar/nachvollziehbar ist, welcher Griff welchen Kurvenabschnitt
|
||||||
|
// steuert (Nutzer-Wunsch: „Hilfslinien sollten schon sichtbar sein um sie
|
||||||
|
// zu steuern" — wie bei Illustrator/Inkscape üblich). `pts` folgt dem Muster
|
||||||
|
// Anker·Griff·Griff·Anker·… (s. `Drawing2DGeom["bezier"]`); jeder Anker
|
||||||
|
// bekommt eine Linie zu seinem/seinen benachbarten Griff(en).
|
||||||
|
const gripHandleLines: { a: Vec2; b: Vec2 }[] = (() => {
|
||||||
|
const out: { a: Vec2; b: Vec2 }[] = [];
|
||||||
|
for (const id of effectiveDrawingIds) {
|
||||||
|
const d = project.drawings2d.find((x) => x.id === id);
|
||||||
|
const g = d?.geom;
|
||||||
|
if (!g || g.shape !== "bezier") continue;
|
||||||
|
for (let i = 0; i + 3 < g.pts.length; i += 3) {
|
||||||
|
out.push({ a: g.pts[i], b: g.pts[i + 1] }); // Anker → Griff 1
|
||||||
|
out.push({ a: g.pts[i + 3], b: g.pts[i + 2] }); // nächster Anker → Griff 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
})();
|
||||||
|
|
||||||
// Nachbar-Griff-Index INNERHALB desselben Elements (für Anker-Auflösung).
|
// Nachbar-Griff-Index INNERHALB desselben Elements (für Anker-Auflösung).
|
||||||
// null = kein Nachbar möglich (Einzelgriff-Element wie Kreis/Öffnung/Treppe).
|
// null = kein Nachbar möglich (Einzelgriff-Element wie Kreis/Öffnung/Treppe).
|
||||||
const neighborGripIndex = (index: number): number | null => {
|
const neighborGripIndex = (index: number): number | null => {
|
||||||
@@ -1048,6 +1068,7 @@ export function useGripEditing(opts: {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
grips,
|
grips,
|
||||||
|
gripHandleLines,
|
||||||
edgeGrips,
|
edgeGrips,
|
||||||
gripHandlers,
|
gripHandlers,
|
||||||
gripEdit,
|
gripEdit,
|
||||||
|
|||||||
@@ -2143,6 +2143,16 @@ body {
|
|||||||
vector-effect: non-scaling-stroke;
|
vector-effect: non-scaling-stroke;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Bezier-Hilfslinien (Anker → Kontrollpunkt-Griff): dünn, gestrichelt, deutlich
|
||||||
|
zurückhaltender als der Kurven-Umriss selbst — reine Steuerungshilfe. */
|
||||||
|
.plan-svg .plan-grip-line {
|
||||||
|
stroke: var(--accent-light);
|
||||||
|
stroke-width: 1;
|
||||||
|
stroke-dasharray: 3 3;
|
||||||
|
vector-effect: non-scaling-stroke;
|
||||||
|
fill: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* Kanten-/Seiten-Griffe (Edge Grips): dreieckiger Anfasser je Seite, Spitze
|
/* Kanten-/Seiten-Griffe (Edge Grips): dreieckiger Anfasser je Seite, Spitze
|
||||||
nach außen. Gleiche Akzent-/Rand-Farben wie die Eckpunkt-Griffe. */
|
nach außen. Gleiche Akzent-/Rand-Farben wie die Eckpunkt-Griffe. */
|
||||||
.plan-svg .plan-edge-grip {
|
.plan-svg .plan-edge-grip {
|
||||||
|
|||||||
@@ -117,6 +117,7 @@ export function Content({
|
|||||||
toolHandlers,
|
toolHandlers,
|
||||||
hudFields,
|
hudFields,
|
||||||
grips,
|
grips,
|
||||||
|
gripHandleLines,
|
||||||
edgeGrips,
|
edgeGrips,
|
||||||
selectedDrawingId,
|
selectedDrawingId,
|
||||||
selectedDrawingIds,
|
selectedDrawingIds,
|
||||||
@@ -218,6 +219,7 @@ export function Content({
|
|||||||
toolHandlers: ToolHandlers;
|
toolHandlers: ToolHandlers;
|
||||||
hudFields: HudFieldsState | null;
|
hudFields: HudFieldsState | null;
|
||||||
grips: Vec2[];
|
grips: Vec2[];
|
||||||
|
gripHandleLines: { a: Vec2; b: Vec2 }[];
|
||||||
edgeGrips: EdgeGrip[];
|
edgeGrips: EdgeGrip[];
|
||||||
selectedDrawingId: string | null;
|
selectedDrawingId: string | null;
|
||||||
selectedDrawingIds?: string[];
|
selectedDrawingIds?: string[];
|
||||||
@@ -328,6 +330,7 @@ export function Content({
|
|||||||
toolHandlers={toolHandlers}
|
toolHandlers={toolHandlers}
|
||||||
hudFields={hudFields}
|
hudFields={hudFields}
|
||||||
grips={grips}
|
grips={grips}
|
||||||
|
gripHandleLines={gripHandleLines}
|
||||||
edgeGrips={edgeGrips}
|
edgeGrips={edgeGrips}
|
||||||
selectedDrawingId={selectedDrawingId}
|
selectedDrawingId={selectedDrawingId}
|
||||||
selectedDrawingIds={selectedDrawingIds}
|
selectedDrawingIds={selectedDrawingIds}
|
||||||
@@ -393,6 +396,7 @@ export function Content({
|
|||||||
toolHandlers={toolHandlers}
|
toolHandlers={toolHandlers}
|
||||||
hudFields={hudFields}
|
hudFields={hudFields}
|
||||||
grips={grips}
|
grips={grips}
|
||||||
|
gripHandleLines={gripHandleLines}
|
||||||
edgeGrips={edgeGrips}
|
edgeGrips={edgeGrips}
|
||||||
selectedDrawingId={selectedDrawingId}
|
selectedDrawingId={selectedDrawingId}
|
||||||
selectedDrawingIds={selectedDrawingIds}
|
selectedDrawingIds={selectedDrawingIds}
|
||||||
@@ -500,6 +504,7 @@ export function Content({
|
|||||||
toolHandlers={toolHandlers}
|
toolHandlers={toolHandlers}
|
||||||
hudFields={hudFields}
|
hudFields={hudFields}
|
||||||
grips={grips}
|
grips={grips}
|
||||||
|
gripHandleLines={gripHandleLines}
|
||||||
edgeGrips={edgeGrips}
|
edgeGrips={edgeGrips}
|
||||||
selectedDrawingId={selectedDrawingId}
|
selectedDrawingId={selectedDrawingId}
|
||||||
selectedDrawingIds={selectedDrawingIds}
|
selectedDrawingIds={selectedDrawingIds}
|
||||||
@@ -555,6 +560,7 @@ function LevelPlanView({
|
|||||||
toolHandlers,
|
toolHandlers,
|
||||||
hudFields,
|
hudFields,
|
||||||
grips,
|
grips,
|
||||||
|
gripHandleLines,
|
||||||
edgeGrips,
|
edgeGrips,
|
||||||
selectedDrawingId,
|
selectedDrawingId,
|
||||||
selectedDrawingIds,
|
selectedDrawingIds,
|
||||||
@@ -607,6 +613,7 @@ function LevelPlanView({
|
|||||||
toolHandlers: ToolHandlers;
|
toolHandlers: ToolHandlers;
|
||||||
hudFields: HudFieldsState | null;
|
hudFields: HudFieldsState | null;
|
||||||
grips: Vec2[];
|
grips: Vec2[];
|
||||||
|
gripHandleLines: { a: Vec2; b: Vec2 }[];
|
||||||
edgeGrips: EdgeGrip[];
|
edgeGrips: EdgeGrip[];
|
||||||
selectedDrawingId: string | null;
|
selectedDrawingId: string | null;
|
||||||
selectedDrawingIds?: string[];
|
selectedDrawingIds?: string[];
|
||||||
@@ -688,6 +695,7 @@ function LevelPlanView({
|
|||||||
toolHandlers={toolHandlers}
|
toolHandlers={toolHandlers}
|
||||||
hudFields={hudFields}
|
hudFields={hudFields}
|
||||||
grips={grips}
|
grips={grips}
|
||||||
|
gripHandleLines={gripHandleLines}
|
||||||
edgeGrips={edgeGrips}
|
edgeGrips={edgeGrips}
|
||||||
hairline={hairline}
|
hairline={hairline}
|
||||||
marqueeColor={marqueeColor}
|
marqueeColor={marqueeColor}
|
||||||
@@ -752,6 +760,7 @@ function SectionPlanView({
|
|||||||
toolHandlers,
|
toolHandlers,
|
||||||
hudFields,
|
hudFields,
|
||||||
grips,
|
grips,
|
||||||
|
gripHandleLines,
|
||||||
edgeGrips,
|
edgeGrips,
|
||||||
selectedDrawingId,
|
selectedDrawingId,
|
||||||
selectedDrawingIds,
|
selectedDrawingIds,
|
||||||
@@ -795,6 +804,7 @@ function SectionPlanView({
|
|||||||
toolHandlers: ToolHandlers;
|
toolHandlers: ToolHandlers;
|
||||||
hudFields: HudFieldsState | null;
|
hudFields: HudFieldsState | null;
|
||||||
grips: Vec2[];
|
grips: Vec2[];
|
||||||
|
gripHandleLines: { a: Vec2; b: Vec2 }[];
|
||||||
edgeGrips: EdgeGrip[];
|
edgeGrips: EdgeGrip[];
|
||||||
selectedDrawingId: string | null;
|
selectedDrawingId: string | null;
|
||||||
selectedDrawingIds?: string[];
|
selectedDrawingIds?: string[];
|
||||||
@@ -906,6 +916,7 @@ function SectionPlanView({
|
|||||||
toolHandlers={toolHandlers}
|
toolHandlers={toolHandlers}
|
||||||
hudFields={hudFields}
|
hudFields={hudFields}
|
||||||
grips={grips}
|
grips={grips}
|
||||||
|
gripHandleLines={gripHandleLines}
|
||||||
edgeGrips={edgeGrips}
|
edgeGrips={edgeGrips}
|
||||||
hairline={hairline}
|
hairline={hairline}
|
||||||
marqueeColor={marqueeColor}
|
marqueeColor={marqueeColor}
|
||||||
|
|||||||
Reference in New Issue
Block a user