(null)
@@ -5867,37 +6016,9 @@ export function FloorplanPanel({
slabDraftPoints,
zoneDraftPoints,
])
- const polygonDraftPolylinePoints = useMemo(() => {
- if (!(isPolygonDraftBuildActive && cursorPoint && activePolygonDraftPoints.length > 0)) {
- return null
- }
-
- return formatPolygonPoints([...activePolygonDraftPoints.map(toPoint2D), toPoint2D(cursorPoint)])
- }, [activePolygonDraftPoints, cursorPoint, isPolygonDraftBuildActive])
- const polygonDraftPolygonPoints = useMemo(() => {
- if (!(isPolygonDraftBuildActive && cursorPoint && activePolygonDraftPoints.length >= 2)) {
- return null
- }
-
- return formatPolygonPoints([...activePolygonDraftPoints.map(toPoint2D), toPoint2D(cursorPoint)])
- }, [activePolygonDraftPoints, cursorPoint, isPolygonDraftBuildActive])
- const polygonDraftClosingSegment = useMemo(() => {
- if (!(isPolygonDraftBuildActive && cursorPoint && activePolygonDraftPoints.length >= 2)) {
- return null
- }
-
- const firstPoint = activePolygonDraftPoints[0]
- if (!firstPoint) {
- return null
- }
-
- return {
- x1: toSvgX(cursorPoint[0]),
- y1: toSvgY(cursorPoint[1]),
- x2: toSvgX(firstPoint[0]),
- y2: toSvgY(firstPoint[1]),
- }
- }, [activePolygonDraftPoints, cursorPoint, isPolygonDraftBuildActive])
+ // The cursor-following polygon-draft preview (slab / zone / ceiling) moved into
+ // `FloorplanDraftCursorLayer`, which reads the live cursor from the draft store
+ // so it re-renders per move without re-rendering this panel.
const svgAspectRatio = surfaceSize.width / surfaceSize.height || 1
@@ -6315,8 +6436,12 @@ export function FloorplanPanel({
// While the cursor drives live geometry (items, drafts, moves), `fittedViewport` changes every
// pointermove. Syncing `viewport` here would call setState in a tight loop (max update depth).
+ // `cursorPoint` now lives in the draft store; read it non-reactively (this
+ // effect only re-runs when `fittedViewport` / the other transient signals
+ // change, and the viewport never refits mid-draft because scene data is
+ // stable then — so a live store read is sufficient and correct).
const transientFloorplanFit =
- cursorPoint != null ||
+ useFloorplanDraftPreview.getState().cursorPoint != null ||
movingNode != null ||
endpointReshape != null ||
isCurveReshape ||
@@ -6329,7 +6454,6 @@ export function FloorplanPanel({
)
}
}, [
- cursorPoint,
endpointReshape,
fittedViewport,
isCurveReshape,
@@ -10307,9 +10431,8 @@ export function FloorplanPanel({
>
-
@@ -10764,24 +10882,17 @@ export function FloorplanPanel({
/>
)}
- {cursorPoint && (
-
-
-
-
- )}
+
{activeDraftAnchorPoint && (
((set) => ({
+ cursorPoint: null,
+ cursorPosition: null,
+ setCursorPoint: (point) =>
+ set((state) => {
+ const prev = state.cursorPoint
+ if (!point && !prev) return state
+ if (point && prev && prev[0] === point[0] && prev[1] === point[1]) return state
+ return { cursorPoint: point }
+ }),
+ setCursorPosition: (point) =>
+ set((state) => {
+ const prev = state.cursorPosition
+ if (!point && !prev) return state
+ if (point && prev && prev.x === point.x && prev.y === point.y) return state
+ return { cursorPosition: point }
+ }),
+ reset: () =>
+ set((state) =>
+ state.cursorPoint === null && state.cursorPosition === null
+ ? state
+ : { cursorPoint: null, cursorPosition: null },
+ ),
+}))