@mapka/shelf-pack 0.4.1 → 0.4.3

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/lib/index.js CHANGED
@@ -1,29 +1,3 @@
1
- export default ShelfPack;
2
- /**
3
- * Create a new ShelfPack bin allocator.
4
- *
5
- * Uses the Shelf Best Height Fit algorithm from
6
- * http://clb.demon.fi/files/RectangleBinPack.pdf
7
- *
8
- * @class ShelfPack
9
- * @param {number} [w=64] Initial width of the sprite
10
- * @param {number} [h=64] Initial width of the sprite
11
- * @param {Object} [options]
12
- * @param {boolean} [options.autoResize=false] If `true`, the sprite will automatically grow
13
- * @example
14
- * var sprite = new ShelfPack(64, 64, { autoResize: false });
15
- */
16
- function ShelfPack(w, h, options) {
17
- options = options || {};
18
- this.w = w || 64;
19
- this.h = h || 64;
20
- this.autoResize = !!options.autoResize;
21
- this.shelves = [];
22
- this.freebins = [];
23
- this.stats = {};
24
- this.bins = {};
25
- this.maxId = 0;
26
- }
27
1
  /**
28
2
  * Bin object with `id`, `width`, `height` properties
29
3
  * @typedef {Object} BinShorthand
@@ -32,374 +6,401 @@ function ShelfPack(w, h, options) {
32
6
  * @property {number} h Height of the bin
33
7
  */
34
8
  /**
35
- * Bin object with `id`, `w`, `h` properties
36
- * @typedef {Object} Bin
37
- * @property {string} id Unique identifier for this bin
38
- * @property {number} width Width of the bin
39
- * @property {number} height Height of the bin
40
- */
41
- /**
42
- * Batch pack multiple bins into the sprite.
9
+ * Create a new ShelfPack bin allocator.
10
+ *
11
+ * Uses the Shelf Best Height Fit algorithm from
12
+ * http://clb.demon.fi/files/RectangleBinPack.pdf
43
13
  *
44
- * @param {Object[]} bins Array of requested bins - each object should have `width`, `height` (or `w`, `h`) properties
45
- * @param {Object} [options]
46
- * @param {boolean} [options.inPlace=false] If `true`, the supplied bin objects will be updated inplace with `x` and `y` properties
47
- * @returns {Bin[]} Array of allocated Bins - each Bin is an object with `id`, `x`, `y`, `w`, `h` properties
48
- * @noto Mutate input bins
49
14
  * @example
50
- * var bins = [
51
- * { id: 1, w: 12, h: 12 },
52
- * { id: 2, w: 12, h: 16 },
53
- * { id: 3, w: 12, h: 24 }
54
- * ];
55
- * var results = sprite.pack(bins, { inPlace: false });
15
+ * var sprite = new ShelfPack(64, 64, { autoResize: false });
56
16
  */
57
- ShelfPack.prototype.pack = function (bins, options) {
58
- bins = [].concat(bins);
59
- options = options || {};
60
- var results = [], w, h, id, allocation;
61
- for (var i = 0; i < bins.length; i++) {
62
- w = bins[i].w || bins[i].width;
63
- h = bins[i].h || bins[i].height;
64
- id = bins[i].id;
65
- if (w && h) {
66
- allocation = this.packOne(w, h, id);
67
- if (!allocation) {
68
- continue;
69
- }
70
- if (options.inPlace) {
71
- bins[i].x = allocation.x;
72
- bins[i].y = allocation.y;
73
- bins[i].id = allocation.id;
17
+ export default class ShelfPack {
18
+ /**
19
+ * @param {number} [w=64] Initial width of the sprite
20
+ * @param {number} [h=64] Initial width of the sprite
21
+ * @param {Object} [options]
22
+ * @param {boolean} [options.autoResize=false] If `true`, the sprite will automatically grow
23
+ */
24
+ constructor(w, h, options) {
25
+ options = options || {};
26
+ this.w = w || 64;
27
+ this.h = h || 64;
28
+ this.autoResize = !!options.autoResize;
29
+ this.shelves = [];
30
+ this.freebins = [];
31
+ this.stats = {};
32
+ this.bins = {};
33
+ this.maxId = 0;
34
+ }
35
+ /**
36
+ * Batch pack multiple bins into the sprite.
37
+ *
38
+ * @param {Object[]} bins Array of requested bins - each object should have `width`, `height` (or `w`, `h`) properties
39
+ * @param {Object} [options]
40
+ * @param {boolean} [options.inPlace=false] If `true`, the supplied bin objects will be updated inplace with `x` and `y` properties
41
+ * @returns {Bin[]} Array of allocated Bins - each Bin is an object with `id`, `x`, `y`, `w`, `h` properties
42
+ * @noto Mutate input bins
43
+ * @example
44
+ * var bins = [
45
+ * { id: 1, w: 12, h: 12 },
46
+ * { id: 2, w: 12, h: 16 },
47
+ * { id: 3, w: 12, h: 24 }
48
+ * ];
49
+ * var results = sprite.pack(bins, { inPlace: false });
50
+ */
51
+ pack(bins, options) {
52
+ bins = [].concat(bins);
53
+ options = options || {};
54
+ var results = [], w, h, id, allocation;
55
+ for (var i = 0; i < bins.length; i++) {
56
+ w = bins[i].w || bins[i].width;
57
+ h = bins[i].h || bins[i].height;
58
+ id = bins[i].id;
59
+ if (w && h) {
60
+ allocation = this.packOne(w, h, id);
61
+ if (!allocation) {
62
+ continue;
63
+ }
64
+ if (options.inPlace) {
65
+ bins[i].x = allocation.x;
66
+ bins[i].y = allocation.y;
67
+ bins[i].id = allocation.id;
68
+ }
69
+ results.push(allocation);
74
70
  }
75
- results.push(allocation);
76
71
  }
72
+ this.shrink();
73
+ return results;
77
74
  }
78
- this.shrink();
79
- return results;
80
- };
81
- /**
82
- * Pack a single bin into the sprite.
83
- *
84
- * Each bin will have a unique identitifer.
85
- * If no identifier is supplied in the `id` parameter, one will be created.
86
- * Note: The supplied `id` is used as an object index, so numeric values are fastest!
87
- *
88
- * Bins are automatically refcounted (i.e. a newly packed Bin will have a refcount of 1).
89
- * When a bin is no longer needed, use the `ShelfPack.unref` function to mark it
90
- * as unused. When a Bin's refcount decrements to 0, the Bin will be marked
91
- * as free and its space may be reused by the packing code.
92
- *
93
- * @param {number} w Width of the bin to allocate
94
- * @param {number} h Height of the bin to allocate
95
- * @param {number|string} [id] Unique identifier for this bin, (if unsupplied, assume it's a new bin and create an id)
96
- * @returns {Bin} Bin object with `id`, `x`, `y`, `w`, `h` properties, or `null` if allocation failed
97
- * @example
98
- * var results = sprite.packOne(12, 16, 'a');
99
- */
100
- ShelfPack.prototype.packOne = function (w, h, id) {
101
- var best = { freebin: -1, shelf: -1, waste: Infinity }, y = 0, bin, shelf, waste, i;
102
- // if id was supplied, attempt a lookup..
103
- if (typeof id === 'string' || typeof id === 'number') {
104
- bin = this.getBin(id);
105
- if (bin) { // we packed this bin already
106
- this.ref(bin);
107
- return bin;
75
+ /**
76
+ * Pack a single bin into the sprite.
77
+ *
78
+ * Each bin will have a unique identitifer.
79
+ * If no identifier is supplied in the `id` parameter, one will be created.
80
+ * Note: The supplied `id` is used as an object index, so numeric values are fastest!
81
+ *
82
+ * Bins are automatically refcounted (i.e. a newly packed Bin will have a refcount of 1).
83
+ * When a bin is no longer needed, use the `ShelfPack.unref` function to mark it
84
+ * as unused. When a Bin's refcount decrements to 0, the Bin will be marked
85
+ * as free and its space may be reused by the packing code.
86
+ *
87
+ * @param {number} w Width of the bin to allocate
88
+ * @param {number} h Height of the bin to allocate
89
+ * @param {number|string} [id] Unique identifier for this bin, (if unsupplied, assume it's a new bin and create an id)
90
+ * @returns {Bin} Bin object with `id`, `x`, `y`, `w`, `h` properties, or `null` if allocation failed
91
+ * @example
92
+ * var results = sprite.packOne(12, 16, 'a');
93
+ */
94
+ packOne(w, h, id) {
95
+ var best = { freebin: -1, shelf: -1, waste: Infinity }, y = 0, bin, shelf, waste, i;
96
+ // if id was supplied, attempt a lookup..
97
+ if (typeof id === 'string' || typeof id === 'number') {
98
+ bin = this.getBin(id);
99
+ if (bin) { // we packed this bin already
100
+ this.ref(bin);
101
+ return bin;
102
+ }
103
+ if (typeof id === 'number') {
104
+ this.maxId = Math.max(id, this.maxId);
105
+ }
108
106
  }
109
- if (typeof id === 'number') {
110
- this.maxId = Math.max(id, this.maxId);
107
+ else {
108
+ id = ++this.maxId;
111
109
  }
112
- }
113
- else {
114
- id = ++this.maxId;
115
- }
116
- // First try to reuse a free bin..
117
- for (i = 0; i < this.freebins.length; i++) {
118
- bin = this.freebins[i];
119
- // exactly the right height and width, use it..
120
- if (h === bin.maxh && w === bin.maxw) {
121
- return this.allocFreebin(i, w, h, id);
122
- }
123
- // not enough height or width, skip it..
124
- if (h > bin.maxh || w > bin.maxw) {
125
- continue;
110
+ // First try to reuse a free bin..
111
+ for (i = 0; i < this.freebins.length; i++) {
112
+ bin = this.freebins[i];
113
+ // exactly the right height and width, use it..
114
+ if (h === bin.maxh && w === bin.maxw) {
115
+ return this.allocFreebin(i, w, h, id);
116
+ }
117
+ // not enough height or width, skip it..
118
+ if (h > bin.maxh || w > bin.maxw) {
119
+ continue;
120
+ }
121
+ // extra height or width, minimize wasted area..
122
+ if (h <= bin.maxh && w <= bin.maxw) {
123
+ waste = (bin.maxw * bin.maxh) - (w * h);
124
+ if (waste < best.waste) {
125
+ best.waste = waste;
126
+ best.freebin = i;
127
+ }
128
+ }
126
129
  }
127
- // extra height or width, minimize wasted area..
128
- if (h <= bin.maxh && w <= bin.maxw) {
129
- waste = (bin.maxw * bin.maxh) - (w * h);
130
- if (waste < best.waste) {
131
- best.waste = waste;
132
- best.freebin = i;
130
+ // Next find the best shelf..
131
+ for (i = 0; i < this.shelves.length; i++) {
132
+ shelf = this.shelves[i];
133
+ y += shelf.h;
134
+ // not enough width on this shelf, skip it..
135
+ if (w > shelf.free) {
136
+ continue;
137
+ }
138
+ // exactly the right height, pack it..
139
+ if (h === shelf.h) {
140
+ return this.allocShelf(i, w, h, id);
141
+ }
142
+ // not enough height, skip it..
143
+ if (h > shelf.h) {
144
+ continue;
145
+ }
146
+ // extra height, minimize wasted area..
147
+ if (h < shelf.h) {
148
+ waste = (shelf.h - h) * w;
149
+ if (waste < best.waste) {
150
+ best.freebin = -1;
151
+ best.waste = waste;
152
+ best.shelf = i;
153
+ }
133
154
  }
134
155
  }
135
- }
136
- // Next find the best shelf..
137
- for (i = 0; i < this.shelves.length; i++) {
138
- shelf = this.shelves[i];
139
- y += shelf.h;
140
- // not enough width on this shelf, skip it..
141
- if (w > shelf.free) {
142
- continue;
156
+ if (best.freebin !== -1) {
157
+ return this.allocFreebin(best.freebin, w, h, id);
143
158
  }
144
- // exactly the right height, pack it..
145
- if (h === shelf.h) {
146
- return this.allocShelf(i, w, h, id);
159
+ if (best.shelf !== -1) {
160
+ return this.allocShelf(best.shelf, w, h, id);
147
161
  }
148
- // not enough height, skip it..
149
- if (h > shelf.h) {
150
- continue;
162
+ // No free bins or shelves.. add shelf..
163
+ if (h <= (this.h - y) && w <= this.w) {
164
+ shelf = new Shelf(y, this.w, h);
165
+ return this.allocShelf(this.shelves.push(shelf) - 1, w, h, id);
151
166
  }
152
- // extra height, minimize wasted area..
153
- if (h < shelf.h) {
154
- waste = (shelf.h - h) * w;
155
- if (waste < best.waste) {
156
- best.freebin = -1;
157
- best.waste = waste;
158
- best.shelf = i;
167
+ // No room for more shelves..
168
+ // If `autoResize` option is set, grow the sprite as follows:
169
+ // * double whichever sprite dimension is smaller (`w1` or `h1`)
170
+ // * if sprite dimensions are equal, grow width before height
171
+ // * accomodate very large bin requests (big `w` or `h`)
172
+ if (this.autoResize) {
173
+ var h1, h2, w1, w2;
174
+ h1 = h2 = this.h;
175
+ w1 = w2 = this.w;
176
+ if (w1 <= h1 || w > w1) { // grow width..
177
+ w2 = Math.max(w, w1) * 2;
159
178
  }
179
+ if (h1 < w1 || h > h1) { // grow height..
180
+ h2 = Math.max(h, h1) * 2;
181
+ }
182
+ this.resize(w2, h2);
183
+ return this.packOne(w, h, id); // retry
160
184
  }
185
+ return null;
161
186
  }
162
- if (best.freebin !== -1) {
163
- return this.allocFreebin(best.freebin, w, h, id);
164
- }
165
- if (best.shelf !== -1) {
166
- return this.allocShelf(best.shelf, w, h, id);
187
+ /**
188
+ * Called by packOne() to allocate a bin by reusing an existing freebin
189
+ *
190
+ * @private
191
+ * @param {number} index Index into the `this.freebins` array
192
+ * @param {number} w Width of the bin to allocate
193
+ * @param {number} h Height of the bin to allocate
194
+ * @param {number|string} id Unique identifier for this bin
195
+ * @returns {Bin} Bin object with `id`, `x`, `y`, `w`, `h` properties
196
+ * @example
197
+ * var bin = sprite.allocFreebin(0, 12, 16, 'a');
198
+ */
199
+ allocFreebin(index, w, h, id) {
200
+ var bin = this.freebins.splice(index, 1)[0];
201
+ bin.id = id;
202
+ bin.w = w;
203
+ bin.h = h;
204
+ bin.refcount = 0;
205
+ this.bins[id] = bin;
206
+ this.ref(bin);
207
+ return bin;
167
208
  }
168
- // No free bins or shelves.. add shelf..
169
- if (h <= (this.h - y) && w <= this.w) {
170
- shelf = new Shelf(y, this.w, h);
171
- return this.allocShelf(this.shelves.push(shelf) - 1, w, h, id);
209
+ /**
210
+ * Called by `packOne() to allocate bin on an existing shelf
211
+ *
212
+ * @private
213
+ * @param {number} index Index into the `this.shelves` array
214
+ * @param {number} w Width of the bin to allocate
215
+ * @param {number} h Height of the bin to allocate
216
+ * @param {number|string} id Unique identifier for this bin
217
+ * @returns {Bin} Bin object with `id`, `x`, `y`, `w`, `h` properties
218
+ * @example
219
+ * var results = sprite.allocShelf(0, 12, 16, 'a');
220
+ */
221
+ allocShelf(index, w, h, id) {
222
+ var shelf = this.shelves[index];
223
+ var bin = shelf.alloc(w, h, id);
224
+ this.bins[id] = bin;
225
+ this.ref(bin);
226
+ return bin;
172
227
  }
173
- // No room for more shelves..
174
- // If `autoResize` option is set, grow the sprite as follows:
175
- // * double whichever sprite dimension is smaller (`w1` or `h1`)
176
- // * if sprite dimensions are equal, grow width before height
177
- // * accomodate very large bin requests (big `w` or `h`)
178
- if (this.autoResize) {
179
- var h1, h2, w1, w2;
180
- h1 = h2 = this.h;
181
- w1 = w2 = this.w;
182
- if (w1 <= h1 || w > w1) { // grow width..
183
- w2 = Math.max(w, w1) * 2;
184
- }
185
- if (h1 < w1 || h > h1) { // grow height..
186
- h2 = Math.max(h, h1) * 2;
228
+ /**
229
+ * Shrink the width/height of the sprite to the bare minimum.
230
+ * Since shelf-pack doubles first width, then height when running out of shelf space
231
+ * this can result in fairly large unused space both in width and height if that happens
232
+ * towards the end of bin packing.
233
+ */
234
+ shrink() {
235
+ if (this.shelves.length > 0) {
236
+ var w2 = 0;
237
+ var h2 = 0;
238
+ for (var j = 0; j < this.shelves.length; j++) {
239
+ var shelf = this.shelves[j];
240
+ h2 += shelf.h;
241
+ w2 = Math.max(shelf.w - shelf.free, w2);
242
+ }
243
+ this.resize(w2, h2);
187
244
  }
188
- this.resize(w2, h2);
189
- return this.packOne(w, h, id); // retry
190
245
  }
191
- return null;
192
- };
193
- /**
194
- * Called by packOne() to allocate a bin by reusing an existing freebin
195
- *
196
- * @private
197
- * @param {number} index Index into the `this.freebins` array
198
- * @param {number} w Width of the bin to allocate
199
- * @param {number} h Height of the bin to allocate
200
- * @param {number|string} id Unique identifier for this bin
201
- * @returns {Bin} Bin object with `id`, `x`, `y`, `w`, `h` properties
202
- * @example
203
- * var bin = sprite.allocFreebin(0, 12, 16, 'a');
204
- */
205
- ShelfPack.prototype.allocFreebin = function (index, w, h, id) {
206
- var bin = this.freebins.splice(index, 1)[0];
207
- bin.id = id;
208
- bin.w = w;
209
- bin.h = h;
210
- bin.refcount = 0;
211
- this.bins[id] = bin;
212
- this.ref(bin);
213
- return bin;
214
- };
215
- /**
216
- * Called by `packOne() to allocate bin on an existing shelf
217
- *
218
- * @private
219
- * @param {number} index Index into the `this.shelves` array
220
- * @param {number} w Width of the bin to allocate
221
- * @param {number} h Height of the bin to allocate
222
- * @param {number|string} id Unique identifier for this bin
223
- * @returns {Bin} Bin object with `id`, `x`, `y`, `w`, `h` properties
224
- * @example
225
- * var results = sprite.allocShelf(0, 12, 16, 'a');
226
- */
227
- ShelfPack.prototype.allocShelf = function (index, w, h, id) {
228
- var shelf = this.shelves[index];
229
- var bin = shelf.alloc(w, h, id);
230
- this.bins[id] = bin;
231
- this.ref(bin);
232
- return bin;
233
- };
234
- /**
235
- * Shrink the width/height of the sprite to the bare minimum.
236
- * Since shelf-pack doubles first width, then height when running out of shelf space
237
- * this can result in fairly large unused space both in width and height if that happens
238
- * towards the end of bin packing.
239
- */
240
- ShelfPack.prototype.shrink = function () {
241
- if (this.shelves.length > 0) {
242
- var w2 = 0;
243
- var h2 = 0;
244
- for (var j = 0; j < this.shelves.length; j++) {
245
- var shelf = this.shelves[j];
246
- h2 += shelf.h;
247
- w2 = Math.max(shelf.w - shelf.free, w2);
248
- }
249
- this.resize(w2, h2);
246
+ /**
247
+ * Return a packed bin given its id, or undefined if the id is not found
248
+ *
249
+ * @param {number|string} id Unique identifier for this bin,
250
+ * @returns {Bin} The requested bin, or undefined if not yet packed
251
+ * @example
252
+ * var b = sprite.getBin('a');
253
+ */
254
+ getBin(id) {
255
+ return this.bins[id];
250
256
  }
251
- };
252
- /**
253
- * Return a packed bin given its id, or undefined if the id is not found
254
- *
255
- * @param {number|string} id Unique identifier for this bin,
256
- * @returns {Bin} The requested bin, or undefined if not yet packed
257
- * @example
258
- * var b = sprite.getBin('a');
259
- */
260
- ShelfPack.prototype.getBin = function (id) {
261
- return this.bins[id];
262
- };
263
- /**
264
- * Increment the ref count of a bin and update statistics.
265
- *
266
- * @param {Bin} bin Bin instance
267
- * @returns {number} New refcount of the bin
268
- * @example
269
- * var bin = sprite.getBin('a');
270
- * sprite.ref(bin);
271
- */
272
- ShelfPack.prototype.ref = function (bin) {
273
- if (++bin.refcount === 1) { // a new Bin.. record height in stats historgram..
274
- var h = bin.h;
275
- this.stats[h] = (this.stats[h] | 0) + 1;
257
+ /**
258
+ * Increment the ref count of a bin and update statistics.
259
+ *
260
+ * @param {Bin} bin Bin instance
261
+ * @returns {number} New refcount of the bin
262
+ * @example
263
+ * var bin = sprite.getBin('a');
264
+ * sprite.ref(bin);
265
+ */
266
+ ref(bin) {
267
+ if (++bin.refcount === 1) { // a new Bin.. record height in stats historgram..
268
+ var h = bin.h;
269
+ this.stats[h] = (this.stats[h] | 0) + 1;
270
+ }
271
+ return bin.refcount;
276
272
  }
277
- return bin.refcount;
278
- };
279
- /**
280
- * Decrement the ref count of a bin and update statistics.
281
- * The bin will be automatically marked as free space once the refcount reaches 0.
282
- *
283
- * @param {Bin} bin Bin instance
284
- * @returns {number} New refcount of the bin
285
- * @example
286
- * var bin = sprite.getBin('a');
287
- * sprite.unref(bin);
288
- */
289
- ShelfPack.prototype.unref = function (bin) {
290
- if (bin.refcount === 0) {
291
- return 0;
273
+ /**
274
+ * Decrement the ref count of a bin and update statistics.
275
+ * The bin will be automatically marked as free space once the refcount reaches 0.
276
+ *
277
+ * @param {Bin} bin Bin instance
278
+ * @returns {number} New refcount of the bin
279
+ * @example
280
+ * var bin = sprite.getBin('a');
281
+ * sprite.unref(bin);
282
+ */
283
+ unref(bin) {
284
+ if (bin.refcount === 0) {
285
+ return 0;
286
+ }
287
+ if (--bin.refcount === 0) {
288
+ this.stats[bin.h]--;
289
+ delete this.bins[bin.id];
290
+ this.freebins.push(bin);
291
+ }
292
+ return bin.refcount;
292
293
  }
293
- if (--bin.refcount === 0) {
294
- this.stats[bin.h]--;
295
- delete this.bins[bin.id];
296
- this.freebins.push(bin);
294
+ /**
295
+ * Clear the sprite. Resets everything and resets statistics.
296
+ *
297
+ * @example
298
+ * sprite.clear();
299
+ */
300
+ clear() {
301
+ this.shelves = [];
302
+ this.freebins = [];
303
+ this.stats = {};
304
+ this.bins = {};
305
+ this.maxId = 0;
297
306
  }
298
- return bin.refcount;
299
- };
300
- /**
301
- * Clear the sprite. Resets everything and resets statistics.
302
- *
303
- * @example
304
- * sprite.clear();
305
- */
306
- ShelfPack.prototype.clear = function () {
307
- this.shelves = [];
308
- this.freebins = [];
309
- this.stats = {};
310
- this.bins = {};
311
- this.maxId = 0;
312
- };
313
- /**
314
- * Resize the sprite.
315
- *
316
- * @param {number} w Requested new sprite width
317
- * @param {number} h Requested new sprite height
318
- * @returns {boolean} `true` if resize succeeded, `false` if failed
319
- * @example
320
- * sprite.resize(256, 256);
321
- */
322
- ShelfPack.prototype.resize = function (w, h) {
323
- this.w = w;
324
- this.h = h;
325
- for (var i = 0; i < this.shelves.length; i++) {
326
- this.shelves[i].resize(w);
307
+ /**
308
+ * Resize the sprite.
309
+ *
310
+ * @param {number} w Requested new sprite width
311
+ * @param {number} h Requested new sprite height
312
+ * @returns {boolean} `true` if resize succeeded, `false` if failed
313
+ * @example
314
+ * sprite.resize(256, 256);
315
+ */
316
+ resize(w, h) {
317
+ this.w = w;
318
+ this.h = h;
319
+ for (var i = 0; i < this.shelves.length; i++) {
320
+ this.shelves[i].resize(w);
321
+ }
322
+ return true;
327
323
  }
328
- return true;
329
- };
324
+ }
330
325
  /**
331
326
  * Create a new Shelf.
332
327
  *
333
328
  * @private
334
- * @class Shelf
335
- * @param {number} y Top coordinate of the new shelf
336
- * @param {number} w Width of the new shelf
337
- * @param {number} h Height of the new shelf
338
329
  * @example
339
330
  * var shelf = new Shelf(64, 512, 24);
340
331
  */
341
- function Shelf(y, w, h) {
342
- this.x = 0;
343
- this.y = y;
344
- this.w = this.free = w;
345
- this.h = h;
346
- }
347
- /**
348
- * Allocate a single bin into the shelf.
349
- *
350
- * @private
351
- * @param {number} w Width of the bin to allocate
352
- * @param {number} h Height of the bin to allocate
353
- * @param {number|string} id Unique id of the bin to allocate
354
- * @returns {Bin} Bin object with `id`, `x`, `y`, `w`, `h` properties, or `null` if allocation failed
355
- * @example
356
- * shelf.alloc(12, 16, 'a');
357
- */
358
- Shelf.prototype.alloc = function (w, h, id) {
359
- if (w > this.free || h > this.h) {
360
- return null;
332
+ class Shelf {
333
+ /**
334
+ * @param {number} y Top coordinate of the new shelf
335
+ * @param {number} w Width of the new shelf
336
+ * @param {number} h Height of the new shelf
337
+ */
338
+ constructor(y, w, h) {
339
+ this.x = 0;
340
+ this.y = y;
341
+ this.w = this.free = w;
342
+ this.h = h;
361
343
  }
362
- var x = this.x;
363
- this.x += w;
364
- this.free -= w;
365
- return new Bin(id, x, this.y, w, h, w, this.h);
366
- };
367
- /**
368
- * Resize the shelf.
369
- *
370
- * @private
371
- * @param {number} w Requested new width of the shelf
372
- * @returns {boolean} true
373
- * @example
374
- * shelf.resize(512);
375
- */
376
- Shelf.prototype.resize = function (w) {
377
- this.free += (w - this.w);
378
- this.w = w;
379
- return true;
380
- };
344
+ /**
345
+ * Allocate a single bin into the shelf.
346
+ *
347
+ * @private
348
+ * @param {number} w Width of the bin to allocate
349
+ * @param {number} h Height of the bin to allocate
350
+ * @param {number|string} id Unique id of the bin to allocate
351
+ * @returns {Bin} Bin object with `id`, `x`, `y`, `w`, `h` properties, or `null` if allocation failed
352
+ * @example
353
+ * shelf.alloc(12, 16, 'a');
354
+ */
355
+ alloc(w, h, id) {
356
+ if (w > this.free || h > this.h) {
357
+ return null;
358
+ }
359
+ var x = this.x;
360
+ this.x += w;
361
+ this.free -= w;
362
+ return new Bin(id, x, this.y, w, h, w, this.h);
363
+ }
364
+ /**
365
+ * Resize the shelf.
366
+ *
367
+ * @private
368
+ * @param {number} w Requested new width of the shelf
369
+ * @returns {boolean} true
370
+ * @example
371
+ * shelf.resize(512);
372
+ */
373
+ resize(w) {
374
+ this.free += (w - this.w);
375
+ this.w = w;
376
+ return true;
377
+ }
378
+ }
381
379
  /**
382
380
  * Create a new Bin object.
383
381
  *
384
- * @class Bin
385
- * @param {number|string} id Unique id of the bin
386
- * @param {number} x Left coordinate of the bin
387
- * @param {number} y Top coordinate of the bin
388
- * @param {number} w Width of the bin
389
- * @param {number} h Height of the bin
390
- * @param {number} [maxw] Max width of the bin (defaults to `w` if not provided)
391
- * @param {number} [maxh] Max height of the bin (defaults to `h` if not provided)
392
382
  * @example
393
383
  * var bin = new Bin('a', 0, 0, 12, 16);
394
384
  */
395
- function Bin(id, x, y, w, h, maxw, maxh) {
396
- this.id = id;
397
- this.x = x;
398
- this.y = y;
399
- this.w = w;
400
- this.h = h;
401
- this.maxw = maxw || w;
402
- this.maxh = maxh || h;
403
- this.refcount = 0;
385
+ export class Bin {
386
+ /**
387
+ * @param {number|string} id Unique id of the bin
388
+ * @param {number} x Left coordinate of the bin
389
+ * @param {number} y Top coordinate of the bin
390
+ * @param {number} w Width of the bin
391
+ * @param {number} h Height of the bin
392
+ * @param {number} [maxw] Max width of the bin (defaults to `w` if not provided)
393
+ * @param {number} [maxh] Max height of the bin (defaults to `h` if not provided)
394
+ */
395
+ constructor(id, x, y, w, h, maxw, maxh) {
396
+ this.id = id;
397
+ this.x = x;
398
+ this.y = y;
399
+ this.w = w;
400
+ this.h = h;
401
+ this.maxw = maxw || w;
402
+ this.maxh = maxh || h;
403
+ this.refcount = 0;
404
+ }
404
405
  }
405
406
  //# sourceMappingURL=index.js.map