@mark1russell7/packing 0.2.9 → 0.2.10
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/build/index.js +22 -1
- package/build/index.js.map +1 -1
- package/package.json +1 -1
- package/src/skyline.ts +24 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package",
|
|
3
3
|
"name": "@mark1russell7/packing",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.10",
|
|
5
5
|
"description": "Rectangle packing: shelf, guillotine and skyline strategies, push cascades and measures of a layout.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"rectangle-packing",
|
package/src/skyline.ts
CHANGED
|
@@ -156,6 +156,9 @@ export function packSkyline<T>(rects: Rect<T>[], outer: Rect<T>, options: Skylin
|
|
|
156
156
|
/**
|
|
157
157
|
* This function packs rectangles with a skyline in a free space. Each cell has a free range: the skyline is its start,
|
|
158
158
|
* and `limit` is its end. A cell with less room than the lowest rectangle left goes to its next free range.
|
|
159
|
+
*
|
|
160
|
+
* A rectangle that needs more cells than the outer rectangle has goes at the left edge. Its y is the first y where each
|
|
161
|
+
* cell is free over its height. Then each cell starts after the rectangle, as in the plain skyline.
|
|
159
162
|
*/
|
|
160
163
|
function packSkylineInSpace<T>(rects: Rect<T>[], outer: Rect<T>, order: SortOrder, space: FreeSpace): Rect<T> {
|
|
161
164
|
const width = Math.floor(outer.size.x);
|
|
@@ -198,9 +201,29 @@ function packSkylineInSpace<T>(rects: Rect<T>[], outer: Rect<T>, order: SortOrde
|
|
|
198
201
|
x = 0;
|
|
199
202
|
y = 0;
|
|
200
203
|
for (let i = 0; i < width; i++) if (Number.isFinite(skyline[i]!) && skyline[i]! > y) y = skyline[i]!;
|
|
204
|
+
// The rectangle covers each cell, thus it goes to the first y where each cell is free over its height
|
|
205
|
+
for (let moved = true; moved; ) {
|
|
206
|
+
moved = false;
|
|
207
|
+
for (let i = 0; i < width; i++) {
|
|
208
|
+
if (!Number.isFinite(skyline[i]!)) continue;
|
|
209
|
+
const [s, e] = rangeOf(i, y);
|
|
210
|
+
const next = s > y ? s : e < y + rh ? rangeOf(i, e)[0] : y;
|
|
211
|
+
if (next > y && Number.isFinite(next)) {
|
|
212
|
+
y = next;
|
|
213
|
+
moved = true;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
201
217
|
rect.position.set(x + ox, y + oy);
|
|
202
218
|
rect.wasPacked = true;
|
|
203
|
-
|
|
219
|
+
const top = y + rh;
|
|
220
|
+
// Each cell starts after the rectangle. A cell with a range that ends before the top of the rectangle goes to its next range.
|
|
221
|
+
for (let i = 0; i < width; i++) {
|
|
222
|
+
if (!Number.isFinite(skyline[i]!)) continue;
|
|
223
|
+
if (top <= limit[i]!) skyline[i] = top;
|
|
224
|
+
else [skyline[i], limit[i]] = rangeOf(i, top);
|
|
225
|
+
}
|
|
226
|
+
outer.size.y = Math.max(outer.size.y, top);
|
|
204
227
|
continue;
|
|
205
228
|
}
|
|
206
229
|
let found = findWindow(skyline, width, rw, limit, rh);
|