@allmaps/render
Version:
Render functions for WebGL and image buffers
130 lines (129 loc) • 3.92 kB
JavaScript
import { proxy } from "comlink";
import { FetchableTile } from "./FetchableTile.js";
import { CacheableTile } from "./CacheableTile.js";
import { WarpedMapEvent, WarpedMapEventType } from "../shared/events.js";
class CacheableWorkerImageDataTile extends CacheableTile {
#worker;
#spritesWorker;
constructor(fetchableTile, worker, spritesWorker, fetchFn) {
super(fetchableTile, fetchFn);
this.#worker = worker;
this.#spritesWorker = spritesWorker;
}
/**
* Fetch the tile and create its ImageData using a WebWorker.
*
* @returns
*/
async fetch() {
try {
this.#worker.getImageData(
this.fetchableTile.tileUrl,
proxy(() => this.abortController.abort()),
this.fetchFn,
this.fetchableTile.tile.tileZoomLevel.width,
this.fetchableTile.tile.tileZoomLevel.height
).then((response) => {
this.data = response;
this.dispatchEvent(
new WarpedMapEvent(WarpedMapEventType.TILEFETCHED, {
tileUrl: this.fetchableTile.tileUrl
})
);
}).catch((err) => {
if (err instanceof Error && err.name === "AbortError") {
console.log("Fetch aborted");
} else {
console.error(err);
}
});
} catch (err) {
if (err instanceof Error && err.name === "AbortError") ;
else {
this.dispatchEvent(
new WarpedMapEvent(WarpedMapEventType.TILEFETCHERROR, {
tileUrl: this.fetchableTile.tileUrl
})
);
}
}
return this.data;
}
async applySprites() {
const data = this.data;
const spritesInfo = this.fetchableTile.options?.spritesInfo;
const warpedMapsByResourceId = this.fetchableTile.options?.warpedMapsByResourceId;
if (!data || !spritesInfo || !warpedMapsByResourceId) {
return;
}
const tileSizesByResourceId = new Map(
Array.from(warpedMapsByResourceId.entries()).map(
([resourceId, warpedMaps]) => [
resourceId,
warpedMaps.map((warpedMap) => warpedMap.tileSize)
]
)
);
return this.#spritesWorker.applySprites(data, spritesInfo.sprites, tileSizesByResourceId).then((clippedImageDatas) => {
this.cachedTilesFromSprites = this.spritesDataToCachedTiles(
clippedImageDatas,
spritesInfo,
warpedMapsByResourceId
);
this.dispatchEvent(
new WarpedMapEvent(WarpedMapEventType.TILESFROMSPRITETILE, {
tileUrl: this.fetchableTile.tileUrl
})
);
});
}
spritesDataToCachedTiles(clippedImageDatas, spritesInfo, warpedMapsByResourceId) {
const cachedTiles = [];
let index = 0;
for (const sprite of spritesInfo.sprites) {
const warpedMaps = warpedMapsByResourceId.get(sprite.imageId);
if (!warpedMaps) {
break;
}
for (const warpedMap of warpedMaps) {
const cachedTile = new CachedWorkerImageDataTile(
FetchableTile.fromSprite(sprite, spritesInfo.imageSize, warpedMap, {
spritesInfo
}),
this.#worker,
this.#spritesWorker,
clippedImageDatas[index]
);
cachedTiles.push(cachedTile);
index++;
}
}
return cachedTiles;
}
static createFactory(worker, spritesWorker) {
return (fetchableTile, fetchFn) => new CacheableWorkerImageDataTile(
fetchableTile,
worker,
spritesWorker,
fetchFn
);
}
}
class CachedWorkerImageDataTile extends CacheableWorkerImageDataTile {
/**
* Creates an instance of CachedTile.
*
* @constructor
* @param fetchableTile
* @param data
*/
constructor(fetchableTile, worker, spritesWorker, data) {
super(fetchableTile, worker, spritesWorker);
this.data = data;
}
}
export {
CacheableWorkerImageDataTile,
CachedWorkerImageDataTile
};
//# sourceMappingURL=CacheableWorkerImageDataTile.js.map