floor-editor-ts 1.0.9 → 1.1.0
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-editor.es.js +178 -1
- package/dist/floor-editor.es.js.map +1 -1
- package/package.json +1 -1
package/dist/floor-editor.es.js
CHANGED
|
@@ -62605,6 +62605,48 @@ function wts(cs, wx, wy) {
|
|
|
62605
62605
|
y: (wy - cs.camY) * cs.zoom + cs.height / 2
|
|
62606
62606
|
};
|
|
62607
62607
|
}
|
|
62608
|
+
function getFloorBounds(floor, options = {}) {
|
|
62609
|
+
var _floor$walls;
|
|
62610
|
+
if (!((_floor$walls = floor.walls) === null || _floor$walls === void 0 ? void 0 : _floor$walls.length)) return null;
|
|
62611
|
+
let minX = Infinity;
|
|
62612
|
+
let maxX = -Infinity;
|
|
62613
|
+
let minY = Infinity;
|
|
62614
|
+
let maxY = -Infinity;
|
|
62615
|
+
let found = false;
|
|
62616
|
+
function expand(x, y, pad = 0) {
|
|
62617
|
+
minX = Math.min(minX, x - pad);
|
|
62618
|
+
maxX = Math.max(maxX, x + pad);
|
|
62619
|
+
minY = Math.min(minY, y - pad);
|
|
62620
|
+
maxY = Math.max(maxY, y + pad);
|
|
62621
|
+
found = true;
|
|
62622
|
+
}
|
|
62623
|
+
for (const wall of floor.walls) {
|
|
62624
|
+
const pad = options.includeWallThickness ? wall.thickness / 2 : 0;
|
|
62625
|
+
if (wall.curvePoint) {
|
|
62626
|
+
const segments = 24;
|
|
62627
|
+
for (let i = 0; i <= segments; i++) {
|
|
62628
|
+
const t = i / segments;
|
|
62629
|
+
const mt = 1 - t;
|
|
62630
|
+
expand(mt * mt * wall.start.x + 2 * mt * t * wall.curvePoint.x + t * t * wall.end.x, mt * mt * wall.start.y + 2 * mt * t * wall.curvePoint.y + t * t * wall.end.y, pad);
|
|
62631
|
+
}
|
|
62632
|
+
} else {
|
|
62633
|
+
expand(wall.start.x, wall.start.y, pad);
|
|
62634
|
+
expand(wall.end.x, wall.end.y, pad);
|
|
62635
|
+
}
|
|
62636
|
+
}
|
|
62637
|
+
if (!found) return null;
|
|
62638
|
+
const width = maxX - minX;
|
|
62639
|
+
const height = maxY - minY;
|
|
62640
|
+
if (width <= 0 || height <= 0) return null;
|
|
62641
|
+
return {
|
|
62642
|
+
minX,
|
|
62643
|
+
minY,
|
|
62644
|
+
maxX,
|
|
62645
|
+
maxY,
|
|
62646
|
+
width,
|
|
62647
|
+
height
|
|
62648
|
+
};
|
|
62649
|
+
}
|
|
62608
62650
|
function drawWall(cs, w, selected, showDimensions, dimSettings) {
|
|
62609
62651
|
const { ctx, zoom, width, height } = cs;
|
|
62610
62652
|
const s = wts(cs, w.start.x, w.start.y);
|
|
@@ -64133,6 +64175,80 @@ function drawMinimap(cs, minimapCanvas, floor, getWorldBBox) {
|
|
|
64133
64175
|
mctx.lineWidth = 1;
|
|
64134
64176
|
mctx.strokeRect(0, 0, mw, mh);
|
|
64135
64177
|
}
|
|
64178
|
+
function drawFloorHeatmap(cs, floor, heatmapMatrix, detectedRooms) {
|
|
64179
|
+
var _heatmapMatrix$;
|
|
64180
|
+
const { ctx, zoom } = cs;
|
|
64181
|
+
const rows = heatmapMatrix.length;
|
|
64182
|
+
const cols = ((_heatmapMatrix$ = heatmapMatrix[0]) === null || _heatmapMatrix$ === void 0 ? void 0 : _heatmapMatrix$.length) || 0;
|
|
64183
|
+
if (rows === 0 || cols === 0) return;
|
|
64184
|
+
const maxValue = Math.max(...heatmapMatrix.flat());
|
|
64185
|
+
if (maxValue <= 0) return;
|
|
64186
|
+
const bounds = getFloorBounds(floor);
|
|
64187
|
+
if (!bounds) return;
|
|
64188
|
+
const { minX, minY, maxX, maxY } = bounds;
|
|
64189
|
+
const boxW = bounds.width;
|
|
64190
|
+
const boxH = bounds.height;
|
|
64191
|
+
if (boxW <= 0 || boxH <= 0) return;
|
|
64192
|
+
const cellW = boxW / cols;
|
|
64193
|
+
const cellH = boxH / rows;
|
|
64194
|
+
ctx.save();
|
|
64195
|
+
const boundP1 = wts(cs, minX, minY);
|
|
64196
|
+
const boundP2 = wts(cs, maxX, maxY);
|
|
64197
|
+
ctx.beginPath();
|
|
64198
|
+
ctx.rect(Math.min(boundP1.x, boundP2.x), Math.min(boundP1.y, boundP2.y), Math.abs(boundP2.x - boundP1.x), Math.abs(boundP2.y - boundP1.y));
|
|
64199
|
+
ctx.clip();
|
|
64200
|
+
let hasRoomClip = false;
|
|
64201
|
+
ctx.beginPath();
|
|
64202
|
+
for (const room of detectedRooms) {
|
|
64203
|
+
const poly = getRoomPolygon(room, floor.walls);
|
|
64204
|
+
if (poly.length < 3) continue;
|
|
64205
|
+
const screenPoly = poly.map((p) => wts(cs, p.x, p.y));
|
|
64206
|
+
ctx.moveTo(screenPoly[0].x, screenPoly[0].y);
|
|
64207
|
+
for (let i = 1; i < screenPoly.length; i++) ctx.lineTo(screenPoly[i].x, screenPoly[i].y);
|
|
64208
|
+
ctx.closePath();
|
|
64209
|
+
hasRoomClip = true;
|
|
64210
|
+
}
|
|
64211
|
+
if (hasRoomClip) ctx.clip();
|
|
64212
|
+
ctx.globalCompositeOperation = "source-over";
|
|
64213
|
+
ctx.filter = `blur(${Math.min(14, Math.max(3, 5 * zoom))}px)`;
|
|
64214
|
+
const radius = Math.max(cellW, cellH) * zoom * 1.15;
|
|
64215
|
+
for (let y = 0; y < rows; y++) for (let x = 0; x < cols; x++) {
|
|
64216
|
+
const value = heatmapMatrix[y][x];
|
|
64217
|
+
if (!value || value <= 0) continue;
|
|
64218
|
+
const intensity = Math.min(value / maxValue, 1);
|
|
64219
|
+
const s = wts(cs, minX + (x + .5) * cellW, minY + (y + .5) * cellH);
|
|
64220
|
+
const gradient = ctx.createRadialGradient(s.x, s.y, 0, s.x, s.y, radius);
|
|
64221
|
+
const alpha = .08 + intensity * .45;
|
|
64222
|
+
gradient.addColorStop(0, getHeatmapColor(intensity, alpha));
|
|
64223
|
+
gradient.addColorStop(.35, getHeatmapColor(intensity, alpha * .35));
|
|
64224
|
+
gradient.addColorStop(1, getHeatmapColor(intensity, 0));
|
|
64225
|
+
ctx.fillStyle = gradient;
|
|
64226
|
+
ctx.beginPath();
|
|
64227
|
+
ctx.arc(s.x, s.y, radius, 0, Math.PI * 2);
|
|
64228
|
+
ctx.fill();
|
|
64229
|
+
}
|
|
64230
|
+
ctx.filter = "none";
|
|
64231
|
+
ctx.globalCompositeOperation = "source-over";
|
|
64232
|
+
ctx.strokeStyle = "rgba(255, 255, 255, 0.22)";
|
|
64233
|
+
ctx.lineWidth = Math.max(.5, 1 / zoom);
|
|
64234
|
+
ctx.beginPath();
|
|
64235
|
+
for (let x = 0; x <= cols; x++) {
|
|
64236
|
+
const wx = minX + x * cellW;
|
|
64237
|
+
const p1 = wts(cs, wx, minY);
|
|
64238
|
+
const p2 = wts(cs, wx, maxY);
|
|
64239
|
+
ctx.moveTo(p1.x, p1.y);
|
|
64240
|
+
ctx.lineTo(p2.x, p2.y);
|
|
64241
|
+
}
|
|
64242
|
+
for (let y = 0; y <= rows; y++) {
|
|
64243
|
+
const wy = minY + y * cellH;
|
|
64244
|
+
const p1 = wts(cs, minX, wy);
|
|
64245
|
+
const p2 = wts(cs, maxX, wy);
|
|
64246
|
+
ctx.moveTo(p1.x, p1.y);
|
|
64247
|
+
ctx.lineTo(p2.x, p2.y);
|
|
64248
|
+
}
|
|
64249
|
+
ctx.stroke();
|
|
64250
|
+
ctx.restore();
|
|
64251
|
+
}
|
|
64136
64252
|
//#endregion
|
|
64137
64253
|
//#region src/lib/utils/hitTesting.ts
|
|
64138
64254
|
function pointInPolygon(p, poly) {
|
|
@@ -64511,6 +64627,7 @@ function FloorPlanCanvas($$anchor, $$props) {
|
|
|
64511
64627
|
const RULER_SIZE = 24;
|
|
64512
64628
|
let detectedRooms = /* @__PURE__ */ state(proxy([]));
|
|
64513
64629
|
let lastWallHash = "";
|
|
64630
|
+
const GRID = 20;
|
|
64514
64631
|
const SNAP = 10;
|
|
64515
64632
|
const MAGNETIC_SNAP = 15;
|
|
64516
64633
|
const WALL_SNAP_DIST = 30;
|
|
@@ -64814,6 +64931,46 @@ function FloorPlanCanvas($$anchor, $$props) {
|
|
|
64814
64931
|
markDirty();
|
|
64815
64932
|
needsFitToCanvas = true;
|
|
64816
64933
|
}
|
|
64934
|
+
function drawGrid() {
|
|
64935
|
+
if (!ctx || !get(showGrid)) return;
|
|
64936
|
+
const step = (get(currentSnapToGrid) ? get(currentGridSize) : GRID) * get(zoom);
|
|
64937
|
+
if (step < 4) return;
|
|
64938
|
+
ctx.strokeStyle = "#e8eaed";
|
|
64939
|
+
ctx.lineWidth = .5;
|
|
64940
|
+
const offX = (get(width) / 2 - get(camX) * get(zoom)) % step;
|
|
64941
|
+
const offY = (get(height) / 2 - get(camY) * get(zoom)) % step;
|
|
64942
|
+
for (let x = offX; x < get(width); x += step) {
|
|
64943
|
+
ctx.beginPath();
|
|
64944
|
+
ctx.moveTo(x, 0);
|
|
64945
|
+
ctx.lineTo(x, get(height));
|
|
64946
|
+
ctx.stroke();
|
|
64947
|
+
}
|
|
64948
|
+
for (let y = offY; y < get(height); y += step) {
|
|
64949
|
+
ctx.beginPath();
|
|
64950
|
+
ctx.moveTo(0, y);
|
|
64951
|
+
ctx.lineTo(get(width), y);
|
|
64952
|
+
ctx.stroke();
|
|
64953
|
+
}
|
|
64954
|
+
const majorStep = 100 * get(zoom);
|
|
64955
|
+
if (majorStep >= 20) {
|
|
64956
|
+
ctx.strokeStyle = "#d1d5db";
|
|
64957
|
+
ctx.lineWidth = .8;
|
|
64958
|
+
const mOffX = (get(width) / 2 - get(camX) * get(zoom)) % majorStep;
|
|
64959
|
+
const mOffY = (get(height) / 2 - get(camY) * get(zoom)) % majorStep;
|
|
64960
|
+
for (let x = mOffX; x < get(width); x += majorStep) {
|
|
64961
|
+
ctx.beginPath();
|
|
64962
|
+
ctx.moveTo(x, 0);
|
|
64963
|
+
ctx.lineTo(x, get(height));
|
|
64964
|
+
ctx.stroke();
|
|
64965
|
+
}
|
|
64966
|
+
for (let y = mOffY; y < get(height); y += majorStep) {
|
|
64967
|
+
ctx.beginPath();
|
|
64968
|
+
ctx.moveTo(0, y);
|
|
64969
|
+
ctx.lineTo(get(width), y);
|
|
64970
|
+
ctx.stroke();
|
|
64971
|
+
}
|
|
64972
|
+
}
|
|
64973
|
+
}
|
|
64817
64974
|
/** Get point on wall at parameter t (0-1), handling curves */
|
|
64818
64975
|
function wallPointAt(w, t) {
|
|
64819
64976
|
if (w.curvePoint) {
|
|
@@ -65254,6 +65411,9 @@ function FloorPlanCanvas($$anchor, $$props) {
|
|
|
65254
65411
|
}
|
|
65255
65412
|
canvasDirty = false;
|
|
65256
65413
|
ctx.clearRect(0, 0, get(width), get(height));
|
|
65414
|
+
ctx.fillStyle = "#f8f9fa";
|
|
65415
|
+
ctx.fillRect(0, 0, $$props.floorMaxWidth, $$props.floorMaxHeight);
|
|
65416
|
+
drawGrid();
|
|
65257
65417
|
if (!$$props.viewOnly && get(layerVis).guides) drawGuides$1();
|
|
65258
65418
|
drawBackgroundImage();
|
|
65259
65419
|
const floor = get(currentFloor);
|
|
@@ -65273,6 +65433,7 @@ function FloorPlanCanvas($$anchor, $$props) {
|
|
|
65273
65433
|
return id === selId || multiIds.has(id);
|
|
65274
65434
|
}
|
|
65275
65435
|
drawRooms$1();
|
|
65436
|
+
if (floor && $$props.heatmapEnabled) drawFloorHeatmap(getCS(), floor, $$props.heatmapMatrix || [], get(detectedRooms));
|
|
65276
65437
|
if (!$$props.viewOnly) drawSnapPoints$1();
|
|
65277
65438
|
if (get(layerVis).walls) {
|
|
65278
65439
|
for (const w of floor.walls) drawWall$1(w, isSelected(w.id));
|
|
@@ -70291,7 +70452,9 @@ function App($$anchor, $$props) {
|
|
|
70291
70452
|
let config = /* @__PURE__ */ state(proxy({
|
|
70292
70453
|
viewOnly: false,
|
|
70293
70454
|
floorMaxWidth: 600,
|
|
70294
|
-
floorMaxHeight: 400
|
|
70455
|
+
floorMaxHeight: 400,
|
|
70456
|
+
heatmapEnabled: false,
|
|
70457
|
+
heatmapMatrix: []
|
|
70295
70458
|
}));
|
|
70296
70459
|
(_$$props$stores = $$props.stores) === null || _$$props$stores === void 0 || _$$props$stores.floorData.subscribe((v) => set(floorData, v, true));
|
|
70297
70460
|
(_$$props$stores2 = $$props.stores) === null || _$$props$stores2 === void 0 || _$$props$stores2.config.subscribe((v) => set(config, v, true));
|
|
@@ -70402,6 +70565,14 @@ function App($$anchor, $$props) {
|
|
|
70402
70565
|
var _$$get4;
|
|
70403
70566
|
return (_$$get4 = get(config)) === null || _$$get4 === void 0 ? void 0 : _$$get4.floorMaxHeight;
|
|
70404
70567
|
});
|
|
70568
|
+
let $3 = /* @__PURE__ */ user_derived(() => {
|
|
70569
|
+
var _$$get5;
|
|
70570
|
+
return (_$$get5 = get(config)) === null || _$$get5 === void 0 ? void 0 : _$$get5.heatmapMatrix;
|
|
70571
|
+
});
|
|
70572
|
+
let $4 = /* @__PURE__ */ user_derived(() => {
|
|
70573
|
+
var _$$get6;
|
|
70574
|
+
return (_$$get6 = get(config)) === null || _$$get6 === void 0 ? void 0 : _$$get6.heatmapEnabled;
|
|
70575
|
+
});
|
|
70405
70576
|
FloorPlanCanvas(node_4, {
|
|
70406
70577
|
get viewOnly() {
|
|
70407
70578
|
return get($0);
|
|
@@ -70411,6 +70582,12 @@ function App($$anchor, $$props) {
|
|
|
70411
70582
|
},
|
|
70412
70583
|
get floorMaxHeight() {
|
|
70413
70584
|
return get($2);
|
|
70585
|
+
},
|
|
70586
|
+
get heatmapMatrix() {
|
|
70587
|
+
return get($3);
|
|
70588
|
+
},
|
|
70589
|
+
get heatmapEnabled() {
|
|
70590
|
+
return get($4);
|
|
70414
70591
|
}
|
|
70415
70592
|
});
|
|
70416
70593
|
}
|