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 || {}) } })) })), }; }