diff --git a/dist/index.html b/dist/index.html
index 5a46227..67732ff 100644
--- a/dist/index.html
+++ b/dist/index.html
@@ -5,7 +5,7 @@
furniture-app
-
+
diff --git a/src/ai/nn.ts b/src/ai/nn.ts
index d5fcb2e..5402894 100644
--- a/src/ai/nn.ts
+++ b/src/ai/nn.ts
@@ -16,6 +16,11 @@ export function optimizeWithNN(state: LayoutState, options: NNOptions = {}): { b
...f,
shape: { ...f.shape, points: f.shape.points?.map((p) => ({ ...p })) },
})),
+ presets: state.presets?.map((p) => ({
+ ...p,
+ shape: { ...p.shape },
+ conditions: p.conditions.map((c) => ({ ...c, params: { ...(c.params || {}) } })),
+ })),
};
const entrance = candidate.entrance;
diff --git a/src/components/ControlPanel.tsx b/src/components/ControlPanel.tsx
index 565131c..c031499 100644
--- a/src/components/ControlPanel.tsx
+++ b/src/components/ControlPanel.tsx
@@ -308,23 +308,11 @@ export function ControlPanel({
diff --git a/src/components/RoomCanvas.tsx b/src/components/RoomCanvas.tsx
index bbe3651..75986ad 100644
--- a/src/components/RoomCanvas.tsx
+++ b/src/components/RoomCanvas.tsx
@@ -33,38 +33,6 @@ export function RoomCanvas({ state, onStateChange, mode, selectedId, onSelect, s
return () => clearInterval(t);
}, [showPaths]);
- const [viewport, setViewport] = useState({ width: 1200, height: 800 });
- const containerRef = useRef(null);
-
- useEffect(() => {
- const resize = () => {
- if (containerRef.current) {
- setViewport({
- width: Math.floor(containerRef.current.clientWidth),
- height: Math.floor(containerRef.current.clientHeight),
- });
- }
- };
- resize();
- window.addEventListener('resize', resize);
- return () => window.removeEventListener('resize', resize);
- }, []);
-
- useEffect(() => {
- const canvas = canvasRef.current;
- if (!canvas) return;
- const dpr = Math.max(1, window.devicePixelRatio || 1);
- const baseW = Math.min(state.room.width, viewport.width || state.room.width);
- const baseH = Math.min(state.room.height, viewport.height || state.room.height);
- canvas.style.width = `${baseW}px`;
- canvas.style.height = `${baseH}px`;
- canvas.width = baseW * dpr;
- canvas.height = baseH * dpr;
- const ctx = canvas.getContext('2d');
- if (ctx) ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
- draw();
- }, [state.room.width, state.room.height, zoom, viewport]);
-
useEffect(() => {
draw();
}, [state, selectedId, mode, zoom, showPaths, phase]);
@@ -74,14 +42,9 @@ export function RoomCanvas({ state, onStateChange, mode, selectedId, onSelect, s
if (!canvas) return;
const ctx = canvas.getContext('2d');
if (!ctx) return;
- const dpr = Math.max(1, window.devicePixelRatio || 1);
- ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
- ctx.clearRect(0, 0, canvas.width / dpr, canvas.height / dpr);
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.save();
- const scaleX = (canvas.width / dpr) / state.room.width;
- const scaleY = (canvas.height / dpr) / state.room.height;
- const s = Math.min(scaleX, scaleY);
- ctx.scale(s, s);
+ ctx.scale(zoom, zoom);
ctx.fillStyle = '#12151b';
ctx.fillRect(0, 0, state.room.width, state.room.height);
@@ -90,21 +53,16 @@ export function RoomCanvas({ state, onStateChange, mode, selectedId, onSelect, s
ctx.strokeStyle = 'rgba(255,255,255,0.035)';
ctx.lineWidth = 1;
const step = 25;
- const maxLines = 2000;
- const xCount = Math.min(Math.floor(state.room.width / step) + 1, maxLines);
- const yCount = Math.min(Math.floor(state.room.height / step) + 1, maxLines);
- for (let i = 0; i < xCount; i++) {
- const x = i * step;
+ for (let x = 0; x <= state.room.width; x += step) {
ctx.beginPath();
ctx.moveTo(x, 0);
- ctx.lineTo(x, Math.min(state.room.height, step * yCount));
+ ctx.lineTo(x, state.room.height);
ctx.stroke();
}
- for (let i = 0; i < yCount; i++) {
- const y = i * step;
+ for (let y = 0; y <= state.room.height; y += step) {
ctx.beginPath();
ctx.moveTo(0, y);
- ctx.lineTo(Math.min(state.room.width, step * xCount), y);
+ ctx.lineTo(state.room.width, y);
ctx.stroke();
}
@@ -350,19 +308,17 @@ export function RoomCanvas({ state, onStateChange, mode, selectedId, onSelect, s
};
return (
-
-
-
+
);
}
diff --git a/src/geometry/collision.ts b/src/geometry/collision.ts
index b607c03..ca96eed 100644
--- a/src/geometry/collision.ts
+++ b/src/geometry/collision.ts
@@ -35,8 +35,7 @@ export function colliderCorners(c: Collider): Point[] {
function project(points: Point[], axis: Point): [number, number] {
let min = Infinity;
let max = -Infinity;
- for (let i = 0; i < points.length; i++) {
- const p = points[i];
+ for (const p of points) {
const d = p.x * axis.x + p.y * axis.y;
if (d < min) min = d;
if (d > max) max = d;
diff --git a/src/optimization/randomSearch.ts b/src/optimization/randomSearch.ts
index 03080ae..b00b310 100644
--- a/src/optimization/randomSearch.ts
+++ b/src/optimization/randomSearch.ts
@@ -48,5 +48,6 @@ function cloneState(state: LayoutState): LayoutState {
room: { ...state.room },
entrance: state.entrance ? { ...state.entrance } : null,
furniture: state.furniture.map((f) => new Furniture(f).toConfig()),
+ presets: state.presets?.map((p) => ({ ...p, shape: { ...p.shape }, conditions: p.conditions.map((c) => ({ ...c, params: { ...(c.params || {}) } })) })),
};
}