floor-editor-ts 1.1.8 → 1.2.1

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.
@@ -64640,7 +64640,7 @@ var root_22 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -tr
64640
64640
  var root_23 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-emerald-600 text-white px-3 py-1 rounded-full text-xs shadow">Click to place text label · Esc to cancel</div>`);
64641
64641
  var root_24 = /* @__PURE__ */ from_html(`<div class="absolute top-2 left-1/2 -translate-x-1/2 bg-indigo-600 text-white px-3 py-1 rounded-full text-xs shadow"> </div>`);
64642
64642
  var root_2$3 = /* @__PURE__ */ from_html(`<!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <!> <div class="absolute bottom-3 left-3 z-20 flex items-center gap-1 bg-white rounded-lg shadow-lg border border-gray-200 px-1 py-0.5"><button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-600 hover:text-gray-800 font-bold text-lg" title="Zoom Out (−)" aria-label="Zoom out">−</button> <button class="min-w-[3.5rem] h-7 flex items-center justify-center rounded hover:bg-gray-100 text-xs font-medium text-gray-600 hover:text-gray-800 tabular-nums" title="Reset to 100%" aria-label="Zoom to 100%"> </button> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-600 hover:text-gray-800 font-bold text-lg" title="Zoom In (+)" aria-label="Zoom in">+</button> <div class="w-px h-5 bg-gray-200"></div> <button class="w-7 h-7 flex items-center justify-center rounded hover:bg-gray-100 text-gray-500 hover:text-gray-700 text-sm" title="Zoom to Fit (F)" aria-label="Zoom to fit">⊞</button></div> <!>`, 1);
64643
- var root$1 = /* @__PURE__ */ from_html(`<div class="w-full h-full relative overflow-hidden" role="application"><div><canvas aria-label="Floor plan editor canvas"></canvas></div> <!> <!></div>`);
64643
+ var root$1 = /* @__PURE__ */ from_html(`<div class="w-full h-full relative overflow-hidden" role="application"><div class="w-full h-full"><canvas aria-label="Floor plan editor canvas"></canvas></div> <!> <!></div>`);
64644
64644
  function FloorPlanCanvas($$anchor, $$props) {
64645
64645
  push($$props, true);
64646
64646
  const $panMode = () => store_get(panMode, "$panMode", $$stores);
@@ -64651,6 +64651,9 @@ function FloorPlanCanvas($$anchor, $$props) {
64651
64651
  let ctx;
64652
64652
  let width = /* @__PURE__ */ state(800);
64653
64653
  let height = /* @__PURE__ */ state(600);
64654
+ let viewOnlyCanvasW = /* @__PURE__ */ state(0);
64655
+ let viewOnlyCanvasH = /* @__PURE__ */ state(0);
64656
+ let canvasFrame;
64654
64657
  let camX = /* @__PURE__ */ state(0);
64655
64658
  let camY = /* @__PURE__ */ state(0);
64656
64659
  let zoom = /* @__PURE__ */ state(1);
@@ -64734,6 +64737,7 @@ function FloorPlanCanvas($$anchor, $$props) {
64734
64737
  user_effect(() => {
64735
64738
  if ($$props.viewOnly) set(showRulers, false);
64736
64739
  if ($$props.viewOnly) set(showMinimap, false);
64740
+ if ($$props.viewOnly) set(showDimensions, false);
64737
64741
  });
64738
64742
  user_effect(() => {
64739
64743
  if ($$props.viewOnly) {
@@ -65083,39 +65087,40 @@ function FloorPlanCanvas($$anchor, $$props) {
65083
65087
  return end;
65084
65088
  }
65085
65089
  function resize() {
65090
+ if ($$props.viewOnly) {
65091
+ layoutViewOnlyViewport();
65092
+ return;
65093
+ }
65086
65094
  const parent = canvas === null || canvas === void 0 ? void 0 : canvas.parentElement;
65087
65095
  if (!parent) return;
65088
- if (!$$props.viewOnly) {
65089
- set(width, parent.clientWidth, true);
65090
- set(height, parent.clientHeight, true);
65091
- if (canvas) {
65092
- canvas.width = get(width);
65093
- canvas.height = get(height);
65094
- }
65095
- markDirty();
65096
- needsFitToCanvas = true;
65097
- return;
65096
+ set(width, parent.clientWidth, true);
65097
+ set(height, parent.clientHeight, true);
65098
+ if (canvas) {
65099
+ canvas.width = get(width);
65100
+ canvas.height = get(height);
65098
65101
  }
65099
- layoutViewOnlyViewport();
65102
+ markDirty();
65103
+ needsFitToCanvas = true;
65100
65104
  }
65101
- /** viewOnly: show full floor contain fit, nothing clipped */
65105
+ /** viewOnly: canvas fills parent 100%, floor zoomed to fit edge-to-edge */
65102
65106
  function layoutViewOnlyViewport() {
65103
- const parent = canvas === null || canvas === void 0 ? void 0 : canvas.parentElement;
65104
- if (!parent || !get(currentFloor)) return;
65107
+ if (!canvasFrame || !get(currentFloor)) return;
65105
65108
  const bounds = getViewOnlyFitBounds(get(currentFloor));
65106
65109
  if (!bounds) return;
65107
- const domWidth = parent.clientWidth;
65108
- const domHeight = parent.clientHeight;
65109
- if (domWidth <= 0 || domHeight <= 0) return;
65110
- set(width, domWidth, true);
65111
- set(height, domHeight, true);
65110
+ const maxW = canvasFrame.clientWidth;
65111
+ const maxH = canvasFrame.clientHeight;
65112
+ if (maxW <= 0 || maxH <= 0) return;
65113
+ set(width, maxW, true);
65114
+ set(height, maxH, true);
65115
+ set(viewOnlyCanvasW, maxW, true);
65116
+ set(viewOnlyCanvasH, maxH, true);
65112
65117
  if (canvas) {
65113
- canvas.width = get(width);
65114
- canvas.height = get(height);
65118
+ canvas.width = maxW;
65119
+ canvas.height = maxH;
65115
65120
  }
65116
65121
  set(camX, (bounds.minX + bounds.maxX) / 2);
65117
65122
  set(camY, (bounds.minY + bounds.maxY) / 2);
65118
- set(zoom, Math.min(get(width) / bounds.width, get(height) / bounds.height), true);
65123
+ set(zoom, Math.min(maxW / bounds.width, maxH / bounds.height), true);
65119
65124
  set(zoom, Math.max(get(zoom), .1), true);
65120
65125
  markDirty();
65121
65126
  }
@@ -65593,65 +65598,19 @@ function FloorPlanCanvas($$anchor, $$props) {
65593
65598
  height
65594
65599
  };
65595
65600
  }
65596
- function getFloorContentBounds(floor = get(currentFloor)) {
65597
- if (!floor) return null;
65598
- let minX = Infinity;
65599
- let maxX = -Infinity;
65600
- let minY = Infinity;
65601
- let maxY = -Infinity;
65602
- let found = false;
65603
- const expand = (x, y, pad = 0) => {
65604
- minX = Math.min(minX, x - pad);
65605
- maxX = Math.max(maxX, x + pad);
65606
- minY = Math.min(minY, y - pad);
65607
- maxY = Math.max(maxY, y + pad);
65608
- found = true;
65609
- };
65610
- for (const wall of floor.walls) {
65611
- expand(wall.start.x, wall.start.y, wall.thickness / 2);
65612
- expand(wall.end.x, wall.end.y, wall.thickness / 2);
65613
- if (wall.curvePoint) expand(wall.curvePoint.x, wall.curvePoint.y, wall.thickness / 2);
65614
- }
65615
- for (const item of floor.furniture) {
65616
- var _item$scale$x, _item$scale, _item$scale$y, _item$scale2, _ref, _item$width, _ref2, _item$depth;
65617
- const cat = getCatalogItem(item.catalogId);
65618
- const sx = Math.abs((_item$scale$x = (_item$scale = item.scale) === null || _item$scale === void 0 ? void 0 : _item$scale.x) !== null && _item$scale$x !== void 0 ? _item$scale$x : 1);
65619
- const sy = Math.abs((_item$scale$y = (_item$scale2 = item.scale) === null || _item$scale2 === void 0 ? void 0 : _item$scale2.y) !== null && _item$scale$y !== void 0 ? _item$scale$y : 1);
65620
- const w = ((_ref = (_item$width = item.width) !== null && _item$width !== void 0 ? _item$width : cat === null || cat === void 0 ? void 0 : cat.width) !== null && _ref !== void 0 ? _ref : 50) * sx;
65621
- const d = ((_ref2 = (_item$depth = item.depth) !== null && _item$depth !== void 0 ? _item$depth : cat === null || cat === void 0 ? void 0 : cat.depth) !== null && _ref2 !== void 0 ? _ref2 : 50) * sy;
65622
- const half = Math.max(w, d) / 2;
65623
- expand(item.position.x, item.position.y, half);
65624
- if (item.catalogId === "camera" && showCameraCones()) {
65625
- const angle = item.rotation * Math.PI / 180;
65626
- const range = Math.max(w, d) * 6;
65627
- expand(item.position.x + Math.cos(angle) * range, item.position.y + Math.sin(angle) * range, half);
65628
- }
65629
- }
65630
- if (!found) return getFloorWallBounds(floor);
65631
- const width = maxX - minX;
65632
- const height = maxY - minY;
65633
- if (width <= 0 || height <= 0) return null;
65634
- return {
65635
- minX,
65636
- minY,
65637
- maxX,
65638
- maxY,
65639
- width,
65640
- height
65641
- };
65642
- }
65643
- /** Bounds for viewOnly fit: walls + furniture bodies + margin, never crops content */
65601
+ /** Bounds for viewOnly fit: wall rect incl. wall thickness */
65644
65602
  function getViewOnlyFitBounds(floor = get(currentFloor)) {
65645
- const bounds = getFloorContentBounds(floor);
65646
- if (!bounds) return null;
65647
- const margin = 40;
65603
+ var _floor$walls2;
65604
+ const wb = getFloorWallBounds(floor);
65605
+ if (!wb || !(floor === null || floor === void 0 || (_floor$walls2 = floor.walls) === null || _floor$walls2 === void 0 ? void 0 : _floor$walls2.length)) return wb;
65606
+ const pad = Math.max(...floor.walls.map((w) => w.thickness / 2), 8);
65648
65607
  return {
65649
- minX: bounds.minX - margin,
65650
- minY: bounds.minY - margin,
65651
- maxX: bounds.maxX + margin,
65652
- maxY: bounds.maxY + margin,
65653
- width: bounds.width + margin * 2,
65654
- height: bounds.height + margin * 2
65608
+ minX: wb.minX - pad,
65609
+ minY: wb.minY - pad,
65610
+ maxX: wb.maxX + pad,
65611
+ maxY: wb.maxY + pad,
65612
+ width: wb.width + pad * 2,
65613
+ height: wb.height + pad * 2
65655
65614
  };
65656
65615
  }
65657
65616
  function getCanvasFrameStyle() {
@@ -65665,11 +65624,9 @@ function FloorPlanCanvas($$anchor, $$props) {
65665
65624
  }
65666
65625
  canvasDirty = false;
65667
65626
  ctx.clearRect(0, 0, get(width), get(height));
65668
- if (!$$props.viewOnly) {
65669
- ctx.fillStyle = "#f8f9fa";
65670
- ctx.fillRect(0, 0, get(width), get(height));
65671
- drawGrid();
65672
- }
65627
+ ctx.fillStyle = "#f8f9fa";
65628
+ ctx.fillRect(0, 0, get(width), get(height));
65629
+ if (!$$props.viewOnly) drawGrid();
65673
65630
  if (!$$props.viewOnly && get(layerVis).guides) drawGuides$1();
65674
65631
  drawBackgroundImage();
65675
65632
  const floor = get(currentFloor);
@@ -66324,7 +66281,7 @@ function FloorPlanCanvas($$anchor, $$props) {
66324
66281
  resize();
66325
66282
  setTextureLoadCallback(() => {});
66326
66283
  const resizeObs = new ResizeObserver(resize);
66327
- resizeObs.observe(canvas.parentElement);
66284
+ if (canvasFrame) resizeObs.observe(canvasFrame);
66328
66285
  requestAnimationFrame(draw);
66329
66286
  let initialFitDone = false;
66330
66287
  const unsub1 = activeFloor.subscribe((f) => {
@@ -69200,6 +69157,7 @@ function FloorPlanCanvas($$anchor, $$props) {
69200
69157
  let classes;
69201
69158
  bind_this(canvas_1, ($$value) => canvas = $$value, () => canvas);
69202
69159
  reset(div_1);
69160
+ bind_this(div_1, ($$value) => canvasFrame = $$value, () => canvasFrame);
69203
69161
  var node = sibling(div_1, 2);
69204
69162
  var consequent = ($$anchor) => {
69205
69163
  var div_2 = root_1$4();