@threekit-tools/treble 0.0.89-next-001 → 0.0.89-next-003

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.
@@ -1,4 +1,4 @@
1
- import { IWalls, IVerticesState, ICoordinate2D, IFeature, IFeatures, ICoordinatesLine, IRoomBuilderStateProps, IElementAddress, IFeatureName, IVertex, IFeaturesHydrated, IElementUi, IElementName, IActiveElement } from './types';
1
+ import { IWalls, IVerticesState, ICoordinate2D, IFeature, IFeatures, ICoordinatesLine, IRoomBuilderStateProps, IElementAddress, IFeatureName, IVertex, IFeaturesHydrated, IElementUi, IElementName, IActiveElement, IEnclosedSpace } from './types';
2
2
  import type { IHydratedAttribute } from '../../types';
3
3
  export declare class RoomBuilderState {
4
4
  private _config;
@@ -30,7 +30,7 @@ export declare class RoomBuilderState {
30
30
  set showDimensions(val: boolean);
31
31
  get angleSnappingEnabled(): boolean;
32
32
  set angleSnappingEnabled(val: boolean);
33
- get enclosedSpaces(): ICoordinatesLine[][];
33
+ get enclosedSpaces(): Array<IEnclosedSpace>;
34
34
  private getWall;
35
35
  private addWall;
36
36
  private addWalls;
@@ -80,6 +80,7 @@ export declare class RoomBuilderState {
80
80
  highlightElementIfInProximity(canvas: HTMLCanvasElement, point: ICoordinate2D): void;
81
81
  startDrawNewWall(startPoint: ICoordinate2D): void;
82
82
  drawNewWall(canvas: HTMLCanvasElement, endPoint: ICoordinate2D): void;
83
+ cancelDrawNewWall(canvas: HTMLCanvasElement): void;
83
84
  finishDrawNewWall(canvas: HTMLCanvasElement, assetId: string): Promise<void>;
84
85
  private moveActiveVertex;
85
86
  private finishMoveActiveVertex;
@@ -88,6 +89,7 @@ export declare class RoomBuilderState {
88
89
  selectElementIfInProximity(canvas: HTMLCanvasElement, point: ICoordinate2D): void;
89
90
  moveActiveElement(canvas: HTMLCanvasElement, moveToPoint: ICoordinate2D): void;
90
91
  finishMoveActiveElement(canvas: HTMLCanvasElement): void;
92
+ cancelMoveActiveElement(canvas: HTMLCanvasElement): void;
91
93
  drawRoom(canvas: HTMLCanvasElement | null): void;
92
94
  }
93
95
  export default RoomBuilderState;
@@ -65,6 +65,7 @@ var draw_1 = require("./draw");
65
65
  var dataHandlers_1 = require("./dataHandlers");
66
66
  var __1 = require("../..");
67
67
  var constants_1 = require("./constants");
68
+ var findLoops_1 = require("./findLoops");
68
69
  var RoomBuilderState = (function () {
69
70
  function RoomBuilderState(config) {
70
71
  var _a;
@@ -318,9 +319,23 @@ var RoomBuilderState = (function () {
318
319
  Object.defineProperty(RoomBuilderState.prototype, "enclosedSpaces", {
319
320
  get: function () {
320
321
  var _this = this;
321
- return (0, geometry_1.findClosedPaths)(this.wallLines).map(function (loop) {
322
- return loop.map(function (wallIndex) { return _this.getWall(wallIndex).line; });
323
- });
322
+ var loops = (0, findLoops_1.findLoops)(this.wallLines).inner;
323
+ return loops.reduce(function (output, loop) {
324
+ var screenSpaceArea = Math.round((0, geometry_1.getPolygonArea)(loop));
325
+ var area = screenSpaceArea * Math.pow(_this._config.config.scale, 2);
326
+ var convertedArea = (0, dataHandlers_1.convertAreaUnit)(area, types_1.IUnits.METER, _this._config.config.unit);
327
+ var enclosedSpace = {
328
+ loop: loop,
329
+ area: (0, dataHandlers_1.prepAreaForUser)(convertedArea, _this._config.config.unit),
330
+ center: loop.reduce(function (centerPoint, point) {
331
+ centerPoint[0] += point[0] / loop.length;
332
+ centerPoint[1] += point[1] / loop.length;
333
+ return centerPoint;
334
+ }, [0, 0]),
335
+ };
336
+ output.push(enclosedSpace);
337
+ return output;
338
+ }, []);
324
339
  },
325
340
  enumerable: false,
326
341
  configurable: true
@@ -369,12 +384,11 @@ var RoomBuilderState = (function () {
369
384
  var line = (_a = this.getWall(index)) === null || _a === void 0 ? void 0 : _a.line;
370
385
  if (!line)
371
386
  return undefined;
372
- var prepLength = function (val) { return val.toFixed(2); };
373
387
  var lineLength = (0, geometry_1.getLengthOfLineSegment)(line) * this._config.config.scale;
374
388
  var convertedVal = (0, dataHandlers_1.convertLengthUnit)(lineLength, types_1.IUnits.METER, this._config.config.unit);
375
389
  return {
376
390
  line: line,
377
- label: "".concat(prepLength(convertedVal), " ").concat(constants_1.UNIT_LABELS[this._config.config.unit]),
391
+ label: (0, dataHandlers_1.prepLengthForUser)(convertedVal, this._config.config.unit),
378
392
  };
379
393
  };
380
394
  RoomBuilderState.prototype.getWallDetailedDimensions = function (index) {
@@ -771,7 +785,7 @@ var RoomBuilderState = (function () {
771
785
  RoomBuilderState.prototype.getWallInProximity = function (point) {
772
786
  var _this = this;
773
787
  var index = this.walls.findIndex(function (wall) {
774
- var path = (0, geometry_1.addThicknessToLine)(wall.line, _this._config.config.styles.wall.thickness * constants_1.WALL_SNAP_DISTANCE);
788
+ var path = (0, geometry_1.addThicknessToLine)(wall.line, _this._config.config.styles.wall.thickness + constants_1.WALL_SNAP_DISTANCE);
775
789
  return (0, geometry_1.isPointInQuadrilateral)(path, point);
776
790
  });
777
791
  if (index === -1)
@@ -838,11 +852,10 @@ var RoomBuilderState = (function () {
838
852
  if (degrees === 0 || degrees % 90 === 0)
839
853
  continue;
840
854
  var radians = degrees * (Math.PI / 180);
841
- var slope = Math.tan(radians);
842
- if ((0, geometry_1.getDistanceToLine)(anchorPoint, slope, point) < snapProximity)
855
+ if ((0, geometry_1.getDistanceToLine)(anchorPoint, radians, point) < snapProximity)
843
856
  return {
844
857
  type: 'Angle',
845
- point: (0, geometry_1.closestPointOnLine)(anchorPoint, slope, point),
858
+ point: (0, geometry_1.closestPointOnLine)(anchorPoint, radians, point),
846
859
  };
847
860
  }
848
861
  return undefined;
@@ -1050,6 +1063,12 @@ var RoomBuilderState = (function () {
1050
1063
  break;
1051
1064
  }
1052
1065
  };
1066
+ RoomBuilderState.prototype.cancelDrawNewWall = function (canvas) {
1067
+ this._newWall = null;
1068
+ this._errorElement = null;
1069
+ this._highlightedElement = null;
1070
+ this.drawRoom(canvas);
1071
+ };
1053
1072
  RoomBuilderState.prototype.finishDrawNewWall = function (canvas, assetId) {
1054
1073
  return __awaiter(this, void 0, void 0, function () {
1055
1074
  var _a, start, end, snapStartTo, snapEndTo, wallsToExclude, filteredWalls, intersections, newWallLines;
@@ -1065,8 +1084,12 @@ var RoomBuilderState = (function () {
1065
1084
  return [2];
1066
1085
  }
1067
1086
  _a = this._newWall || {}, start = _a.start, end = _a.end, snapStartTo = _a.snapStartTo, snapEndTo = _a.snapEndTo;
1068
- if (!start || !end)
1087
+ if (!start || !end) {
1088
+ this._newWall = null;
1089
+ this._errorElement = null;
1090
+ this._highlightedElement = null;
1069
1091
  return [2];
1092
+ }
1070
1093
  wallsToExclude = new Set([]);
1071
1094
  if ((snapStartTo === null || snapStartTo === void 0 ? void 0 : snapStartTo.type) === types_2.IElements.WALL) {
1072
1095
  this.splitWall(snapStartTo.index, start);
@@ -1159,6 +1182,13 @@ var RoomBuilderState = (function () {
1159
1182
  this._highlightedElement = null;
1160
1183
  this.drawRoom(canvas);
1161
1184
  };
1185
+ RoomBuilderState.prototype.cancelMoveActiveElement = function (canvas) {
1186
+ this._activeElement = null;
1187
+ this._errorElement = null;
1188
+ this._highlightedElement = null;
1189
+ this.resetInternalState();
1190
+ this.drawRoom(canvas);
1191
+ };
1162
1192
  RoomBuilderState.prototype.drawRoom = function (canvas) {
1163
1193
  var _a, _b, _c, _d, _e, _f, _g;
1164
1194
  if (!canvas)
@@ -19,15 +19,23 @@ export declare const SCALE = 0.02;
19
19
  export declare const SNAP_PROXIMITY = 10;
20
20
  export declare const MIN_WALL_LENGTH = 50;
21
21
  export declare const WALL_PADDING_FOR_FEATURE = 20;
22
- export declare const DIMENSIONS_TEXT_BOX_WIDTH = 60;
23
22
  export declare const UNIT_LABELS: {
24
23
  feet: string;
25
24
  meter: string;
26
25
  inch: string;
27
26
  cm: string;
28
27
  };
29
- export declare const CANVAS_HEIGHT = 800;
30
- export declare const CANVAS_WIDTH = 800;
28
+ export declare const UNIT_FACTORS: {
29
+ cm: number;
30
+ meter: number;
31
+ feet: number;
32
+ inch: number;
33
+ };
34
+ export declare const FEATURE_LABELS: {
35
+ windows: string;
36
+ doors: string;
37
+ openings: string;
38
+ };
31
39
  export declare const FEATURE_LENGTH = 120;
32
40
  export declare const UI_ANCHOR_DISTANCE = -60;
33
- export declare const WALL_SNAP_DISTANCE = 1.5;
41
+ export declare const WALL_SNAP_DISTANCE = 12;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
- var _a;
2
+ var _a, _b, _c;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.WALL_SNAP_DISTANCE = exports.UI_ANCHOR_DISTANCE = exports.FEATURE_LENGTH = exports.CANVAS_WIDTH = exports.CANVAS_HEIGHT = exports.UNIT_LABELS = exports.DIMENSIONS_TEXT_BOX_WIDTH = exports.WALL_PADDING_FOR_FEATURE = exports.MIN_WALL_LENGTH = exports.SNAP_PROXIMITY = exports.SCALE = exports.IFeatureAttribute = exports.IWallAttributes = void 0;
4
+ exports.WALL_SNAP_DISTANCE = exports.UI_ANCHOR_DISTANCE = exports.FEATURE_LENGTH = exports.FEATURE_LABELS = exports.UNIT_FACTORS = exports.UNIT_LABELS = exports.WALL_PADDING_FOR_FEATURE = exports.MIN_WALL_LENGTH = exports.SNAP_PROXIMITY = exports.SCALE = exports.IFeatureAttribute = exports.IWallAttributes = void 0;
5
5
  var types_1 = require("./types");
6
6
  var IWallAttributes;
7
7
  (function (IWallAttributes) {
@@ -26,15 +26,23 @@ exports.SCALE = 0.02;
26
26
  exports.SNAP_PROXIMITY = 10;
27
27
  exports.MIN_WALL_LENGTH = 50;
28
28
  exports.WALL_PADDING_FOR_FEATURE = 20;
29
- exports.DIMENSIONS_TEXT_BOX_WIDTH = 60;
30
29
  exports.UNIT_LABELS = (_a = {},
31
30
  _a[types_1.IUnits.FEET] = 'ft',
32
31
  _a[types_1.IUnits.METER] = 'm',
33
32
  _a[types_1.IUnits.INCH] = 'in',
34
33
  _a[types_1.IUnits.CM] = 'cm',
35
34
  _a);
36
- exports.CANVAS_HEIGHT = 800;
37
- exports.CANVAS_WIDTH = 800;
35
+ exports.UNIT_FACTORS = (_b = {},
36
+ _b[types_1.IUnits.CM] = 100,
37
+ _b[types_1.IUnits.METER] = 1,
38
+ _b[types_1.IUnits.FEET] = 3.28084,
39
+ _b[types_1.IUnits.INCH] = 39.37,
40
+ _b);
41
+ exports.FEATURE_LABELS = (_c = {},
42
+ _c[types_1.IElements.WINDOW] = 'Window',
43
+ _c[types_1.IElements.DOOR] = 'Door',
44
+ _c[types_1.IElements.OPENING] = 'Opening',
45
+ _c);
38
46
  exports.FEATURE_LENGTH = 120;
39
47
  exports.UI_ANCHOR_DISTANCE = -60;
40
- exports.WALL_SNAP_DISTANCE = 1.5;
48
+ exports.WALL_SNAP_DISTANCE = 12;
@@ -13,3 +13,6 @@ export declare function prepAttributesOutgoing(walls: IWalls, features: IFeature
13
13
  }[];
14
14
  };
15
15
  export declare function convertLengthUnit(value: number, from: IUnits, to: IUnits): number;
16
+ export declare function convertAreaUnit(value: number, from: IUnits, to: IUnits): number;
17
+ export declare function prepLengthForUser(value: number, unit: IUnits): string;
18
+ export declare function prepAreaForUser(value: number, unit: IUnits): string;
@@ -11,7 +11,7 @@ var __assign = (this && this.__assign) || function () {
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.convertLengthUnit = exports.prepAttributesOutgoing = exports.prepAttributesIncoming = void 0;
14
+ exports.prepAreaForUser = exports.prepLengthForUser = exports.convertAreaUnit = exports.convertLengthUnit = exports.prepAttributesOutgoing = exports.prepAttributesIncoming = void 0;
15
15
  var types_1 = require("./types");
16
16
  var constants_1 = require("./constants");
17
17
  var geometry_1 = require("./geometry");
@@ -165,13 +165,23 @@ function prepAttributesOutgoing(walls, features, config) {
165
165
  }
166
166
  exports.prepAttributesOutgoing = prepAttributesOutgoing;
167
167
  function convertLengthUnit(value, from, to) {
168
- var _a;
169
- var factors = (_a = {},
170
- _a[types_1.IUnits.CM] = 100,
171
- _a[types_1.IUnits.METER] = 1,
172
- _a[types_1.IUnits.FEET] = 3.28084,
173
- _a[types_1.IUnits.INCH] = 39.37,
174
- _a);
175
- return (value / factors[from]) * factors[to];
168
+ return (value / constants_1.UNIT_FACTORS[from]) * constants_1.UNIT_FACTORS[to];
176
169
  }
177
170
  exports.convertLengthUnit = convertLengthUnit;
171
+ function convertAreaUnit(value, from, to) {
172
+ return (value / constants_1.UNIT_FACTORS[from]) * Math.pow(constants_1.UNIT_FACTORS[to], 2);
173
+ }
174
+ exports.convertAreaUnit = convertAreaUnit;
175
+ function prepLengthForUser(value, unit) {
176
+ if (unit === types_1.IUnits.FEET) {
177
+ var feet = Math.floor(value);
178
+ var inches = 1.2 * (value % 1);
179
+ return "".concat(feet).concat(constants_1.UNIT_LABELS[types_1.IUnits.FEET], " ").concat(inches.toFixed(2)).concat(constants_1.UNIT_LABELS[types_1.IUnits.INCH]);
180
+ }
181
+ return "".concat(value.toFixed(2), " ").concat(constants_1.UNIT_LABELS[unit]);
182
+ }
183
+ exports.prepLengthForUser = prepLengthForUser;
184
+ function prepAreaForUser(value, unit) {
185
+ return "".concat(value.toFixed(2), " sq-").concat(constants_1.UNIT_LABELS[unit]);
186
+ }
187
+ exports.prepAreaForUser = prepAreaForUser;
@@ -1,4 +1,4 @@
1
- import { IWall, ICoordinate2D, ICoordinatesLine, IFeatures, IFeature, IElementAddress, IRoomBuilderStyles, IRoomBuilderConfigInternal, IStylesGrid, IStylesWall, IStylesVertex, ILineDimensions, IVertex, IElementStyleModes, IStylesFloor } from './types';
1
+ import { IWall, ICoordinate2D, ICoordinatesLine, IFeatures, IFeature, IElementAddress, IRoomBuilderStyles, IRoomBuilderConfigInternal, IStylesGrid, IStylesWall, IStylesVertex, ILineDimensions, IVertex, IElementStyleModes, IStylesFloor, IEnclosedSpace } from './types';
2
2
  interface IWallToDraw extends Omit<IWall, 'assetId' | 'connections'> {
3
3
  }
4
4
  interface IWallsToDraw extends Array<IWallToDraw> {
@@ -6,7 +6,7 @@ interface IWallsToDraw extends Array<IWallToDraw> {
6
6
  export declare function clearCanvas(canvas: HTMLCanvasElement): void;
7
7
  export declare function drawBackground(canvas: HTMLCanvasElement, color?: string): void;
8
8
  export declare function drawGrid(canvas: HTMLCanvasElement, styles: IStylesGrid): void;
9
- export declare function drawFloor(canvas: HTMLCanvasElement, loops: Array<ICoordinatesLine[]>, styles: IStylesFloor): void;
9
+ export declare function drawFloor(canvas: HTMLCanvasElement, enclosedSpaces: Array<IEnclosedSpace>, styles: IStylesFloor): void;
10
10
  export declare function drawVertex(canvas: HTMLCanvasElement, point: ICoordinate2D, style: IStylesVertex, mode?: IElementStyleModes): void;
11
11
  export declare function drawNewWall(canvas: HTMLCanvasElement, line: ICoordinatesLine, styles: IRoomBuilderStyles, mode?: IElementStyleModes.ERROR): void;
12
12
  export declare function drawWalls(canvas: HTMLCanvasElement, walls: IWallsToDraw, selections: {
@@ -46,7 +46,7 @@ export declare function drawElements(canvas: HTMLCanvasElement, walls: IWallsToD
46
46
  hidden: Array<IElementAddress>;
47
47
  error: Array<IElementAddress>;
48
48
  }, styles: IRoomBuilderStyles): void;
49
- export declare function drawRoom(canvas: HTMLCanvasElement, floor: Array<ICoordinatesLine[]>, walls: IWallsToDraw, vertices: Array<IVertex>, features: IFeatures, dimensions: Array<ILineDimensions> | undefined, selections: {
49
+ export declare function drawRoom(canvas: HTMLCanvasElement, enclosedSpaces: Array<IEnclosedSpace>, walls: IWallsToDraw, vertices: Array<IVertex>, features: IFeatures, dimensions: Array<ILineDimensions> | undefined, selections: {
50
50
  active?: Array<IElementAddress> | IElementAddress;
51
51
  highlighted?: Array<IElementAddress> | IElementAddress;
52
52
  hidden?: Array<IElementAddress> | IElementAddress;
@@ -1,10 +1,19 @@
1
1
  "use strict";
2
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
3
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4
+ if (ar || !(i in from)) {
5
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6
+ ar[i] = from[i];
7
+ }
8
+ }
9
+ return to.concat(ar || Array.prototype.slice.call(from));
10
+ };
2
11
  Object.defineProperty(exports, "__esModule", { value: true });
3
12
  exports.drawRoom = exports.drawElements = exports.drawOpenings = exports.drawDoors = exports.drawWindows = exports.drawDimensions = exports.drawVertices = exports.drawWalls = exports.drawNewWall = exports.drawVertex = exports.drawFloor = exports.drawGrid = exports.drawBackground = exports.clearCanvas = void 0;
4
13
  var types_1 = require("./types");
5
14
  var types_2 = require("./types");
6
15
  var geometry_1 = require("./geometry");
7
- var constants_1 = require("./constants");
16
+ var debug = false;
8
17
  function clearCanvas(canvas) {
9
18
  var ctx = canvas.getContext('2d');
10
19
  if (!ctx)
@@ -55,33 +64,24 @@ function drawGrid(canvas, styles) {
55
64
  }
56
65
  }
57
66
  exports.drawGrid = drawGrid;
58
- function drawFloor(canvas, loops, styles) {
67
+ function drawFloor(canvas, enclosedSpaces, styles) {
59
68
  var ctx = canvas.getContext('2d');
60
69
  if (!ctx)
61
70
  return;
62
- if (!loops.length)
71
+ if (!enclosedSpaces.length)
63
72
  return;
64
- loops.forEach(function (lines) {
65
- if (!lines.length)
66
- return;
73
+ for (var _i = 0, enclosedSpaces_1 = enclosedSpaces; _i < enclosedSpaces_1.length; _i++) {
74
+ var enclosedSpace = enclosedSpaces_1[_i];
75
+ var loop = enclosedSpace.loop;
67
76
  ctx.fillStyle = styles.color;
77
+ if (debug)
78
+ ctx.fillStyle = 'rgba(255,0,0,.2)';
68
79
  ctx.beginPath();
69
- ctx.moveTo.apply(ctx, lines[0][0]);
70
- var previousPoint = lines[0][0];
71
- for (var i = 1; i < lines.length; i++) {
72
- if (!i) {
73
- ctx.lineTo.apply(ctx, lines[i][1]);
74
- continue;
75
- }
76
- if ((0, geometry_1.arePointsEqual)(previousPoint, lines[i][0])) {
77
- ctx.lineTo.apply(ctx, lines[i][1]);
78
- }
79
- else {
80
- ctx.lineTo.apply(ctx, lines[i][0]);
81
- }
82
- }
80
+ ctx.moveTo.apply(ctx, loop[0]);
81
+ for (var i = 1; i < loop.length; i++)
82
+ ctx.lineTo.apply(ctx, loop[i]);
83
83
  ctx.fill();
84
- });
84
+ }
85
85
  }
86
86
  exports.drawFloor = drawFloor;
87
87
  function drawWall(canvas, wall, style, mode) {
@@ -99,15 +99,29 @@ function drawWall(canvas, wall, style, mode) {
99
99
  ctx.fillStyle = fill;
100
100
  ctx.lineWidth = strokeWidth || 1;
101
101
  ctx.beginPath();
102
- ctx.moveTo(path[0][0], path[0][1]);
102
+ ctx.moveTo.apply(ctx, path[0]);
103
103
  for (var i = 1; i < path.length; i++) {
104
- ctx.lineTo(path[i][0], path[i][1]);
104
+ ctx.lineTo.apply(ctx, path[i]);
105
105
  }
106
- ctx.lineTo(path[0][0], path[0][1]);
106
+ ctx.lineTo.apply(ctx, path[0]);
107
107
  ctx.fill();
108
108
  if (style.stroke && style.strokeWidth)
109
109
  ctx.stroke();
110
110
  }
111
+ function drawFloorArea(canvas, enclosedSpaces, styles) {
112
+ var ctx = canvas.getContext('2d');
113
+ if (!ctx)
114
+ return;
115
+ if (!enclosedSpaces.length)
116
+ return;
117
+ for (var _i = 0, enclosedSpaces_2 = enclosedSpaces; _i < enclosedSpaces_2.length; _i++) {
118
+ var enclosedSpace = enclosedSpaces_2[_i];
119
+ var center = enclosedSpace.center, area = enclosedSpace.area;
120
+ ctx.font = '20px Arial';
121
+ ctx.fillStyle = styles.textColor;
122
+ ctx.fillText(area, center[0], center[1]);
123
+ }
124
+ }
111
125
  function drawDimension(canvas, line, styles, message) {
112
126
  var ctx = canvas.getContext('2d');
113
127
  if (!ctx)
@@ -123,24 +137,25 @@ function drawDimension(canvas, line, styles, message) {
123
137
  ctx.strokeStyle = styles.lineColor;
124
138
  ctx.lineWidth = 1;
125
139
  ctx.beginPath();
126
- ctx.moveTo(line2[0][0], line2[0][1]);
127
- ctx.lineTo(line2[1][0], line2[1][1]);
140
+ ctx.moveTo.apply(ctx, line2[0]);
141
+ ctx.lineTo.apply(ctx, line2[1]);
128
142
  ctx.stroke();
129
143
  ctx.beginPath();
130
- ctx.moveTo(line1[0][0], line1[0][1]);
131
- ctx.lineTo(line3[0][0], line3[0][1]);
144
+ ctx.moveTo.apply(ctx, line1[0]);
145
+ ctx.lineTo.apply(ctx, line3[0]);
132
146
  ctx.stroke();
133
147
  ctx.beginPath();
134
- ctx.moveTo(line1[1][0], line1[1][1]);
135
- ctx.lineTo(line3[1][0], line3[1][1]);
148
+ ctx.moveTo.apply(ctx, line1[1]);
149
+ ctx.lineTo.apply(ctx, line3[1]);
136
150
  ctx.stroke();
137
151
  ctx.beginPath();
138
152
  ctx.font = "".concat(styles.fontSize, "px ").concat(styles.font);
139
153
  ctx.font = "".concat(styles.fontSize, "px ").concat(styles.font);
140
- ctx.translate(textCoordinates[0], textCoordinates[1]);
154
+ ctx.translate.apply(ctx, textCoordinates);
141
155
  ctx.rotate(textAngle);
142
156
  ctx.fillStyle = styles.textBackgroundColor;
143
- ctx.fillRect(-(constants_1.DIMENSIONS_TEXT_BOX_WIDTH / 2), -((dimensionsBoxHeight * 3) / 4), constants_1.DIMENSIONS_TEXT_BOX_WIDTH, dimensionsBoxHeight);
157
+ var textWidth = ctx.measureText(message).width + 12;
158
+ ctx.fillRect(-(textWidth / 2), -((dimensionsBoxHeight * 3) / 4), textWidth, dimensionsBoxHeight);
144
159
  ctx.fillStyle = styles.textColor;
145
160
  ctx.textAlign = 'center';
146
161
  ctx.fillText(message, 0, 0);
@@ -174,6 +189,11 @@ function drawVertex(canvas, point, style, mode) {
174
189
  ctx.fill();
175
190
  if (!outerRadius && strokeWidth)
176
191
  ctx.stroke();
192
+ if (debug) {
193
+ ctx.font = '20px Arial';
194
+ ctx.fillStyle = 'red';
195
+ ctx.fillText.apply(ctx, __spreadArray([Math.round(point[0]) + ',' + Math.round(point[1])], point, false));
196
+ }
177
197
  }
178
198
  exports.drawVertex = drawVertex;
179
199
  function drawWindow(canvas, wall, offset, length, style, mode) {
@@ -191,27 +211,27 @@ function drawWindow(canvas, wall, offset, length, style, mode) {
191
211
  }
192
212
  ctx.fillStyle = 'white';
193
213
  ctx.beginPath();
194
- ctx.moveTo(points[0][0], points[0][1]);
214
+ ctx.moveTo.apply(ctx, points[0]);
195
215
  for (var i = 1; i < points.length; i++) {
196
- ctx.lineTo(points[i][0], points[i][1]);
216
+ ctx.lineTo.apply(ctx, points[i]);
197
217
  }
198
- ctx.lineTo(points[0][0], points[0][1]);
218
+ ctx.lineTo.apply(ctx, points[0]);
199
219
  ctx.fill();
200
220
  ctx.closePath();
201
221
  ctx.strokeStyle = stroke || fill;
202
222
  ctx.fillStyle = fill;
203
223
  ctx.lineWidth = strokeWidth || 1;
204
- ctx.moveTo(rectanglePoints[0][0], rectanglePoints[0][1]);
224
+ ctx.moveTo.apply(ctx, rectanglePoints[0]);
205
225
  ctx.beginPath();
206
226
  for (var i = 1; i < points.length; i++) {
207
- ctx.lineTo(rectanglePoints[i][0], rectanglePoints[i][1]);
227
+ ctx.lineTo.apply(ctx, rectanglePoints[i]);
208
228
  }
209
- ctx.lineTo(rectanglePoints[0][0], rectanglePoints[0][1]);
229
+ ctx.lineTo.apply(ctx, rectanglePoints[0]);
210
230
  ctx.fill();
211
231
  ctx.closePath();
212
232
  ctx.beginPath();
213
- ctx.moveTo(windowLine[0][0], windowLine[0][1]);
214
- ctx.lineTo(windowLine[1][0], windowLine[1][1]);
233
+ ctx.moveTo.apply(ctx, windowLine[0]);
234
+ ctx.lineTo.apply(ctx, windowLine[1]);
215
235
  if (style.stroke)
216
236
  ctx.stroke();
217
237
  ctx.closePath();
@@ -239,11 +259,11 @@ function drawDoor(canvas, wall, offset, length, style, mode) {
239
259
  ctx.fillStyle = fill;
240
260
  ctx.lineWidth = strokeWidth || 1;
241
261
  ctx.beginPath();
242
- ctx.moveTo(points[0][0], points[0][1]);
262
+ ctx.moveTo.apply(ctx, points[0]);
243
263
  for (var i = 1; i < points.length; i++) {
244
- ctx.lineTo(points[i][0], points[i][1]);
264
+ ctx.lineTo.apply(ctx, points[i]);
245
265
  }
246
- ctx.lineTo(points[0][0], points[0][1]);
266
+ ctx.lineTo.apply(ctx, points[0]);
247
267
  ctx.fill();
248
268
  if (style.stroke)
249
269
  ctx.stroke();
@@ -261,19 +281,19 @@ function drawOpening(canvas, wall, offset, length, style, mode) {
261
281
  }
262
282
  ctx.fillStyle = 'white';
263
283
  ctx.beginPath();
264
- ctx.moveTo(points[0][0], points[0][1]);
284
+ ctx.moveTo.apply(ctx, points[0]);
265
285
  for (var i = 1; i < points.length; i++) {
266
- ctx.lineTo(points[i][0], points[i][1]);
286
+ ctx.lineTo.apply(ctx, points[i]);
267
287
  }
268
- ctx.lineTo(points[0][0], points[0][1]);
288
+ ctx.lineTo.apply(ctx, points[0]);
269
289
  ctx.fill();
270
290
  ctx.beginPath();
271
291
  ctx.strokeStyle = stroke || fill;
272
292
  ctx.fillStyle = fill;
273
293
  ctx.lineWidth = strokeWidth || 1;
274
294
  ctx.setLineDash([10, 10]);
275
- ctx.moveTo(openingLine[0][0], openingLine[0][1]);
276
- ctx.lineTo(openingLine[1][0], openingLine[1][1]);
295
+ ctx.moveTo.apply(ctx, openingLine[0]);
296
+ ctx.lineTo.apply(ctx, openingLine[1]);
277
297
  ctx.stroke();
278
298
  ctx.closePath();
279
299
  ctx.beginPath();
@@ -533,7 +553,7 @@ function drawElements(canvas, walls, vertices, features, selections, styles) {
533
553
  drawOpenings(canvas, walls, features[types_2.IElements.OPENING] || [], openingSelections, styles);
534
554
  }
535
555
  exports.drawElements = drawElements;
536
- function drawRoom(canvas, floor, walls, vertices, features, dimensions, selections, config) {
556
+ function drawRoom(canvas, enclosedSpaces, walls, vertices, features, dimensions, selections, config) {
537
557
  var preppedSelections = {
538
558
  active: [(selections === null || selections === void 0 ? void 0 : selections.active) || []].flat(),
539
559
  highlighted: [(selections === null || selections === void 0 ? void 0 : selections.highlighted) || []].flat(),
@@ -543,9 +563,11 @@ function drawRoom(canvas, floor, walls, vertices, features, dimensions, selectio
543
563
  clearCanvas(canvas);
544
564
  drawBackground(canvas, config.styles.grid.backgroundColor);
545
565
  drawGrid(canvas, config.styles.grid);
546
- drawFloor(canvas, floor, config.styles.floor);
566
+ drawFloor(canvas, enclosedSpaces, config.styles.floor);
547
567
  drawElements(canvas, walls, vertices, features, preppedSelections, config.styles);
548
- if (dimensions)
568
+ if (dimensions) {
549
569
  drawDimensions(canvas, dimensions, config);
570
+ drawFloorArea(canvas, enclosedSpaces, config.styles.floor);
571
+ }
550
572
  }
551
573
  exports.drawRoom = drawRoom;
@@ -0,0 +1,5 @@
1
+ import type { ICoordinate2D, ICoordinatesLine } from './types';
2
+ export declare function findLoops(lines: Array<ICoordinatesLine>): {
3
+ inner: Array<ICoordinate2D[]>;
4
+ outer: Array<ICoordinate2D[]>;
5
+ };
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
3
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4
+ if (ar || !(i in from)) {
5
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
6
+ ar[i] = from[i];
7
+ }
8
+ }
9
+ return to.concat(ar || Array.prototype.slice.call(from));
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.findLoops = void 0;
13
+ var geometry_1 = require("./geometry");
14
+ var areSidesEqual = function (_a, _b) {
15
+ var lineIndex0 = _a[0], fromPoint0 = _a[1];
16
+ var lineIndex1 = _b[0], fromPoint1 = _b[1];
17
+ return lineIndex0 === lineIndex1 && (0, geometry_1.arePointsEqual)(fromPoint0, fromPoint1);
18
+ };
19
+ var composeSideKey = function (_a) {
20
+ var lineIndex = _a[0], point = _a[1];
21
+ return "".concat(lineIndex, ":").concat(JSON.stringify(point));
22
+ };
23
+ var decomposeSideKey = function (key) {
24
+ var _a = key.split(':'), lineIndexStr = _a[0], fromVertStr = _a[1];
25
+ return [Number(lineIndexStr), JSON.parse(fromVertStr)];
26
+ };
27
+ function calcPointToLineAdjacency(lines) {
28
+ return lines.reduce(function (output, line, lineIndex) {
29
+ line.forEach(function (point) {
30
+ var pointStr = JSON.stringify(point);
31
+ if (output[pointStr])
32
+ output[pointStr].push(lineIndex);
33
+ else
34
+ output[pointStr] = [lineIndex];
35
+ });
36
+ return output;
37
+ }, {});
38
+ }
39
+ function findLoops(lines) {
40
+ var pointToLinesIndices = calcPointToLineAdjacency(lines);
41
+ var unvisitedSides = new Set(__spreadArray(__spreadArray([], lines.map(function (line, i) { return composeSideKey([i, line[0]]); }), true), lines.map(function (line, i) { return composeSideKey([i, line[1]]); }), true));
42
+ var sumCurvature = 0;
43
+ function nextAdjacentWallSide(side) {
44
+ var lineIndex = side[0], fromPoint = side[1];
45
+ var line = lines[lineIndex];
46
+ var toPoint = (0, geometry_1.getLineOtherPoint)(line, fromPoint);
47
+ var lineAng = (0, geometry_1.getAngleOfLineSegment)([fromPoint, toPoint]);
48
+ var adjacentLineIndices = pointToLinesIndices[JSON.stringify(toPoint)];
49
+ var nextLineIndex;
50
+ if (adjacentLineIndices.length === 0)
51
+ throw new Error();
52
+ if (adjacentLineIndices.length === 1) {
53
+ nextLineIndex = adjacentLineIndices[0];
54
+ sumCurvature += Math.PI;
55
+ }
56
+ else {
57
+ var smallestAngDiff = Infinity;
58
+ for (var _i = 0, adjacentLineIndices_1 = adjacentLineIndices; _i < adjacentLineIndices_1.length; _i++) {
59
+ var adjacentLineIndex = adjacentLineIndices_1[_i];
60
+ if (adjacentLineIndex === lineIndex)
61
+ continue;
62
+ var adjacentLine = lines[adjacentLineIndex];
63
+ var adjacentPoint = (0, geometry_1.getLineOtherPoint)(adjacentLine, toPoint);
64
+ var adjacentLineAng = (0, geometry_1.getAngleOfLineSegment)([toPoint, adjacentPoint]);
65
+ var angDiff = (0, geometry_1.euclideanMod)(lineAng - adjacentLineAng + Math.PI, Math.PI * 2);
66
+ if (angDiff < smallestAngDiff) {
67
+ smallestAngDiff = angDiff;
68
+ nextLineIndex = adjacentLineIndex;
69
+ }
70
+ }
71
+ sumCurvature += smallestAngDiff - Math.PI;
72
+ }
73
+ return [nextLineIndex, toPoint];
74
+ }
75
+ function traverseLoop(start) {
76
+ var path = new Array();
77
+ var curr = start;
78
+ do {
79
+ path.push(curr[1]);
80
+ unvisitedSides.delete(composeSideKey(curr));
81
+ curr = nextAdjacentWallSide(curr);
82
+ } while (!areSidesEqual(start, curr));
83
+ return path;
84
+ }
85
+ var innerLoops = new Array();
86
+ var outerLoops = new Array();
87
+ while (unvisitedSides.size > 0) {
88
+ sumCurvature = 0;
89
+ var start = decomposeSideKey(unvisitedSides.values().next().value);
90
+ var path = traverseLoop(start);
91
+ var isClockwise = sumCurvature < 0;
92
+ (isClockwise ? innerLoops : outerLoops).push(path);
93
+ }
94
+ return {
95
+ inner: innerLoops,
96
+ outer: outerLoops,
97
+ };
98
+ }
99
+ exports.findLoops = findLoops;