@osamash/floor-planner 1.2.2 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/floor-planner.css +1 -1
- package/dist/floor-planner.es.js +43937 -37765
- package/dist/floor-planner.umd.js +59 -49
- package/dist/types/index.d.ts +3 -1
- package/dist/types/react-planner/ReactPlanner.d.ts +3 -1
- package/dist/types/react-planner/ai-chat/AIChatBubble.d.ts +6 -0
- package/dist/types/react-planner/ai-chat/AIChatPanel.d.ts +8 -0
- package/dist/types/react-planner/ai-chat/SelectionChips.d.ts +2 -0
- package/dist/types/react-planner/ai-chat/ThinkingIndicator.d.ts +5 -0
- package/dist/types/react-planner/ai-chat/aiService.d.ts +327 -0
- package/dist/types/react-planner/ai-chat/imageUpload.d.ts +6 -0
- package/dist/types/react-planner/ai-chat/plannerActions.d.ts +3 -0
- package/dist/types/react-planner/ai-chat/streamingClient.d.ts +32 -0
- package/dist/types/react-planner/ai-chat/useTypewriter.d.ts +19 -0
- package/dist/types/react-planner/catalog/catalog.d.ts +4 -0
- package/dist/types/react-planner/catalog/factories/AreaFactory.d.ts +1 -24
- package/dist/types/react-planner/catalog/factories/WallFactory.d.ts +1 -26
- package/dist/types/react-planner/catalog/factories/area-factory-3d.d.ts +2 -2
- package/dist/types/react-planner/catalog/factories/area-patterns.d.ts +42 -0
- package/dist/types/react-planner/catalog/factories/room-types.d.ts +22 -0
- package/dist/types/react-planner/catalog/factories/wall-factory-3d.d.ts +1 -1
- package/dist/types/react-planner/class/area.d.ts +23 -0
- package/dist/types/react-planner/class/hole.d.ts +13 -0
- package/dist/types/react-planner/class/index.d.ts +3 -1
- package/dist/types/react-planner/class/item.d.ts +22 -0
- package/dist/types/react-planner/class/line.d.ts +12 -3
- package/dist/types/react-planner/class/room.d.ts +18 -0
- package/dist/types/react-planner/components/ErrorBoundary.d.ts +19 -0
- package/dist/types/react-planner/components/SearchInput.d.ts +2 -1
- package/dist/types/react-planner/constants.d.ts +3 -0
- package/dist/types/react-planner/footer-bar/Footerbar.d.ts +1 -1
- package/dist/types/react-planner/models.d.ts +7 -0
- package/dist/types/react-planner/plugins/autosave.d.ts +1 -1
- package/dist/types/react-planner/plugins/keyboard.d.ts +1 -1
- package/dist/types/react-planner/sidebar/Panel.d.ts +2 -1
- package/dist/types/react-planner/sidebar/panel-element-editor/AreaAttributesEditor.d.ts +8 -0
- package/dist/types/react-planner/sidebar/panel-element-editor/AttributesEditor.d.ts +4 -1
- package/dist/types/react-planner/sidebar/panel-element-editor/HoleAttributesEditor.d.ts +3 -4
- package/dist/types/react-planner/sidebar/panel-element-editor/ItemAttributesEditor.d.ts +3 -4
- package/dist/types/react-planner/sidebar/panel-element-editor/SimilarElements.d.ts +15 -0
- package/dist/types/react-planner/sidebar/panel-element-editor/WallAttributesEditor.d.ts +8 -0
- package/dist/types/react-planner/sidebar/panel-element-editor/editor-ui.d.ts +42 -0
- package/dist/types/react-planner/toolbar/CatalogPicker.d.ts +8 -0
- package/dist/types/react-planner/toolbar/NumberStepper.d.ts +11 -0
- package/dist/types/react-planner/toolbar/ProjectMiniMap.d.ts +11 -0
- package/dist/types/react-planner/toolbar/ProjectPanel.d.ts +2 -0
- package/dist/types/react-planner/toolbar/ToolbarRail.d.ts +15 -0
- package/dist/types/react-planner/toolbar/ToolbarSubPanel.d.ts +23 -0
- package/dist/types/react-planner/toolbar/ZoomControls.d.ts +5 -0
- package/dist/types/react-planner/utils/angle.d.ts +9 -0
- package/dist/types/react-planner/utils/geometry.d.ts +15 -0
- package/dist/types/react-planner/utils/image-trim.d.ts +25 -0
- package/dist/types/react-planner/utils/item-footprint.d.ts +23 -0
- package/dist/types/react-planner/utils/item-snap.d.ts +56 -0
- package/dist/types/react-planner/utils/item-transform.d.ts +9 -0
- package/dist/types/react-planner/utils/name-generator.d.ts +1 -1
- package/dist/types/react-planner/utils/three-cache.d.ts +17 -0
- package/dist/types/react-planner/utils/three-materials.d.ts +33 -0
- package/dist/types/react-planner/utils/threeCSG.es6.d.ts +1 -1
- package/dist/types/react-planner/utils/wall-miter.d.ts +53 -0
- package/dist/types/react-planner/utils/zoom.d.ts +2 -2
- package/dist/types/react-planner/viewer2d/Grids.d.ts +1 -1
- package/dist/types/react-planner/viewer2d/Ruler.d.ts +6 -1
- package/dist/types/react-planner/viewer2d/SelectionToolbar.d.ts +12 -0
- package/dist/types/react-planner/viewer2d/WallHoverHandles.d.ts +13 -0
- package/dist/types/react-planner/viewer3d/selection-gizmo.d.ts +57 -0
- package/dist/types/react-planner/viewer3d/viewer3d.d.ts +61 -0
- package/dist/types/shared-style.d.ts +6 -0
- package/dist/types/store/ReactPlannerStore.d.ts +102 -1
- package/package.json +1 -1
- package/dist/types/react-planner/components/PropertyString.d.ts +0 -10
- package/dist/types/react-planner/toolbar/Popup.d.ts +0 -11
- package/dist/types/react-planner/viewer2d/GridHorizontalStreak.d.ts +0 -7
- package/dist/types/react-planner/viewer2d/GridVerticalStreak.d.ts +0 -7
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export declare const MITER_LIMIT = 4;
|
|
2
|
+
export interface MiterShifts {
|
|
3
|
+
/** Shift along the wall axis for the +y (local top) side. Positive cuts the
|
|
4
|
+
* corner back into the wall, negative extends it past the vertex. */
|
|
5
|
+
topShift: number;
|
|
6
|
+
/** Same, for the −y (local bottom) side. */
|
|
7
|
+
botShift: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Compute miter shifts at one end of a wall.
|
|
11
|
+
*
|
|
12
|
+
* - axisDirAway: unit vector from `vertex` toward the wall's OTHER end.
|
|
13
|
+
* - perpTop: the wall's local +y direction in world coords (fixed for both
|
|
14
|
+
* ends of the wall — 90° CCW from the wall's start→end direction).
|
|
15
|
+
*
|
|
16
|
+
* Independent shifts on the two perpendicular sides let the wall's end become
|
|
17
|
+
* a diagonal miter cut instead of a straight rectangle end.
|
|
18
|
+
*/
|
|
19
|
+
export declare function miterShifts(currentLineID: string, vertex: any, axisDirAway: {
|
|
20
|
+
x: number;
|
|
21
|
+
y: number;
|
|
22
|
+
}, perpTop: {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
}, layer: any, halfThickness: number, miterLimit?: number): MiterShifts;
|
|
26
|
+
export interface WallGeometry {
|
|
27
|
+
/** Endpoint the local frame starts from (the smaller-x one). */
|
|
28
|
+
vStart: any;
|
|
29
|
+
vEnd: any;
|
|
30
|
+
/** Centerline length, vertex to vertex. */
|
|
31
|
+
length: number;
|
|
32
|
+
thickness: number;
|
|
33
|
+
halfThickness: number;
|
|
34
|
+
/** Local-frame x of the four corners. The wall is the quadrilateral
|
|
35
|
+
* (topStart, +h) (topEnd, +h) (botEnd, −h) (botStart, −h). */
|
|
36
|
+
topStart: number;
|
|
37
|
+
topEnd: number;
|
|
38
|
+
botStart: number;
|
|
39
|
+
botEnd: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The wall as it is actually drawn: a quadrilateral whose ends are diagonal
|
|
43
|
+
* miter cuts. Everything is in the wall's local frame — x runs along the wall
|
|
44
|
+
* from the smaller-x endpoint, y is perpendicular with +y = 90° CCW from the
|
|
45
|
+
* wall direction. `viewer2d/Line` establishes exactly this frame, which is why
|
|
46
|
+
* the start/end ordering below has to match it.
|
|
47
|
+
*
|
|
48
|
+
* The two face lengths a floor plan quotes as "inside" and "outside" are
|
|
49
|
+
* `topEnd - topStart` and `botEnd - botStart`: a corner cuts one face back by
|
|
50
|
+
* the miter length and extends the other past the vertex by the same amount,
|
|
51
|
+
* so they straddle the centerline length.
|
|
52
|
+
*/
|
|
53
|
+
export declare function wallGeometry(element: any, layer: any): WallGeometry | null;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export declare const MIN_ZOOM = 0.
|
|
1
|
+
export declare const MIN_ZOOM = 0.25;
|
|
2
2
|
export declare const MAX_ZOOM = 5;
|
|
3
|
-
export declare const SVG_MIN_ZOOM = 0.
|
|
3
|
+
export declare const SVG_MIN_ZOOM = 0.25;
|
|
4
4
|
export declare const SVG_MAX_ZOOM = 5;
|
|
5
5
|
export declare function zoomToPercentage(zoom: number): number;
|
|
@@ -3,7 +3,12 @@ interface RulerProps {
|
|
|
3
3
|
length: number;
|
|
4
4
|
unit: string;
|
|
5
5
|
transform: string;
|
|
6
|
+
/** Which side of the rule the measurement sits on. "below" is for a ruler
|
|
7
|
+
* drawn under the thing it measures, so the label falls away from it
|
|
8
|
+
* instead of landing on top of it. */
|
|
9
|
+
labelPlacement?: "above" | "below";
|
|
6
10
|
}
|
|
7
|
-
declare
|
|
11
|
+
export declare const formatDistance: (length: number, unit: string) => string;
|
|
12
|
+
declare function Ruler({ length, unit, transform, labelPlacement, }: RulerProps): import("react/jsx-runtime").JSX.Element;
|
|
8
13
|
declare const _default: React.MemoExoticComponent<typeof Ruler>;
|
|
9
14
|
export default _default;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface SelectionToolbarProps {
|
|
3
|
+
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Floating action bar for the current selection. It is plain HTML positioned
|
|
7
|
+
* over the SVG — the element's rendered bounding box is read straight from the
|
|
8
|
+
* DOM, which keeps it correct for any catalog element whatever the zoom, pan
|
|
9
|
+
* or rotation.
|
|
10
|
+
*/
|
|
11
|
+
declare const SelectionToolbar: ({ containerRef }: SelectionToolbarProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
12
|
+
export default SelectionToolbar;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface WallHoverHandlesProps {
|
|
2
|
+
layer: any;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Endpoint handles for the wall currently under the pointer — drag one to
|
|
6
|
+
* lengthen or shorten the wall, no selection needed.
|
|
7
|
+
*
|
|
8
|
+
* They render as the layer's last child rather than inside the wall's own
|
|
9
|
+
* group: SVG has no z-index, only document order, so anything drawn from
|
|
10
|
+
* inside the wall would be painted over by walls and items that come later.
|
|
11
|
+
*/
|
|
12
|
+
export default function WallHoverHandles({ layer }: WallHoverHandlesProps): import("react/jsx-runtime").JSX.Element | null;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import * as THREE from "three";
|
|
2
|
+
export type GizmoHandle = "rotate" | "lift";
|
|
3
|
+
export interface GizmoTarget {
|
|
4
|
+
/** Centre of the item's footprint, in world space. */
|
|
5
|
+
centre: THREE.Vector3;
|
|
6
|
+
/** Floor the item stands on, in world space. */
|
|
7
|
+
floorY: number;
|
|
8
|
+
/** Where the lift handle sits — around the middle of the item. */
|
|
9
|
+
handleY: number;
|
|
10
|
+
/** Half the footprint's diagonal. */
|
|
11
|
+
radius: number;
|
|
12
|
+
/** The item's heading, so the ring's arrow reads as its front. */
|
|
13
|
+
rotationY: number;
|
|
14
|
+
/** Underside of the item, for deciding whether it is off the floor at all. */
|
|
15
|
+
bottomY: number;
|
|
16
|
+
/** Whether the lift handle is being dragged right now. */
|
|
17
|
+
lifting: boolean;
|
|
18
|
+
}
|
|
19
|
+
export default class SelectionGizmo {
|
|
20
|
+
readonly group: THREE.Group<THREE.Object3DEventMap>;
|
|
21
|
+
/** Turns with the item: the ring and the arrow marking its front. */
|
|
22
|
+
private readonly base;
|
|
23
|
+
private readonly ring;
|
|
24
|
+
private readonly rotateGrab;
|
|
25
|
+
private readonly rotateArrow;
|
|
26
|
+
/** Always faces the camera, always the same size on screen. */
|
|
27
|
+
private readonly lift;
|
|
28
|
+
private readonly liftGrab;
|
|
29
|
+
/** Dashed line from the handle down to the floor, when the item is lifted. */
|
|
30
|
+
private readonly plumb;
|
|
31
|
+
private readonly plumbTexture;
|
|
32
|
+
private readonly materials;
|
|
33
|
+
private readonly geometries;
|
|
34
|
+
private readonly textures;
|
|
35
|
+
constructor();
|
|
36
|
+
private keep;
|
|
37
|
+
private keepTexture;
|
|
38
|
+
/**
|
|
39
|
+
* Place the gizmo around `target`, or hide it when there is nothing
|
|
40
|
+
* selected. `worldPerPixel` converts a screen size at a given distance into
|
|
41
|
+
* world units, which is what keeps the lift handle the same size however far
|
|
42
|
+
* away the camera is.
|
|
43
|
+
*/
|
|
44
|
+
update(target: GizmoTarget | null, camera: THREE.Camera, worldPerPixel: (distance: number) => number): void;
|
|
45
|
+
/**
|
|
46
|
+
* The line that says how far off the floor the item is. Drawn from the
|
|
47
|
+
* handle straight down to where the ring is, for the length of the lift
|
|
48
|
+
* drag only — it answers "how high am I putting this", which is a question
|
|
49
|
+
* that stops being asked the moment the handle is let go. It also needs a
|
|
50
|
+
* gap to describe: an item still sitting on the floor doesn't get one.
|
|
51
|
+
*/
|
|
52
|
+
private updatePlumb;
|
|
53
|
+
/** Which handle, if any, a ray hits. The lift handle wins ties: it sits on
|
|
54
|
+
* top of the ring and is the smaller target. */
|
|
55
|
+
pick(raycaster: THREE.Raycaster): GizmoHandle | null;
|
|
56
|
+
dispose(): void;
|
|
57
|
+
}
|
|
@@ -9,6 +9,7 @@ interface Viewer3DProps {
|
|
|
9
9
|
[key: string]: any;
|
|
10
10
|
};
|
|
11
11
|
catalog: Catalog;
|
|
12
|
+
showGrid: boolean;
|
|
12
13
|
}
|
|
13
14
|
export default class Scene3DViewer extends React.Component<Viewer3DProps> {
|
|
14
15
|
private canvasWrapperRef;
|
|
@@ -23,8 +24,68 @@ export default class Scene3DViewer extends React.Component<Viewer3DProps> {
|
|
|
23
24
|
private lastMousePosition;
|
|
24
25
|
private mouseDownEvent;
|
|
25
26
|
private mouseUpEvent;
|
|
27
|
+
private lastBoundingBox;
|
|
28
|
+
private userMovedCamera;
|
|
29
|
+
private sun;
|
|
30
|
+
private shadowsDirtyUntil;
|
|
31
|
+
private gizmo;
|
|
32
|
+
private gizmoDrag;
|
|
33
|
+
private gizmoMoveEvent;
|
|
34
|
+
private gizmoUpEvent;
|
|
35
|
+
private readonly scratchBox;
|
|
36
|
+
private readonly scratchVector;
|
|
37
|
+
private readonly scratchSize;
|
|
38
|
+
private gizmoRadiusFor;
|
|
39
|
+
private gizmoRadius;
|
|
26
40
|
constructor(props: Viewer3DProps);
|
|
27
41
|
componentDidMount(): void;
|
|
42
|
+
/** World units one screen pixel covers at `distance` from the camera. */
|
|
43
|
+
private worldPerPixel;
|
|
44
|
+
/** The item the gizmo should be wrapped around, if there is one. */
|
|
45
|
+
private selectedItemTarget;
|
|
46
|
+
private beginGizmoDrag;
|
|
47
|
+
/**
|
|
48
|
+
* Move the item itself rather than the store: a drag is one gesture and
|
|
49
|
+
* should be one entry in the history, and an altitude change rebuilds the
|
|
50
|
+
* item's whole model — neither is something to do per mouse move. The store
|
|
51
|
+
* hears about it once, when the drag ends.
|
|
52
|
+
*/
|
|
53
|
+
private updateGizmoDrag;
|
|
54
|
+
private endGizmoDrag;
|
|
55
|
+
/**
|
|
56
|
+
* Aim the sun at the plan and size its shadow frustum to cover it.
|
|
57
|
+
*
|
|
58
|
+
* A directional light shadows through an orthographic camera, and anything
|
|
59
|
+
* outside that box simply casts nothing — so the box has to follow the plan
|
|
60
|
+
* as it grows. Sizing it to the sphere around the bounding box means the
|
|
61
|
+
* coverage holds from any angle.
|
|
62
|
+
*/
|
|
63
|
+
private positionSun;
|
|
64
|
+
/**
|
|
65
|
+
* Re-render the shadow map.
|
|
66
|
+
*
|
|
67
|
+
* Not just on the next frame: meshes and their textures arrive over the
|
|
68
|
+
* following moments, so keep it refreshing for a beat rather than baking
|
|
69
|
+
* shadows for a scene that is still half loaded.
|
|
70
|
+
*/
|
|
71
|
+
private invalidateShadows;
|
|
72
|
+
/**
|
|
73
|
+
* Dolly toward (factor > 1) or away from (factor < 1) the orbit target.
|
|
74
|
+
* OrbitControls' own min/maxDistance still bound the result, so the buttons
|
|
75
|
+
* can't push the camera anywhere the scroll wheel couldn't.
|
|
76
|
+
*/
|
|
77
|
+
zoomBy(factor: number): void;
|
|
78
|
+
/**
|
|
79
|
+
* Frame the whole plan: keep looking from the current direction, but re-aim
|
|
80
|
+
* at the plan's center and back off far enough for it to fit.
|
|
81
|
+
*/
|
|
82
|
+
fitToScene(): void;
|
|
83
|
+
/**
|
|
84
|
+
* Re-aim at the plan's center and back off far enough to fit it in frame.
|
|
85
|
+
* `direction` is where the camera sits relative to that center; omitted, it
|
|
86
|
+
* keeps looking from wherever it already is.
|
|
87
|
+
*/
|
|
88
|
+
private frameScene;
|
|
28
89
|
componentWillUnmount(): void;
|
|
29
90
|
componentDidUpdate(prevProps: Viewer3DProps): void;
|
|
30
91
|
render(): React.DetailedReactHTMLElement<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>;
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export declare const COLORS: {
|
|
2
2
|
white: string;
|
|
3
3
|
black: string;
|
|
4
|
+
wall: string;
|
|
5
|
+
threeBG: string;
|
|
6
|
+
canvasBG: string;
|
|
4
7
|
};
|
|
5
8
|
export declare const MATERIAL_COLORS: {
|
|
6
9
|
500: {
|
|
@@ -53,6 +56,9 @@ declare const SharedStyle: {
|
|
|
53
56
|
COLORS: {
|
|
54
57
|
white: string;
|
|
55
58
|
black: string;
|
|
59
|
+
wall: string;
|
|
60
|
+
threeBG: string;
|
|
61
|
+
canvasBG: string;
|
|
56
62
|
};
|
|
57
63
|
MATERIAL_COLORS: {
|
|
58
64
|
500: {
|
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
import { State } from "../react-planner/models";
|
|
2
2
|
import { ReactSVGPanZoom } from "react-svg-pan-zoom";
|
|
3
|
+
export type PlannerSelectionKind = "item" | "hole" | "surface" | "wall";
|
|
4
|
+
export interface PlannerSelection {
|
|
5
|
+
layerID: string;
|
|
6
|
+
kind: PlannerSelectionKind;
|
|
7
|
+
id: string;
|
|
8
|
+
}
|
|
9
|
+
/** The camera moves the toolbar can ask the 3D viewer to make. Structural on
|
|
10
|
+
* purpose — the store stays free of three.js. */
|
|
11
|
+
export interface Viewer3DHandle {
|
|
12
|
+
/** > 1 moves the camera closer to what it is orbiting, < 1 pulls it back. */
|
|
13
|
+
zoomBy: (factor: number) => void;
|
|
14
|
+
fitToScene: () => void;
|
|
15
|
+
}
|
|
16
|
+
/** What the pointer is currently over in the 2D viewer while idle. */
|
|
17
|
+
export interface HoveredElement {
|
|
18
|
+
layerID: string;
|
|
19
|
+
/** "lines" | "vertices" | "items" | "holes" */
|
|
20
|
+
prototype: string;
|
|
21
|
+
id: string;
|
|
22
|
+
/** Sub-part of the element (rotation-anchor, resize-anchor…). */
|
|
23
|
+
part?: string;
|
|
24
|
+
/** The wall this node belongs to. Set both for the wall itself and for the
|
|
25
|
+
* endpoint handles it draws, so the wall keeps its highlight while the
|
|
26
|
+
* pointer sits on one of its handles. */
|
|
27
|
+
lineID?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare const getSelectedElement: (planner: any) => PlannerSelection | null;
|
|
3
30
|
interface Floor {
|
|
4
31
|
floorID: number;
|
|
5
32
|
floorTitle: string;
|
|
@@ -26,12 +53,55 @@ export interface ReactPlannerStore {
|
|
|
26
53
|
remove: () => void;
|
|
27
54
|
showDimensions: boolean;
|
|
28
55
|
setShowDimensions: (showDimensions: boolean) => void;
|
|
56
|
+
showGrid: boolean;
|
|
57
|
+
setShowGrid: (showGrid: boolean) => void;
|
|
58
|
+
theme: "light" | "dark";
|
|
59
|
+
setTheme: (theme: "light" | "dark") => void;
|
|
60
|
+
/** Returns the new wall's line ID (or undefined if nothing got created). */
|
|
61
|
+
addWallByCoords: (x0: number, y0: number, x1: number, y1: number) => string | undefined;
|
|
62
|
+
addSurfaceByPoints: (points: {
|
|
63
|
+
x: number;
|
|
64
|
+
y: number;
|
|
65
|
+
}[], surfaceType?: string) => void;
|
|
66
|
+
addRoom: (x0: number, y0: number, x1: number, y1: number, options?: {
|
|
67
|
+
thickness?: number;
|
|
68
|
+
height?: number;
|
|
69
|
+
}) => void;
|
|
70
|
+
selectToolDrawingRoom: (options?: {
|
|
71
|
+
thickness?: number;
|
|
72
|
+
height?: number;
|
|
73
|
+
}) => void;
|
|
74
|
+
updateRoomDrawingProperties: (options: {
|
|
75
|
+
thickness?: number;
|
|
76
|
+
height?: number;
|
|
77
|
+
}) => void;
|
|
78
|
+
beginDrawingRoom: (layerID: string, x: number, y: number) => void;
|
|
79
|
+
updateDrawingRoom: (x: number, y: number) => void;
|
|
80
|
+
endDrawingRoom: (x: number, y: number) => void;
|
|
81
|
+
/** Returns the new item's ID (or undefined if nothing got created). */
|
|
82
|
+
addItemByCoords: (itemType: string, x: number, y: number, width?: number, height?: number, rotation?: number) => string | undefined;
|
|
83
|
+
/** Returns the new hole's ID (or undefined if nothing got created). */
|
|
84
|
+
addHoleOnLine: (lineID: string, holeType: string, offset: number) => string | undefined;
|
|
85
|
+
setAreaProperties: (areaID: string, properties: any) => void;
|
|
86
|
+
setLineProperties: (lineID: string, properties: any) => void;
|
|
87
|
+
moveVertex: (vertexID: string, x: number, y: number) => void;
|
|
88
|
+
removeLine: (lineID: string) => void;
|
|
89
|
+
removeArea: (areaID: string) => void;
|
|
90
|
+
removeItem: (itemID: string) => void;
|
|
91
|
+
removeHole: (holeID: string) => void;
|
|
92
|
+
fitViewerToScene: (options?: {
|
|
93
|
+
animate?: boolean;
|
|
94
|
+
}) => void;
|
|
95
|
+
focusOnArea: (layerID: string, areaID: string) => void;
|
|
29
96
|
setToast: (toast: {
|
|
30
97
|
text: string;
|
|
31
98
|
} | null) => void;
|
|
32
99
|
setPlan: (plan: Plan) => void;
|
|
33
100
|
setAlterateState: () => void;
|
|
34
|
-
selectToolDrawingLine: (sceneComponentType: any
|
|
101
|
+
selectToolDrawingLine: (sceneComponentType: any, options?: {
|
|
102
|
+
thickness?: number;
|
|
103
|
+
height?: number;
|
|
104
|
+
}) => void;
|
|
35
105
|
selectToolDrawingSurface: (sceneComponentType: any) => void;
|
|
36
106
|
selectToolDrawingItem: (sceneComponentType: any) => void;
|
|
37
107
|
selectToolDrawingHole: (sceneComponentType: any) => void;
|
|
@@ -43,6 +113,33 @@ export interface ReactPlannerStore {
|
|
|
43
113
|
unselectAll: () => void;
|
|
44
114
|
beginDraggingVertex: (layerID: string, vertexID: string, x: number, y: number, snapMask: any) => void;
|
|
45
115
|
endDraggingVertex: (x: number, y: number, snapMask: any) => void;
|
|
116
|
+
duplicateSelected: () => void;
|
|
117
|
+
duplicateItem: (itemID: string) => void;
|
|
118
|
+
duplicateHole: (holeID: string) => void;
|
|
119
|
+
duplicateSurface: (areaID: string) => void;
|
|
120
|
+
/** Positive turns counter-clockwise as seen in the 2D view. */
|
|
121
|
+
rotateSelected: (degrees: number) => void;
|
|
122
|
+
flipSelected: (axis: "x" | "y") => void;
|
|
123
|
+
/** Rotate one surface polygon about its own center, addressed by ID rather
|
|
124
|
+
* than via the selection. Same sign convention as `rotateSelected`. */
|
|
125
|
+
rotateArea: (areaID: string, degrees: number) => void;
|
|
126
|
+
/** Mirror one surface polygon about its own center — "x" flips it
|
|
127
|
+
* left-right, "y" top-bottom. */
|
|
128
|
+
mirrorArea: (areaID: string, axis: "x" | "y") => void;
|
|
129
|
+
setItemAttributes: (itemID: string, attributes: Record<string, any>) => void;
|
|
130
|
+
setHoleProperties: (holeID: string, properties: Record<string, any>) => void;
|
|
131
|
+
setHoleAttributes: (holeID: string, attributes: Record<string, any>) => void;
|
|
132
|
+
moveHole: (holeID: string, offset: number) => void;
|
|
133
|
+
resizeHandlesFor: string | null;
|
|
134
|
+
setResizeHandlesFor: (itemID: string | null) => void;
|
|
135
|
+
/** Drives the hover affordances in the 2D viewer (wall highlight + endpoint
|
|
136
|
+
* handles) so elements can be dragged/resized without selecting them
|
|
137
|
+
* first. Only ever set while the planner is idle. */
|
|
138
|
+
hoveredElement: HoveredElement | null;
|
|
139
|
+
setHoveredElement: (hovered: HoveredElement | null) => void;
|
|
140
|
+
beginResizingItem: (layerID: string, itemID: string, x: number, y: number) => void;
|
|
141
|
+
updateResizingItem: (x: number, y: number) => void;
|
|
142
|
+
endResizingItem: (x: number, y: number) => void;
|
|
46
143
|
beginRotatingItem: (layerID: string, itemID: string, x: number, y: number) => void;
|
|
47
144
|
endRotatingItem: (x: number, y: number) => void;
|
|
48
145
|
beginDraggingItem: (layerID: string, itemID: string, x: number, y: number) => void;
|
|
@@ -117,6 +214,10 @@ export interface ReactPlannerStore {
|
|
|
117
214
|
undo: () => void;
|
|
118
215
|
viewer: ReactSVGPanZoom | null;
|
|
119
216
|
setViewer: (viewer: ReactSVGPanZoom) => void;
|
|
217
|
+
/** The mounted 3D viewer, or null when the 3D view isn't on screen. Lets
|
|
218
|
+
* the toolbar drive the camera without knowing anything about three.js. */
|
|
219
|
+
viewer3D: Viewer3DHandle | null;
|
|
220
|
+
setViewer3D: (viewer: Viewer3DHandle | null) => void;
|
|
120
221
|
plan: Plan | null;
|
|
121
222
|
initCatalog: (catalog: any) => void;
|
|
122
223
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
interface PropertyStringProps {
|
|
2
|
-
value: any;
|
|
3
|
-
onUpdate: (v: any) => void;
|
|
4
|
-
onValid?: (event: Event) => void;
|
|
5
|
-
configs: Record<string, any>;
|
|
6
|
-
sourceElement?: any;
|
|
7
|
-
internalState?: any;
|
|
8
|
-
}
|
|
9
|
-
declare const PropertyString: ({ value, onUpdate, configs, sourceElement, internalState, }: PropertyStringProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
|
-
export default PropertyString;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import Catalog from "../catalog/catalog";
|
|
2
|
-
interface PopupProps {
|
|
3
|
-
onClose: () => void;
|
|
4
|
-
catalog: Catalog;
|
|
5
|
-
popupEvent: {
|
|
6
|
-
rect: DOMRect;
|
|
7
|
-
page: string;
|
|
8
|
-
} | null;
|
|
9
|
-
}
|
|
10
|
-
declare const Popup: ({ catalog, popupEvent, onClose: handleClose }: PopupProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
-
export default Popup;
|