@flighthq/tileset 0.1.0 → 0.2.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/tileset.d.ts +1 -0
- package/dist/tileset.d.ts.map +1 -1
- package/dist/tileset.js +24 -4
- package/dist/tileset.js.map +1 -1
- package/dist/tilesetFrom.d.ts +4 -4
- package/dist/tilesetFrom.d.ts.map +1 -1
- package/dist/tilesetFrom.js +8 -8
- package/dist/tilesetFrom.js.map +1 -1
- package/package.json +10 -5
- package/src/tileset.test.ts +77 -2
- package/src/tilesetFrom.test.ts +28 -0
package/dist/tileset.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Tileset } from '@flighthq/types';
|
|
2
2
|
export declare function buildTilesetRegions(target: Tileset): void;
|
|
3
3
|
export declare function createTileset(obj?: Partial<Tileset>): Tileset;
|
|
4
|
+
export declare function disposeTileset(tileset: Tileset): void;
|
|
4
5
|
//# sourceMappingURL=tileset.d.ts.map
|
package/dist/tileset.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tileset.d.ts","sourceRoot":"","sources":["../src/tileset.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"tileset.d.ts","sourceRoot":"","sources":["../src/tileset.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAS/C,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAqBzD;AAED,wBAAgB,aAAa,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAU7D;AAOD,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAErD"}
|
package/dist/tileset.js
CHANGED
|
@@ -3,19 +3,31 @@ import { createTextureAtlasRegion, setTextureAtlasRegion } from '@flighthq/textu
|
|
|
3
3
|
// Fills or refreshes the atlas region array with one region per tile in the grid, using the
|
|
4
4
|
// tileset's tileWidth/tileHeight, margin (border padding), and spacing (inter-tile gap).
|
|
5
5
|
// Existing region objects are reused in place when the capacity matches — zero new allocations
|
|
6
|
-
// for repeated calls on an already-populated tileset.
|
|
6
|
+
// for repeated calls on an already-populated tileset. When the grid shrinks, trailing regions
|
|
7
|
+
// beyond the new tile count are truncated so no stale regions linger. Each region's `id` is its
|
|
8
|
+
// tile index (row-major), and reused regions have their `name`/`rotated`/`trimmed` metadata reset
|
|
9
|
+
// so `getTextureAtlasRegionById` and friends see a clean grid, not leftovers from a prior build.
|
|
7
10
|
export function buildTilesetRegions(target) {
|
|
8
11
|
const { atlas, rows, columns, tileWidth, tileHeight, margin, spacing } = target;
|
|
9
12
|
if (atlas === null)
|
|
10
13
|
return;
|
|
14
|
+
const regions = atlas.regions;
|
|
15
|
+
const count = rows * columns;
|
|
16
|
+
if (regions.length > count)
|
|
17
|
+
regions.length = count;
|
|
11
18
|
let i = 0;
|
|
12
19
|
for (let row = 0; row < rows; row++) {
|
|
13
20
|
for (let column = 0; column < columns; column++) {
|
|
14
|
-
if (i >=
|
|
15
|
-
|
|
21
|
+
if (i >= regions.length)
|
|
22
|
+
regions.push(createTextureAtlasRegion());
|
|
23
|
+
const region = regions[i];
|
|
16
24
|
const x = margin + column * (tileWidth + spacing);
|
|
17
25
|
const y = margin + row * (tileHeight + spacing);
|
|
18
|
-
setTextureAtlasRegion(
|
|
26
|
+
setTextureAtlasRegion(region, x, y, tileWidth, tileHeight);
|
|
27
|
+
region.id = i;
|
|
28
|
+
region.name = null;
|
|
29
|
+
region.rotated = false;
|
|
30
|
+
region.trimmed = false;
|
|
19
31
|
i++;
|
|
20
32
|
}
|
|
21
33
|
}
|
|
@@ -31,4 +43,12 @@ export function createTileset(obj) {
|
|
|
31
43
|
tileWidth: obj?.tileWidth ?? 0,
|
|
32
44
|
});
|
|
33
45
|
}
|
|
46
|
+
// Releases what keeps the tileset reachable — the atlas reference — so the atlas (and its image)
|
|
47
|
+
// become eligible for GC once nothing else holds them. The tileset is plain GC-managed memory with
|
|
48
|
+
// no non-GC resource to free, so this is `dispose`, not `destroy`; the grid parameters
|
|
49
|
+
// (rows/columns/tile size) are left intact. Does not clear the atlas's regions: the atlas is a
|
|
50
|
+
// separate entity a caller may still hold, so its contents are not this tileset's to erase.
|
|
51
|
+
export function disposeTileset(tileset) {
|
|
52
|
+
tileset.atlas = null;
|
|
53
|
+
}
|
|
34
54
|
//# sourceMappingURL=tileset.js.map
|
package/dist/tileset.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tileset.js","sourceRoot":"","sources":["../src/tileset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAGzF,4FAA4F;AAC5F,yFAAyF;AACzF,+FAA+F;AAC/F,
|
|
1
|
+
{"version":3,"file":"tileset.js","sourceRoot":"","sources":["../src/tileset.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAGzF,4FAA4F;AAC5F,yFAAyF;AACzF,+FAA+F;AAC/F,8FAA8F;AAC9F,gGAAgG;AAChG,kGAAkG;AAClG,iGAAiG;AACjG,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;IAChF,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO;IAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC;IAC9B,MAAM,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,GAAG,KAAK;QAAE,OAAO,CAAC,MAAM,GAAG,KAAK,CAAC;IACnD,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,EAAE,EAAE,CAAC;QACpC,KAAK,IAAI,MAAM,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC;YAChD,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM;gBAAE,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,CAAC,CAAC;YAClE,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,CAAC,GAAG,MAAM,GAAG,MAAM,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,CAAC;YAClD,MAAM,CAAC,GAAG,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC;YAChD,qBAAqB,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;YAC3D,MAAM,CAAC,EAAE,GAAG,CAAC,CAAC;YACd,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;YACnB,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;YACvB,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;YACvB,CAAC,EAAE,CAAC;QACN,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAsB;IAClD,OAAO,YAAY,CAAC;QAClB,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,IAAI;QACzB,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,CAAC;QAC1B,MAAM,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC;QACxB,IAAI,EAAE,GAAG,EAAE,IAAI,IAAI,CAAC;QACpB,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,CAAC;QAC1B,UAAU,EAAE,GAAG,EAAE,UAAU,IAAI,CAAC;QAChC,SAAS,EAAE,GAAG,EAAE,SAAS,IAAI,CAAC;KAC/B,CAAC,CAAC;AACL,CAAC;AAED,iGAAiG;AACjG,mGAAmG;AACnG,uFAAuF;AACvF,+FAA+F;AAC/F,4FAA4F;AAC5F,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;AACvB,CAAC"}
|
package/dist/tilesetFrom.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ImageResource, TextureAtlas, Tileset } from '@flighthq/types';
|
|
2
2
|
export declare function createTilesetFromAtlas(atlas: TextureAtlas, tileWidth: number, tileHeight: number, margin?: number, spacing?: number): Tileset;
|
|
3
3
|
export declare function createTilesetFromImageResource(resource: ImageResource, tileWidth: number, tileHeight: number, margin?: number, spacing?: number): Tileset;
|
|
4
|
-
export declare function loadTilesetFromBase64(base64: string, mimeType: string, tileWidth: number, tileHeight: number, signal?: AbortSignal): Promise<Tileset>;
|
|
5
|
-
export declare function loadTilesetFromBlob(blob: Blob, tileWidth: number, tileHeight: number, signal?: AbortSignal): Promise<Tileset>;
|
|
6
|
-
export declare function loadTilesetFromBytes(bytes: Uint8Array, tileWidth: number, tileHeight: number, mimeType?: string, signal?: AbortSignal): Promise<Tileset>;
|
|
7
|
-
export declare function loadTilesetFromUrl(url: string, tileWidth: number, tileHeight: number, crossOrigin?: string, signal?: AbortSignal): Promise<Tileset>;
|
|
4
|
+
export declare function loadTilesetFromBase64(base64: string, mimeType: string, tileWidth: number, tileHeight: number, margin?: number, spacing?: number, signal?: AbortSignal): Promise<Tileset>;
|
|
5
|
+
export declare function loadTilesetFromBlob(blob: Blob, tileWidth: number, tileHeight: number, margin?: number, spacing?: number, signal?: AbortSignal): Promise<Tileset>;
|
|
6
|
+
export declare function loadTilesetFromBytes(bytes: Uint8Array, tileWidth: number, tileHeight: number, margin?: number, spacing?: number, mimeType?: string, signal?: AbortSignal): Promise<Tileset>;
|
|
7
|
+
export declare function loadTilesetFromUrl(url: string, tileWidth: number, tileHeight: number, margin?: number, spacing?: number, crossOrigin?: string, signal?: AbortSignal): Promise<Tileset>;
|
|
8
8
|
//# sourceMappingURL=tilesetFrom.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tilesetFrom.d.ts","sourceRoot":"","sources":["../src/tilesetFrom.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAO5E,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAU,EAClB,OAAO,GAAE,MAAU,GAClB,OAAO,CAST;AAED,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAU,EAClB,OAAO,GAAE,MAAU,GAClB,OAAO,CAET;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"tilesetFrom.d.ts","sourceRoot":"","sources":["../src/tilesetFrom.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAO5E,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAU,EAClB,OAAO,GAAE,MAAU,GAClB,OAAO,CAST;AAED,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAU,EAClB,OAAO,GAAE,MAAU,GAClB,OAAO,CAET;AAED,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAU,EAClB,OAAO,GAAE,MAAU,EACnB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAU,EAClB,OAAO,GAAE,MAAU,EACnB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAU,EAClB,OAAO,GAAE,MAAU,EACnB,QAAQ,CAAC,EAAE,MAAM,EACjB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAU,EAClB,OAAO,GAAE,MAAU,EACnB,WAAW,CAAC,EAAE,MAAM,EACpB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,OAAO,CAAC,CAQlB"}
|
package/dist/tilesetFrom.js
CHANGED
|
@@ -15,16 +15,16 @@ export function createTilesetFromAtlas(atlas, tileWidth, tileHeight, margin = 0,
|
|
|
15
15
|
export function createTilesetFromImageResource(resource, tileWidth, tileHeight, margin = 0, spacing = 0) {
|
|
16
16
|
return createTilesetFromAtlas(createTextureAtlas({ image: resource }), tileWidth, tileHeight, margin, spacing);
|
|
17
17
|
}
|
|
18
|
-
export async function loadTilesetFromBase64(base64, mimeType, tileWidth, tileHeight, signal) {
|
|
19
|
-
return createTilesetFromImageResource(await loadImageResourceFromBase64(base64, mimeType, signal), tileWidth, tileHeight);
|
|
18
|
+
export async function loadTilesetFromBase64(base64, mimeType, tileWidth, tileHeight, margin = 0, spacing = 0, signal) {
|
|
19
|
+
return createTilesetFromImageResource(await loadImageResourceFromBase64(base64, mimeType, signal), tileWidth, tileHeight, margin, spacing);
|
|
20
20
|
}
|
|
21
|
-
export async function loadTilesetFromBlob(blob, tileWidth, tileHeight, signal) {
|
|
22
|
-
return createTilesetFromImageResource(await loadImageResourceFromBlob(blob, signal), tileWidth, tileHeight);
|
|
21
|
+
export async function loadTilesetFromBlob(blob, tileWidth, tileHeight, margin = 0, spacing = 0, signal) {
|
|
22
|
+
return createTilesetFromImageResource(await loadImageResourceFromBlob(blob, signal), tileWidth, tileHeight, margin, spacing);
|
|
23
23
|
}
|
|
24
|
-
export async function loadTilesetFromBytes(bytes, tileWidth, tileHeight, mimeType, signal) {
|
|
25
|
-
return createTilesetFromImageResource(await loadImageResourceFromBytes(bytes, mimeType, signal), tileWidth, tileHeight);
|
|
24
|
+
export async function loadTilesetFromBytes(bytes, tileWidth, tileHeight, margin = 0, spacing = 0, mimeType, signal) {
|
|
25
|
+
return createTilesetFromImageResource(await loadImageResourceFromBytes(bytes, mimeType, signal), tileWidth, tileHeight, margin, spacing);
|
|
26
26
|
}
|
|
27
|
-
export async function loadTilesetFromUrl(url, tileWidth, tileHeight, crossOrigin, signal) {
|
|
28
|
-
return createTilesetFromImageResource(await loadImageResourceFromUrl(url, crossOrigin, signal), tileWidth, tileHeight);
|
|
27
|
+
export async function loadTilesetFromUrl(url, tileWidth, tileHeight, margin = 0, spacing = 0, crossOrigin, signal) {
|
|
28
|
+
return createTilesetFromImageResource(await loadImageResourceFromUrl(url, crossOrigin, signal), tileWidth, tileHeight, margin, spacing);
|
|
29
29
|
}
|
|
30
30
|
//# sourceMappingURL=tilesetFrom.js.map
|
package/dist/tilesetFrom.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tilesetFrom.js","sourceRoot":"","sources":["../src/tilesetFrom.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,yBAAyB,EACzB,0BAA0B,EAC1B,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAG5D,OAAO,EAAE,mBAAmB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/D,0FAA0F;AAC1F,wFAAwF;AACxF,wEAAwE;AACxE,MAAM,UAAU,sBAAsB,CACpC,KAAmB,EACnB,SAAiB,EACjB,UAAkB,EAClB,SAAiB,CAAC,EAClB,UAAkB,CAAC;IAEnB,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1B,MAAM,OAAO,GACX,KAAK,KAAK,IAAI,IAAI,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjH,MAAM,IAAI,GACR,KAAK,KAAK,IAAI,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpH,MAAM,OAAO,GAAG,aAAa,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;IAChG,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,8BAA8B,CAC5C,QAAuB,EACvB,SAAiB,EACjB,UAAkB,EAClB,SAAiB,CAAC,EAClB,UAAkB,CAAC;IAEnB,OAAO,sBAAsB,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AACjH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAc,EACd,QAAgB,EAChB,SAAiB,EACjB,UAAkB,EAClB,MAAoB;IAEpB,OAAO,8BAA8B,CACnC,MAAM,2BAA2B,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,EAC3D,SAAS,EACT,UAAU,
|
|
1
|
+
{"version":3,"file":"tilesetFrom.js","sourceRoot":"","sources":["../src/tilesetFrom.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/tileset",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "https://github.com/flighthq/flight.git",
|
|
7
|
+
"directory": "packages/tileset"
|
|
8
|
+
},
|
|
4
9
|
"type": "module",
|
|
5
10
|
"main": "dist/index.js",
|
|
6
11
|
"types": "dist/index.d.ts",
|
|
@@ -27,10 +32,10 @@
|
|
|
27
32
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
28
33
|
},
|
|
29
34
|
"dependencies": {
|
|
30
|
-
"@flighthq/entity": "0.
|
|
31
|
-
"@flighthq/image": "0.
|
|
32
|
-
"@flighthq/textureatlas": "0.
|
|
33
|
-
"@flighthq/types": "0.
|
|
35
|
+
"@flighthq/entity": "0.2.0",
|
|
36
|
+
"@flighthq/image": "0.2.0",
|
|
37
|
+
"@flighthq/textureatlas": "0.2.0",
|
|
38
|
+
"@flighthq/types": "0.2.0"
|
|
34
39
|
},
|
|
35
40
|
"devDependencies": {
|
|
36
41
|
"typescript": "^5.3.0"
|
package/src/tileset.test.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { createImageResourceFromImageElement } from '@flighthq/image';
|
|
2
|
-
import { createTextureAtlas } from '@flighthq/textureatlas';
|
|
2
|
+
import { createTextureAtlas, createTextureAtlasRegion, getTextureAtlasRegionById } from '@flighthq/textureatlas';
|
|
3
3
|
import type { TextureAtlas, Tileset } from '@flighthq/types';
|
|
4
4
|
|
|
5
|
-
import { buildTilesetRegions, createTileset } from './tileset';
|
|
5
|
+
import { buildTilesetRegions, createTileset, disposeTileset } from './tileset';
|
|
6
6
|
|
|
7
7
|
describe('buildTilesetRegions', () => {
|
|
8
8
|
it('advances y by tileHeight for each row', () => {
|
|
@@ -76,6 +76,43 @@ describe('buildTilesetRegions', () => {
|
|
|
76
76
|
expect(atlas.regions[0].x).toBe(0);
|
|
77
77
|
expect(atlas.regions[1].x).toBe(32);
|
|
78
78
|
});
|
|
79
|
+
|
|
80
|
+
it('truncates stale trailing regions when the grid shrinks after growing', () => {
|
|
81
|
+
const source = createImageResourceFromImageElement({ width: 64, height: 64 } as HTMLImageElement);
|
|
82
|
+
const atlas = createTextureAtlas({ image: source });
|
|
83
|
+
const tileset = createTileset({ atlas, columns: 2, rows: 2, tileWidth: 32, tileHeight: 32 });
|
|
84
|
+
buildTilesetRegions(tileset);
|
|
85
|
+
expect(atlas.regions).toHaveLength(4);
|
|
86
|
+
|
|
87
|
+
tileset.columns = 1;
|
|
88
|
+
tileset.rows = 1;
|
|
89
|
+
buildTilesetRegions(tileset);
|
|
90
|
+
expect(atlas.regions).toHaveLength(1);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('assigns each region id to its row-major tile index', () => {
|
|
94
|
+
const source = createImageResourceFromImageElement({ width: 64, height: 64 } as HTMLImageElement);
|
|
95
|
+
const atlas = createTextureAtlas({ image: source });
|
|
96
|
+
const tileset = createTileset({ atlas, columns: 2, rows: 2, tileWidth: 32, tileHeight: 32 });
|
|
97
|
+
buildTilesetRegions(tileset);
|
|
98
|
+
|
|
99
|
+
expect(atlas.regions.map((region) => region.id)).toEqual([0, 1, 2, 3]);
|
|
100
|
+
expect(getTextureAtlasRegionById(atlas, 3)).toBe(atlas.regions[3]);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('clears stale name/rotated/trimmed metadata on a reused region', () => {
|
|
104
|
+
const source = createImageResourceFromImageElement({ width: 32, height: 32 } as HTMLImageElement);
|
|
105
|
+
const atlas = createTextureAtlas({ image: source });
|
|
106
|
+
atlas.regions.push(createTextureAtlasRegion({ id: 99, name: 'stale', rotated: true, trimmed: true }));
|
|
107
|
+
const tileset = createTileset({ atlas, columns: 1, rows: 1, tileWidth: 32, tileHeight: 32 });
|
|
108
|
+
|
|
109
|
+
buildTilesetRegions(tileset);
|
|
110
|
+
|
|
111
|
+
expect(atlas.regions[0].id).toBe(0);
|
|
112
|
+
expect(atlas.regions[0].name).toBeNull();
|
|
113
|
+
expect(atlas.regions[0].rotated).toBe(false);
|
|
114
|
+
expect(atlas.regions[0].trimmed).toBe(false);
|
|
115
|
+
});
|
|
79
116
|
});
|
|
80
117
|
|
|
81
118
|
describe('createTileset', () => {
|
|
@@ -121,3 +158,41 @@ describe('createTileset', () => {
|
|
|
121
158
|
expect(obj).not.toStrictEqual(base);
|
|
122
159
|
});
|
|
123
160
|
});
|
|
161
|
+
|
|
162
|
+
describe('disposeTileset', () => {
|
|
163
|
+
it('clears the atlas reference so it becomes eligible for GC', () => {
|
|
164
|
+
const source = createImageResourceFromImageElement({ width: 32, height: 32 } as HTMLImageElement);
|
|
165
|
+
const atlas = createTextureAtlas({ image: source });
|
|
166
|
+
const tileset = createTileset({ atlas, columns: 1, rows: 1, tileWidth: 32, tileHeight: 32 });
|
|
167
|
+
|
|
168
|
+
disposeTileset(tileset);
|
|
169
|
+
|
|
170
|
+
expect(tileset.atlas).toBeNull();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('leaves the grid parameters intact', () => {
|
|
174
|
+
const source = createImageResourceFromImageElement({ width: 64, height: 32 } as HTMLImageElement);
|
|
175
|
+
const atlas = createTextureAtlas({ image: source });
|
|
176
|
+
const tileset = createTileset({ atlas, columns: 2, rows: 1, tileWidth: 32, tileHeight: 16, margin: 4, spacing: 2 });
|
|
177
|
+
|
|
178
|
+
disposeTileset(tileset);
|
|
179
|
+
|
|
180
|
+
expect(tileset.columns).toBe(2);
|
|
181
|
+
expect(tileset.rows).toBe(1);
|
|
182
|
+
expect(tileset.tileWidth).toBe(32);
|
|
183
|
+
expect(tileset.tileHeight).toBe(16);
|
|
184
|
+
expect(tileset.margin).toBe(4);
|
|
185
|
+
expect(tileset.spacing).toBe(2);
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
it('does not erase the shared atlas regions', () => {
|
|
189
|
+
const source = createImageResourceFromImageElement({ width: 64, height: 32 } as HTMLImageElement);
|
|
190
|
+
const atlas = createTextureAtlas({ image: source });
|
|
191
|
+
const tileset = createTileset({ atlas, columns: 2, rows: 1, tileWidth: 32, tileHeight: 32 });
|
|
192
|
+
buildTilesetRegions(tileset);
|
|
193
|
+
|
|
194
|
+
disposeTileset(tileset);
|
|
195
|
+
|
|
196
|
+
expect(atlas.regions).toHaveLength(2);
|
|
197
|
+
});
|
|
198
|
+
});
|
package/src/tilesetFrom.test.ts
CHANGED
|
@@ -95,6 +95,12 @@ describe('loadTilesetFromBase64', () => {
|
|
|
95
95
|
expect(tileset.tileHeight).toBe(16);
|
|
96
96
|
expect(tileset.atlas?.image?.source).toBeInstanceOf(HTMLImageElement);
|
|
97
97
|
});
|
|
98
|
+
|
|
99
|
+
it('threads margin and spacing into the tileset', async () => {
|
|
100
|
+
const tileset = await loadTilesetFromBase64('abc123', 'image/png', 16, 16, 2, 4);
|
|
101
|
+
expect(tileset.margin).toBe(2);
|
|
102
|
+
expect(tileset.spacing).toBe(4);
|
|
103
|
+
});
|
|
98
104
|
});
|
|
99
105
|
|
|
100
106
|
describe('loadTilesetFromBlob', () => {
|
|
@@ -103,6 +109,13 @@ describe('loadTilesetFromBlob', () => {
|
|
|
103
109
|
const tileset = await loadTilesetFromBlob(blob, 32, 32);
|
|
104
110
|
expect(tileset.atlas?.image?.source).toBeInstanceOf(HTMLImageElement);
|
|
105
111
|
});
|
|
112
|
+
|
|
113
|
+
it('threads margin and spacing into the tileset', async () => {
|
|
114
|
+
const blob = new Blob([], { type: 'image/png' });
|
|
115
|
+
const tileset = await loadTilesetFromBlob(blob, 32, 32, 1, 3);
|
|
116
|
+
expect(tileset.margin).toBe(1);
|
|
117
|
+
expect(tileset.spacing).toBe(3);
|
|
118
|
+
});
|
|
106
119
|
});
|
|
107
120
|
|
|
108
121
|
describe('loadTilesetFromBytes', () => {
|
|
@@ -119,6 +132,14 @@ describe('loadTilesetFromBytes', () => {
|
|
|
119
132
|
const bytes = new Uint8Array(16);
|
|
120
133
|
await expect(loadTilesetFromBytes(bytes, 32, 32)).rejects.toThrow('Unable to determine image type');
|
|
121
134
|
});
|
|
135
|
+
|
|
136
|
+
it('threads margin and spacing into the tileset with mimeType still after them', async () => {
|
|
137
|
+
const bytes = new Uint8Array([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0, 0, 0, 0, 0, 0, 0, 0]);
|
|
138
|
+
const tileset = await loadTilesetFromBytes(bytes, 32, 32, 5, 6, 'image/png');
|
|
139
|
+
expect(tileset.margin).toBe(5);
|
|
140
|
+
expect(tileset.spacing).toBe(6);
|
|
141
|
+
expect(tileset.atlas?.image?.source).toBeInstanceOf(HTMLImageElement);
|
|
142
|
+
});
|
|
122
143
|
});
|
|
123
144
|
|
|
124
145
|
describe('loadTilesetFromUrl', () => {
|
|
@@ -128,4 +149,11 @@ describe('loadTilesetFromUrl', () => {
|
|
|
128
149
|
expect(tileset.tileHeight).toBe(32);
|
|
129
150
|
expect(tileset.atlas?.image?.source).toBeInstanceOf(HTMLImageElement);
|
|
130
151
|
});
|
|
152
|
+
|
|
153
|
+
it('threads margin and spacing into the tileset with crossOrigin still after them', async () => {
|
|
154
|
+
const tileset = await loadTilesetFromUrl('data:image/png;base64,abc', 32, 32, 3, 2, 'anonymous');
|
|
155
|
+
expect(tileset.margin).toBe(3);
|
|
156
|
+
expect(tileset.spacing).toBe(2);
|
|
157
|
+
expect(tileset.atlas?.image?.source).toBeInstanceOf(HTMLImageElement);
|
|
158
|
+
});
|
|
131
159
|
});
|