@pictogrammers/components 0.5.24 → 0.5.25

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pictogrammers/components",
3
3
  "type": "module",
4
- "version": "0.5.24",
4
+ "version": "0.5.25",
5
5
  "license": "MIT",
6
6
  "author": "Austin Andrews",
7
7
  "scripts": {
@@ -305,29 +305,46 @@ export default class PgInputPixelEditor extends HTMLElement {
305
305
  }
306
306
 
307
307
  /**
308
- * Clip a cached grid so its dimensions never exceed the current
309
- * width/height. Used when the canvas is made smaller.
310
- * @param grid 2d grid to clip in place
308
+ * Grow or clip a cached grid in place so it is exactly width x height.
309
+ * New rows/cells are filled with 0. Each grid is resized independently
310
+ * so multi-layer grids never drift out of sync with each other (a prior
311
+ * version resized `#export`/`#selection`/`#selectionPreview` once per
312
+ * layer instead of once per grid, and used a single layer's length to
313
+ * decide whether other layers needed growing, which could leave a layer
314
+ * short and let #redraw read past its real length).
315
+ * @param grid 2d grid to resize in place
316
+ * @param width target width
317
+ * @param height target height
311
318
  */
312
- #clipGrid(grid: number[][]) {
313
- if (grid.length > this.height) {
314
- grid.length = this.height;
319
+ #resizeGrid(grid: number[][], width: number, height: number) {
320
+ if (grid.length > height) {
321
+ grid.length = height;
315
322
  }
316
- for (let y = 0; y < grid.length; y++) {
317
- if (grid[y].length > this.width) {
318
- grid[y].length = this.width;
323
+ for (let y = 0; y < height; y++) {
324
+ if (!grid[y]) {
325
+ grid[y] = new Array(width).fill(0);
326
+ continue;
327
+ }
328
+ if (grid[y].length > width) {
329
+ grid[y].length = width;
330
+ } else {
331
+ for (let x = grid[y].length; x < width; x++) {
332
+ grid[y].push(0);
333
+ }
319
334
  }
320
335
  }
321
336
  }
322
337
 
323
338
  #redraw() {
324
- // When the canvas shrinks, clip the cached grids so stale rows/columns
325
- // outside the new bounds are dropped (the grow case is handled below).
326
- this.#clipGrid(this.#export);
327
- this.#clipGrid(this.#selection);
328
- this.#clipGrid(this.#selectionPreview);
339
+ // Resize every cached grid to the current width/height so stale
340
+ // rows/columns are dropped when shrinking and missing rows/columns are
341
+ // backfilled with 0 when growing, before anything reads from them.
342
+ this.#data.forEach((layer) => this.#resizeGrid(layer, this.width, this.height));
343
+ this.#resizeGrid(this.#export, this.width, this.height);
344
+ this.#resizeGrid(this.#selection, this.width, this.height);
345
+ this.#resizeGrid(this.#selectionPreview, this.width, this.height);
329
346
  // Drop selection pixels that now fall outside the canvas so the
330
- // selection map stays in sync with the clipped #selection grid.
347
+ // selection map stays in sync with the resized #selection grid.
331
348
  this.#selectionPixels.forEach(([x, y], key) => {
332
349
  if (x >= this.width || y >= this.height) {
333
350
  this.#selectionPixels.delete(key);
@@ -337,30 +354,12 @@ export default class PgInputPixelEditor extends HTMLElement {
337
354
  this.$selectionPath.classList.toggle('hide', true);
338
355
  }
339
356
 
340
- // Render individual pixels
341
- const data = this.#data.toReversed();
342
- const layerCount = data.length;
357
+ // Render individual pixels, topmost non-transparent layer wins
343
358
  for (let y = 0; y < this.height; y++) {
344
- if (y >= data[0].length) {
345
- for (let l = 0; l < layerCount; l++) {
346
- data[l].push(new Array(this.width).fill(0));
347
- this.#export.push(new Array(this.width).fill(0));
348
- this.#selection.push(new Array(this.width).fill(0));
349
- this.#selectionPreview.push(new Array(this.width).fill(0));
350
- }
351
- }
352
359
  for (let x = 0; x < this.width; x++) {
353
- if (x >= data[0][y].length) {
354
- for (let l = 0; l < layerCount; l++) {
355
- data[l][y].push(0);
356
- this.#export[y].push(0);
357
- this.#selection[y].push(0);
358
- this.#selectionPreview[y].push(0);
359
- }
360
- }
361
- for (let l = 0; l < layerCount; l++) {
362
- if (data[l][y][x] !== 0) {
363
- this.#setPixel(x, y, data[l][y][x]);
360
+ for (let l = this.#data.length - 1; l >= 0; l--) {
361
+ if (this.#data[l][y][x] !== 0) {
362
+ this.#setPixel(x, y, this.#data[l][y][x], [l]);
364
363
  break;
365
364
  }
366
365
  }