UNPKG

@allmaps/render

Version:

Render functions for WebGL and image buffers

130 lines (129 loc) 3.92 kB
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