@carto/api-client 0.5.32-alpha.723d642.132 → 0.5.32-alpha.72cdcfe.130
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/build/api-client.cjs +22 -217
- package/build/api-client.cjs.map +1 -1
- package/build/api-client.js +22 -217
- package/build/api-client.js.map +1 -1
- package/package.json +1 -1
- package/src/fetch-map/pattern-atlas.ts +43 -253
- package/src/fetch-map/patterns/checker-large.svg +0 -1
- package/src/fetch-map/patterns/checker-medium.svg +0 -1
- package/src/fetch-map/patterns/checker-small.svg +0 -1
- package/src/fetch-map/patterns/cross-hatch-large.svg +0 -1
- package/src/fetch-map/patterns/cross-hatch-medium.svg +0 -1
- package/src/fetch-map/patterns/cross-hatch-small.svg +0 -1
- package/src/fetch-map/patterns/diag-left-large.svg +0 -1
- package/src/fetch-map/patterns/diag-left-medium.svg +0 -1
- package/src/fetch-map/patterns/diag-left-small.svg +0 -1
- package/src/fetch-map/patterns/diag-right-large.svg +0 -1
- package/src/fetch-map/patterns/diag-right-medium.svg +0 -1
- package/src/fetch-map/patterns/diag-right-small.svg +0 -1
- package/src/fetch-map/patterns/dots-large.svg +0 -1
- package/src/fetch-map/patterns/dots-medium.svg +0 -1
- package/src/fetch-map/patterns/dots-small.svg +0 -1
- package/src/fetch-map/patterns/hlines-large.svg +0 -1
- package/src/fetch-map/patterns/hlines-medium.svg +0 -1
- package/src/fetch-map/patterns/hlines-small.svg +0 -1
- package/src/fetch-map/patterns/solid.svg +0 -1
- package/src/fetch-map/patterns/vlines-large.svg +0 -1
- package/src/fetch-map/patterns/vlines-medium.svg +0 -1
- package/src/fetch-map/patterns/vlines-small.svg +0 -1
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"homepage": "https://github.com/CartoDB/carto-api-client#readme",
|
|
9
9
|
"author": "Don McCurdy <donmccurdy@carto.com>",
|
|
10
10
|
"packageManager": "yarn@4.3.1",
|
|
11
|
-
"version": "0.5.32-alpha.
|
|
11
|
+
"version": "0.5.32-alpha.72cdcfe.130",
|
|
12
12
|
"license": "MIT",
|
|
13
13
|
"publishConfig": {
|
|
14
14
|
"access": "public"
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
// Fill-pattern atlas — internal to carto-api-client.
|
|
2
2
|
//
|
|
3
|
-
// The patterns live as individual, developer-editable tiles (src/fetch-map/patterns/
|
|
4
|
-
//
|
|
5
|
-
// by tsup's `dataurl` loader
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// content — so linear sampling stays seamless at repeat boundaries and never bleeds a
|
|
11
|
-
// neighboring cell.
|
|
3
|
+
// The patterns live as individual, developer-editable tiles (src/fetch-map/patterns/
|
|
4
|
+
// *.png — any resolution; ideally anti-aliased exports from the Design vector master),
|
|
5
|
+
// inlined by tsup's `dataurl` loader and composited into a sprite sheet on a canvas the
|
|
6
|
+
// first time a pattern is needed. Each cell is surrounded by a gutter filled with the
|
|
7
|
+
// tile's own wrapped content, so linear sampling stays seamless at repeat boundaries
|
|
8
|
+
// and never bleeds a neighboring cell. High-res sources are smoothly downscaled;
|
|
9
|
+
// lower-res (pixel-art) sources are upscaled nearest-neighbor.
|
|
12
10
|
//
|
|
13
11
|
// parse-map sets `result.fillPatternAtlas = getPatternAtlas()`. deck.gl's
|
|
14
12
|
// `fillPatternAtlas` prop is async — but the Promise must resolve to a decoded image,
|
|
@@ -20,10 +18,6 @@
|
|
|
20
18
|
// globalThis.__CARTO_PATTERN_TEXTURE_PARAMS__ = {magFilter: 'nearest', ...}
|
|
21
19
|
// // merged into the atlas texture's sampler via deck's `textureParameters`;
|
|
22
20
|
// // unset -> deck defaults (linear).
|
|
23
|
-
// globalThis.__CARTO_PATTERN_ASSET_SOURCE__ = 'png' | 'svg' | 'procedural'
|
|
24
|
-
// // 'png' (default): Design's original 64px raster masks, tiled at native
|
|
25
|
-
// // resolution. 'svg': in-repo vector tiles rasterized at atlas-build time
|
|
26
|
-
// // (2x texel density per repeat). 'procedural': canvas painters, no assets.
|
|
27
21
|
|
|
28
22
|
import hlinesLarge from './patterns/hlines-large.png';
|
|
29
23
|
import hlinesMedium from './patterns/hlines-medium.png';
|
|
@@ -48,43 +42,13 @@ import checkerMedium from './patterns/checker-medium.png';
|
|
|
48
42
|
import checkerSmall from './patterns/checker-small.png';
|
|
49
43
|
import solid from './patterns/solid.png';
|
|
50
44
|
|
|
51
|
-
import hlinesLargeSvg from './patterns/hlines-large.svg';
|
|
52
|
-
import hlinesMediumSvg from './patterns/hlines-medium.svg';
|
|
53
|
-
import hlinesSmallSvg from './patterns/hlines-small.svg';
|
|
54
|
-
import vlinesLargeSvg from './patterns/vlines-large.svg';
|
|
55
|
-
import vlinesMediumSvg from './patterns/vlines-medium.svg';
|
|
56
|
-
import vlinesSmallSvg from './patterns/vlines-small.svg';
|
|
57
|
-
import diagLeftLargeSvg from './patterns/diag-left-large.svg';
|
|
58
|
-
import diagLeftMediumSvg from './patterns/diag-left-medium.svg';
|
|
59
|
-
import diagLeftSmallSvg from './patterns/diag-left-small.svg';
|
|
60
|
-
import diagRightLargeSvg from './patterns/diag-right-large.svg';
|
|
61
|
-
import diagRightMediumSvg from './patterns/diag-right-medium.svg';
|
|
62
|
-
import diagRightSmallSvg from './patterns/diag-right-small.svg';
|
|
63
|
-
import crossHatchLargeSvg from './patterns/cross-hatch-large.svg';
|
|
64
|
-
import crossHatchMediumSvg from './patterns/cross-hatch-medium.svg';
|
|
65
|
-
import crossHatchSmallSvg from './patterns/cross-hatch-small.svg';
|
|
66
|
-
import dotsLargeSvg from './patterns/dots-large.svg';
|
|
67
|
-
import dotsMediumSvg from './patterns/dots-medium.svg';
|
|
68
|
-
import dotsSmallSvg from './patterns/dots-small.svg';
|
|
69
|
-
import checkerLargeSvg from './patterns/checker-large.svg';
|
|
70
|
-
import checkerMediumSvg from './patterns/checker-medium.svg';
|
|
71
|
-
import checkerSmallSvg from './patterns/checker-small.svg';
|
|
72
|
-
import solidSvg from './patterns/solid.svg';
|
|
73
|
-
|
|
74
45
|
const DEFAULT_CELL_SIZE = 128;
|
|
75
|
-
// px of the
|
|
76
|
-
// defined against — one tile spans 64 design units whatever the asset source.
|
|
46
|
+
// px of the authored pattern art; also the reference for on-screen pattern size.
|
|
77
47
|
const SOURCE_TILE_SIZE = 64;
|
|
78
|
-
// Vector sources (svg/procedural) rasterize each repeat at up to this many px,
|
|
79
|
-
// doubling texel density per repeat vs the 64px masks.
|
|
80
|
-
const VECTOR_RENDER_SIZE = 128;
|
|
81
|
-
|
|
82
|
-
export type PatternAssetSource = 'png' | 'svg' | 'procedural';
|
|
83
48
|
|
|
84
49
|
type PatternDebugGlobals = {
|
|
85
50
|
__CARTO_PATTERN_CELL_SIZE__?: number;
|
|
86
51
|
__CARTO_PATTERN_TEXTURE_PARAMS__?: Record<string, unknown>;
|
|
87
|
-
__CARTO_PATTERN_ASSET_SOURCE__?: PatternAssetSource;
|
|
88
52
|
};
|
|
89
53
|
|
|
90
54
|
export type PatternAtlasFrame = {
|
|
@@ -134,32 +98,6 @@ const CELL_URLS: Record<string, string> = {
|
|
|
134
98
|
solid,
|
|
135
99
|
};
|
|
136
100
|
|
|
137
|
-
// atlas key -> inlined data URL of its vector source tile
|
|
138
|
-
const CELL_SVG_URLS: Record<string, string> = {
|
|
139
|
-
'hlines-large': hlinesLargeSvg,
|
|
140
|
-
'hlines-medium': hlinesMediumSvg,
|
|
141
|
-
'hlines-small': hlinesSmallSvg,
|
|
142
|
-
'vlines-large': vlinesLargeSvg,
|
|
143
|
-
'vlines-medium': vlinesMediumSvg,
|
|
144
|
-
'vlines-small': vlinesSmallSvg,
|
|
145
|
-
'diag-left-large': diagLeftLargeSvg,
|
|
146
|
-
'diag-left-medium': diagLeftMediumSvg,
|
|
147
|
-
'diag-left-small': diagLeftSmallSvg,
|
|
148
|
-
'diag-right-large': diagRightLargeSvg,
|
|
149
|
-
'diag-right-medium': diagRightMediumSvg,
|
|
150
|
-
'diag-right-small': diagRightSmallSvg,
|
|
151
|
-
'cross-hatch-large': crossHatchLargeSvg,
|
|
152
|
-
'cross-hatch-medium': crossHatchMediumSvg,
|
|
153
|
-
'cross-hatch-small': crossHatchSmallSvg,
|
|
154
|
-
'dots-large': dotsLargeSvg,
|
|
155
|
-
'dots-medium': dotsMediumSvg,
|
|
156
|
-
'dots-small': dotsSmallSvg,
|
|
157
|
-
'checker-large': checkerLargeSvg,
|
|
158
|
-
'checker-medium': checkerMediumSvg,
|
|
159
|
-
'checker-small': checkerSmallSvg,
|
|
160
|
-
solid: solidSvg,
|
|
161
|
-
};
|
|
162
|
-
|
|
163
101
|
function debugGlobals(): PatternDebugGlobals {
|
|
164
102
|
return globalThis as PatternDebugGlobals;
|
|
165
103
|
}
|
|
@@ -169,11 +107,6 @@ export function getPatternCellSize(): number {
|
|
|
169
107
|
return typeof cell === 'number' && cell > 0 ? cell : DEFAULT_CELL_SIZE;
|
|
170
108
|
}
|
|
171
109
|
|
|
172
|
-
export function getPatternAssetSource(): PatternAssetSource {
|
|
173
|
-
const source = debugGlobals().__CARTO_PATTERN_ASSET_SOURCE__;
|
|
174
|
-
return source === 'svg' || source === 'procedural' ? source : 'png';
|
|
175
|
-
}
|
|
176
|
-
|
|
177
110
|
/** Sampler overrides for the atlas texture; undefined keeps deck's defaults (linear). */
|
|
178
111
|
export function getPatternTextureParameters():
|
|
179
112
|
| Record<string, unknown>
|
|
@@ -182,27 +115,14 @@ export function getPatternTextureParameters():
|
|
|
182
115
|
return params && typeof params === 'object' ? params : undefined;
|
|
183
116
|
}
|
|
184
117
|
|
|
185
|
-
// Copies of the source tile laid side by side inside one atlas cell, per axis. Raster
|
|
186
|
-
// tiles draw at native resolution (no resampling); vector sources rasterize each
|
|
187
|
-
// repeat at up to VECTOR_RENDER_SIZE px. The UV wrap — where sampling seams live —
|
|
188
|
-
// happens 1/reps as often.
|
|
189
|
-
function getPatternRepeats(
|
|
190
|
-
cell: number,
|
|
191
|
-
source: PatternAssetSource = getPatternAssetSource()
|
|
192
|
-
): number {
|
|
193
|
-
const repeatSize = source === 'png' ? SOURCE_TILE_SIZE : VECTOR_RENDER_SIZE;
|
|
194
|
-
return Math.max(1, Math.floor(cell / repeatSize));
|
|
195
|
-
}
|
|
196
|
-
|
|
197
118
|
// deck's fill-pattern shader sizes the on-screen repeat proportionally to the mapping
|
|
198
|
-
// frame's texel size (scale = FILL_UV_SCALE * getFillPatternScale * frame.wh)
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
// and asset sources.
|
|
119
|
+
// frame's texel size (scale = FILL_UV_SCALE * getFillPatternScale * frame.wh), so a
|
|
120
|
+
// bigger cell magnifies the art instead of sharpening it. This factor compensates:
|
|
121
|
+
// getFillPatternScale must be multiplied by it so cell size only changes resolution.
|
|
202
122
|
export function getPatternScaleAdjustment(
|
|
203
123
|
cell: number = getPatternCellSize()
|
|
204
124
|
): number {
|
|
205
|
-
return
|
|
125
|
+
return SOURCE_TILE_SIZE / cell;
|
|
206
126
|
}
|
|
207
127
|
|
|
208
128
|
// Gutter width around each cell; sized so a few mip levels stay bleed-free.
|
|
@@ -268,108 +188,27 @@ async function loadImage(dataUrl: string): Promise<CanvasImageSource> {
|
|
|
268
188
|
});
|
|
269
189
|
}
|
|
270
190
|
|
|
271
|
-
|
|
272
|
-
// inconsistent across engines, and drawImage from an SVG image rasterizes from the
|
|
273
|
-
// vector at the destination size in modern browsers.
|
|
274
|
-
function loadSvgImage(dataUrl: string): Promise<CanvasImageSource> {
|
|
275
|
-
return new Promise((resolve, reject) => {
|
|
276
|
-
const img = new Image();
|
|
277
|
-
img.onload = () => resolve(img);
|
|
278
|
-
img.onerror = reject;
|
|
279
|
-
img.src = dataUrl;
|
|
280
|
-
});
|
|
281
|
-
}
|
|
191
|
+
const atlasPromises = new Map<number, Promise<AssembledAtlas>>();
|
|
282
192
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
const linePeriod = 4 * step;
|
|
295
|
-
const diagPeriod = 16 * step;
|
|
296
|
-
const square = 2 * step;
|
|
297
|
-
ctx.fillStyle = '#000';
|
|
298
|
-
ctx.strokeStyle = '#000';
|
|
299
|
-
const diag = (dir: 1 | -1) => {
|
|
300
|
-
// dir 1: "\" lines (x - y = k*p); dir -1: "/" lines (x + y = k*p)
|
|
301
|
-
ctx.lineWidth = Math.SQRT2; // 2px horizontal width at 45 degrees
|
|
302
|
-
ctx.beginPath();
|
|
303
|
-
for (
|
|
304
|
-
let k = -Math.ceil(64 / diagPeriod);
|
|
305
|
-
k <= 2 * Math.ceil(64 / diagPeriod);
|
|
306
|
-
k++
|
|
307
|
-
) {
|
|
308
|
-
ctx.moveTo(k * diagPeriod - 8 * dir, -8);
|
|
309
|
-
ctx.lineTo(k * diagPeriod + 72 * dir, 72);
|
|
310
|
-
}
|
|
311
|
-
ctx.stroke();
|
|
312
|
-
};
|
|
313
|
-
switch (name) {
|
|
314
|
-
case 'solid':
|
|
315
|
-
ctx.fillRect(0, 0, 64, 64);
|
|
316
|
-
break;
|
|
317
|
-
case 'hlines':
|
|
318
|
-
for (let y = 0; y < 64; y += linePeriod) ctx.fillRect(0, y, 64, 2);
|
|
319
|
-
break;
|
|
320
|
-
case 'vlines':
|
|
321
|
-
for (let x = 0; x < 64; x += linePeriod) ctx.fillRect(x, 0, 2, 64);
|
|
322
|
-
break;
|
|
323
|
-
case 'dots':
|
|
324
|
-
for (let y = 0; y < 64; y += linePeriod)
|
|
325
|
-
for (let x = 0; x < 64; x += linePeriod) ctx.fillRect(x, y, 2, 2);
|
|
326
|
-
break;
|
|
327
|
-
case 'checker':
|
|
328
|
-
for (let j = 0; j * square < 64; j++)
|
|
329
|
-
for (let i = 0; i * square < 64; i++)
|
|
330
|
-
if ((i + j) % 2 === 0)
|
|
331
|
-
ctx.fillRect(i * square, j * square, square, square);
|
|
332
|
-
break;
|
|
333
|
-
case 'diag-left':
|
|
334
|
-
diag(1);
|
|
335
|
-
break;
|
|
336
|
-
case 'diag-right':
|
|
337
|
-
diag(-1);
|
|
338
|
-
break;
|
|
339
|
-
case 'cross-hatch':
|
|
340
|
-
diag(1);
|
|
341
|
-
diag(-1);
|
|
342
|
-
break;
|
|
193
|
+
/** Assemble the sprite sheet from the individual editable pattern tiles. Memoized. */
|
|
194
|
+
export function getPatternAtlas(
|
|
195
|
+
cell: number = getPatternCellSize()
|
|
196
|
+
): Promise<AssembledAtlas> {
|
|
197
|
+
let promise = atlasPromises.get(cell);
|
|
198
|
+
if (!promise) {
|
|
199
|
+
promise = build(cell);
|
|
200
|
+
// Keep a rejection observed even if no consumer attaches a handler (e.g. Node,
|
|
201
|
+
// where there is no canvas) — the returned promise still rejects for real callers.
|
|
202
|
+
promise.catch(() => {});
|
|
203
|
+
atlasPromises.set(cell, promise);
|
|
343
204
|
}
|
|
205
|
+
return promise;
|
|
344
206
|
}
|
|
345
207
|
|
|
346
|
-
function
|
|
347
|
-
const canvas = createCanvas(size, size);
|
|
348
|
-
const ctx = canvas.getContext('2d');
|
|
349
|
-
if (!ctx)
|
|
350
|
-
throw new Error(
|
|
351
|
-
'carto-api-client: 2D context unavailable for pattern tile'
|
|
352
|
-
);
|
|
353
|
-
ctx.scale(size / 64, size / 64);
|
|
354
|
-
paintDesignTile(ctx, key);
|
|
355
|
-
return canvas;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
type TileImages = Record<string, CanvasImageSource>;
|
|
359
|
-
|
|
360
|
-
// Shared compositor: lay out the per-key tile images on the atlas grid. `none` is
|
|
361
|
-
// left transparent (no tile). Every other cell is filled with reps x reps copies of
|
|
362
|
-
// its tile, with one extra ring clipped into the gutter, so the padding holds the
|
|
363
|
-
// tile's own wrapped content.
|
|
364
|
-
async function composeAtlas(
|
|
365
|
-
cell: number,
|
|
366
|
-
reps: number,
|
|
367
|
-
images: TileImages
|
|
368
|
-
): Promise<AssembledAtlas> {
|
|
208
|
+
async function build(cell: number): Promise<AssembledAtlas> {
|
|
369
209
|
const mapping = getPatternAtlasMapping(cell);
|
|
370
210
|
const pad = getPatternCellPadding(cell);
|
|
371
211
|
const pitch = cell + 2 * pad;
|
|
372
|
-
const step = cell / reps;
|
|
373
212
|
const canvas = createCanvas(pitch * 3, pitch * (PATTERN_ROWS.length + 1));
|
|
374
213
|
const ctx = canvas.getContext('2d');
|
|
375
214
|
if (!ctx)
|
|
@@ -377,16 +216,30 @@ async function composeAtlas(
|
|
|
377
216
|
'carto-api-client: 2D context unavailable for pattern atlas'
|
|
378
217
|
);
|
|
379
218
|
|
|
219
|
+
const images: Record<string, CanvasImageSource> = {};
|
|
220
|
+
await Promise.all(
|
|
221
|
+
Object.entries(CELL_URLS).map(async ([key, url]) => {
|
|
222
|
+
images[key] = await loadImage(url);
|
|
223
|
+
})
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
// `none` is left transparent (no tile). Every other tile is drawn 3x3 clipped to its
|
|
227
|
+
// padded rect, so the gutter holds the tile's own wrapped content.
|
|
380
228
|
for (const [key, frame] of Object.entries(mapping)) {
|
|
381
229
|
const img = images[key];
|
|
382
230
|
if (!img) continue;
|
|
231
|
+
// Two art classes: diagonal tiles rely on baked anti-aliasing, which nearest
|
|
232
|
+
// scaling turns into hard blocks — scale them smoothly. Axis-aligned tiles have
|
|
233
|
+
// exact hard edges on texel boundaries — nearest is lossless, smoothing blurs.
|
|
234
|
+
ctx.imageSmoothingEnabled = /^(diag-|cross-hatch)/.test(key);
|
|
235
|
+
if ('imageSmoothingQuality' in ctx) ctx.imageSmoothingQuality = 'high';
|
|
383
236
|
ctx.save();
|
|
384
237
|
ctx.beginPath();
|
|
385
238
|
ctx.rect(frame.x - pad, frame.y - pad, cell + 2 * pad, cell + 2 * pad);
|
|
386
239
|
ctx.clip();
|
|
387
|
-
for (
|
|
388
|
-
for (
|
|
389
|
-
ctx.drawImage(img, frame.x +
|
|
240
|
+
for (const dx of [-cell, 0, cell]) {
|
|
241
|
+
for (const dy of [-cell, 0, cell]) {
|
|
242
|
+
ctx.drawImage(img, frame.x + dx, frame.y + dy, cell, cell);
|
|
390
243
|
}
|
|
391
244
|
}
|
|
392
245
|
ctx.restore();
|
|
@@ -396,66 +249,3 @@ async function composeAtlas(
|
|
|
396
249
|
return createImageBitmap(canvas);
|
|
397
250
|
return canvas as HTMLCanvasElement;
|
|
398
251
|
}
|
|
399
|
-
|
|
400
|
-
// One builder per asset source, all funneling into composeAtlas.
|
|
401
|
-
|
|
402
|
-
// Design's original 64px raster masks, tiled at native resolution (never resampled).
|
|
403
|
-
async function buildPngAtlas(cell: number): Promise<AssembledAtlas> {
|
|
404
|
-
const images: TileImages = {};
|
|
405
|
-
await Promise.all(
|
|
406
|
-
Object.entries(CELL_URLS).map(async ([key, url]) => {
|
|
407
|
-
images[key] = await loadImage(url);
|
|
408
|
-
})
|
|
409
|
-
);
|
|
410
|
-
return composeAtlas(cell, getPatternRepeats(cell, 'png'), images);
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// In-repo vector tiles, rasterized from the vector at the repeat size.
|
|
414
|
-
async function buildSvgAtlas(cell: number): Promise<AssembledAtlas> {
|
|
415
|
-
const images: TileImages = {};
|
|
416
|
-
await Promise.all(
|
|
417
|
-
Object.entries(CELL_SVG_URLS).map(async ([key, url]) => {
|
|
418
|
-
images[key] = await loadSvgImage(url);
|
|
419
|
-
})
|
|
420
|
-
);
|
|
421
|
-
return composeAtlas(cell, getPatternRepeats(cell, 'svg'), images);
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// Asset-free canvas painters drawing the measured design-grid geometry.
|
|
425
|
-
async function buildProceduralAtlas(cell: number): Promise<AssembledAtlas> {
|
|
426
|
-
const reps = getPatternRepeats(cell, 'procedural');
|
|
427
|
-
const step = cell / reps;
|
|
428
|
-
const images: TileImages = {};
|
|
429
|
-
for (const key of Object.keys(CELL_URLS)) {
|
|
430
|
-
images[key] = paintTileCanvas(key, step);
|
|
431
|
-
}
|
|
432
|
-
return composeAtlas(cell, reps, images);
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
const ATLAS_BUILDERS: Record<
|
|
436
|
-
PatternAssetSource,
|
|
437
|
-
(cell: number) => Promise<AssembledAtlas>
|
|
438
|
-
> = {
|
|
439
|
-
png: buildPngAtlas,
|
|
440
|
-
svg: buildSvgAtlas,
|
|
441
|
-
procedural: buildProceduralAtlas,
|
|
442
|
-
};
|
|
443
|
-
|
|
444
|
-
const atlasPromises = new Map<string, Promise<AssembledAtlas>>();
|
|
445
|
-
|
|
446
|
-
/** Assemble the sprite sheet for the active asset source and cell size. Memoized. */
|
|
447
|
-
export function getPatternAtlas(
|
|
448
|
-
cell: number = getPatternCellSize()
|
|
449
|
-
): Promise<AssembledAtlas> {
|
|
450
|
-
const source = getPatternAssetSource();
|
|
451
|
-
const memoKey = `${source}:${cell}`;
|
|
452
|
-
let promise = atlasPromises.get(memoKey);
|
|
453
|
-
if (!promise) {
|
|
454
|
-
promise = ATLAS_BUILDERS[source](cell);
|
|
455
|
-
// Keep a rejection observed even if no consumer attaches a handler (e.g. Node,
|
|
456
|
-
// where there is no canvas) — the returned promise still rejects for real callers.
|
|
457
|
-
promise.catch(() => {});
|
|
458
|
-
atlasPromises.set(memoKey, promise);
|
|
459
|
-
}
|
|
460
|
-
return promise;
|
|
461
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="16" height="16" patternUnits="userSpaceOnUse"><rect width="8" height="8"/><rect x="8" y="8" width="8" height="8"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="4" height="4"/><rect x="4" y="4" width="4" height="4"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="4" height="4" patternUnits="userSpaceOnUse"><rect width="2" height="2"/><rect x="2" y="2" width="2" height="2"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="a" width="45.2548" height="64" patternUnits="userSpaceOnUse" patternTransform="rotate(-45)"><rect width="1.4142" height="64"/></pattern><pattern id="b" width="45.2548" height="64" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><rect width="1.4142" height="64"/></pattern></defs><rect width="64" height="64" fill="url(#a)"/><rect width="64" height="64" fill="url(#b)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="a" width="22.6274" height="64" patternUnits="userSpaceOnUse" patternTransform="rotate(-45)"><rect width="1.4142" height="64"/></pattern><pattern id="b" width="22.6274" height="64" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><rect width="1.4142" height="64"/></pattern></defs><rect width="64" height="64" fill="url(#a)"/><rect width="64" height="64" fill="url(#b)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="a" width="11.3137" height="64" patternUnits="userSpaceOnUse" patternTransform="rotate(-45)"><rect width="1.4142" height="64"/></pattern><pattern id="b" width="11.3137" height="64" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><rect width="1.4142" height="64"/></pattern></defs><rect width="64" height="64" fill="url(#a)"/><rect width="64" height="64" fill="url(#b)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="45.2548" height="64" patternUnits="userSpaceOnUse" patternTransform="rotate(-45)"><rect width="1.4142" height="64"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="22.6274" height="64" patternUnits="userSpaceOnUse" patternTransform="rotate(-45)"><rect width="1.4142" height="64"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="11.3137" height="64" patternUnits="userSpaceOnUse" patternTransform="rotate(-45)"><rect width="1.4142" height="64"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="45.2548" height="64" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><rect width="1.4142" height="64"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="22.6274" height="64" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><rect width="1.4142" height="64"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="11.3137" height="64" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><rect width="1.4142" height="64"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="16" height="16" patternUnits="userSpaceOnUse"><rect width="2" height="2"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="8" height="8" patternUnits="userSpaceOnUse"><rect width="2" height="2"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="4" height="4" patternUnits="userSpaceOnUse"><rect width="2" height="2"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="64" height="16" patternUnits="userSpaceOnUse"><rect width="64" height="2"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="64" height="8" patternUnits="userSpaceOnUse"><rect width="64" height="2"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="64" height="4" patternUnits="userSpaceOnUse"><rect width="64" height="2"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs></defs><rect width="64" height="64"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="16" height="64" patternUnits="userSpaceOnUse"><rect width="2" height="64"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="8" height="64" patternUnits="userSpaceOnUse"><rect width="2" height="64"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64"><defs><pattern id="p" width="4" height="64" patternUnits="userSpaceOnUse"><rect width="2" height="64"/></pattern></defs><rect width="64" height="64" fill="url(#p)"/></svg>
|