spryte 0.2.3 → 0.4.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.
Files changed (50) hide show
  1. package/README.md +11 -8
  2. package/dist/backend.d.ts +22 -5
  3. package/dist/backend.d.ts.map +1 -1
  4. package/dist/canvas2d.d.ts +11 -3
  5. package/dist/canvas2d.d.ts.map +1 -1
  6. package/dist/canvas2d.js +72 -4
  7. package/dist/canvas2d.js.map +1 -1
  8. package/dist/draw.d.ts +50 -20
  9. package/dist/draw.d.ts.map +1 -1
  10. package/dist/draw.js +48 -7
  11. package/dist/draw.js.map +1 -1
  12. package/dist/filters.d.ts +59 -0
  13. package/dist/filters.d.ts.map +1 -0
  14. package/dist/filters.js +188 -0
  15. package/dist/filters.js.map +1 -0
  16. package/dist/index.d.ts +6 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +6 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/mask.d.ts +13 -0
  21. package/dist/mask.d.ts.map +1 -0
  22. package/dist/mask.js +29 -0
  23. package/dist/mask.js.map +1 -0
  24. package/dist/offscreen.d.ts +26 -0
  25. package/dist/offscreen.d.ts.map +1 -0
  26. package/dist/offscreen.js +83 -0
  27. package/dist/offscreen.js.map +1 -0
  28. package/dist/panels.d.ts +44 -0
  29. package/dist/panels.d.ts.map +1 -0
  30. package/dist/panels.js +97 -0
  31. package/dist/panels.js.map +1 -0
  32. package/dist/phaser.d.ts +80 -0
  33. package/dist/phaser.d.ts.map +1 -0
  34. package/dist/phaser.js +100 -0
  35. package/dist/phaser.js.map +1 -0
  36. package/dist/renderer.js +1 -0
  37. package/dist/renderer.js.map +1 -1
  38. package/dist/shapes.d.ts +64 -0
  39. package/dist/shapes.d.ts.map +1 -0
  40. package/dist/shapes.js +367 -0
  41. package/dist/shapes.js.map +1 -0
  42. package/dist/shared.d.ts +29 -0
  43. package/dist/shared.d.ts.map +1 -0
  44. package/dist/shared.js +134 -0
  45. package/dist/shared.js.map +1 -0
  46. package/dist/webgl2.d.ts +29 -12
  47. package/dist/webgl2.d.ts.map +1 -1
  48. package/dist/webgl2.js +138 -19
  49. package/dist/webgl2.js.map +1 -1
  50. package/package.json +8 -2
package/dist/mask.js ADDED
@@ -0,0 +1,29 @@
1
+ import { offscreen, pass, restore, whole } from "./offscreen.js";
2
+ /**
3
+ * Run `fn`, keeping what it draws only where `shape` draws: a sprite (soft, using its alpha), shapes, text,
4
+ * anything. Same units, transform and clips as outside. Nests, and works inside `draw.into()`. Costs two
5
+ * offscreen passes the size of the destination, so mask a group of things at once rather than each sprite.
6
+ *
7
+ * ```ts
8
+ * import { mask } from "spryte";
9
+ * mask(draw, () => draw.circle(px, py, 40, "#fff"), () => drawLevel(draw)); // spotlight
10
+ * ```
11
+ */
12
+ export function mask(draw, shape, fn) {
13
+ const o = offscreen(draw);
14
+ try {
15
+ pass(draw, o, o.a, fn, true);
16
+ draw.alpha = 1;
17
+ pass(draw, o, o.b, shape, true);
18
+ // Keep content where the shape drew: one quad over the whole target, so both backends agree.
19
+ pass(draw, o, o.a, () => {
20
+ draw.backend.setBlend("mask");
21
+ whole(draw, o.b, o);
22
+ }, false);
23
+ }
24
+ finally {
25
+ restore(draw, o);
26
+ }
27
+ whole(draw, o.a, o);
28
+ }
29
+ //# sourceMappingURL=mask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mask.js","sourceRoot":"","sources":["../src/mask.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAEjE;;;;;;;;;GASG;AACH,MAAM,UAAU,IAAI,CAAC,IAAU,EAAE,KAAiB,EAAE,EAAc;IAChE,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,CAAC;QACH,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAChC,6FAA6F;QAC7F,IAAI,CACF,IAAI,EACJ,CAAC,EACD,CAAC,CAAC,CAAC,EACH,GAAG,EAAE;YACH,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC9B,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtB,CAAC,EACD,KAAK,CACN,CAAC;IACJ,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACnB,CAAC;IACD,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACtB,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { ClipRect } from "./backend.js";
2
+ import type { Draw } from "./draw.js";
3
+ import type { Shader } from "./shader.js";
4
+ import { RenderTarget } from "./target.js";
5
+ /** @internal One level of offscreen drawing: the destination's size and two targets matching its pixels. */
6
+ export interface Offscreen {
7
+ outer: RenderTarget | null;
8
+ lw: number;
9
+ lh: number;
10
+ pw: number;
11
+ ph: number;
12
+ a: RenderTarget;
13
+ b: RenderTarget;
14
+ blend: Draw["blendMode"];
15
+ alpha: number;
16
+ clip: ClipRect | null;
17
+ }
18
+ /** @internal */
19
+ export declare function offscreen(draw: Draw): Offscreen;
20
+ /** @internal Draw `fn` into `into` (cleared when `clear`), in the outer units and clip, starting from normal blending. */
21
+ export declare function pass(draw: Draw, o: Offscreen, into: RenderTarget, fn: () => void, clear: boolean): void;
22
+ /** @internal Back to the outer destination, clip, alpha and blend. */
23
+ export declare function restore(draw: Draw, o: Offscreen): void;
24
+ /** @internal Draw a pooled target over the whole destination, 1:1 and untransformed, through `shader` (default none). 1:1 means `smooth` only matters to shaders sampling between texels. */
25
+ export declare function whole(draw: Draw, t: RenderTarget, o: Offscreen, shader?: Shader | null, smooth?: boolean): void;
26
+ //# sourceMappingURL=offscreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offscreen.d.ts","sourceRoot":"","sources":["../src/offscreen.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAK3C,4GAA4G;AAC5G,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,CAAC,EAAE,YAAY,CAAC;IAChB,CAAC,EAAE,YAAY,CAAC;IAChB,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;CACvB;AAED,gBAAgB;AAChB,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAmB/C;AAgBD,0HAA0H;AAC1H,wBAAgB,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAWvG;AAED,sEAAsE;AACtE,wBAAgB,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,GAAG,IAAI,CAOtD;AAED,6LAA6L;AAC7L,wBAAgB,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM,GAAE,MAAM,GAAG,IAAW,EAAE,MAAM,UAAQ,GAAG,IAAI,CAanH"}
@@ -0,0 +1,83 @@
1
+ import { RenderTarget } from "./target.js";
2
+ /** Two pooled targets per level of mask or filter nesting, kept between frames and remade when the size changes. */
3
+ const pools = new WeakMap();
4
+ /** @internal */
5
+ export function offscreen(draw) {
6
+ const outer = draw.target;
7
+ const lw = outer ? outer.width : draw.viewW;
8
+ const lh = outer ? outer.height : draw.viewH;
9
+ const pw = outer ? outer.width : draw.backingW || Math.round(draw.viewW * draw.renderScale);
10
+ const ph = outer ? outer.height : draw.backingH || Math.round(draw.viewH * draw.renderScale);
11
+ const level = draw.maskDepth++;
12
+ return {
13
+ outer,
14
+ lw,
15
+ lh,
16
+ pw,
17
+ ph,
18
+ a: pooled(draw, level * 2, pw, ph),
19
+ b: pooled(draw, level * 2 + 1, pw, ph),
20
+ blend: draw.blendMode,
21
+ alpha: draw.alpha,
22
+ clip: draw.clips.at(-1) ?? null,
23
+ };
24
+ }
25
+ function pooled(draw, i, w, h) {
26
+ let pool = pools.get(draw);
27
+ if (!pool) {
28
+ pool = [];
29
+ pools.set(draw, pool);
30
+ }
31
+ const t = pool[i];
32
+ if (t && t.width === w && t.height === h)
33
+ return t;
34
+ if (t)
35
+ draw.backend.disposeTarget(t);
36
+ const fresh = new RenderTarget(w, h);
37
+ pool[i] = fresh;
38
+ return fresh;
39
+ }
40
+ /** @internal Draw `fn` into `into` (cleared when `clear`), in the outer units and clip, starting from normal blending. */
41
+ export function pass(draw, o, into, fn, clear) {
42
+ draw.target = into;
43
+ draw.backend.setTarget(into, clear ? 0 : null, o.lw, o.lh);
44
+ // Targets match the destination's pixels, so clips carry over as they are.
45
+ if (o.clip)
46
+ draw.backend.setClip(o.clip);
47
+ draw.blend("normal");
48
+ try {
49
+ fn();
50
+ }
51
+ finally {
52
+ if (o.clip)
53
+ draw.backend.setClip(null);
54
+ }
55
+ }
56
+ /** @internal Back to the outer destination, clip, alpha and blend. */
57
+ export function restore(draw, o) {
58
+ draw.target = o.outer;
59
+ draw.backend.setTarget(o.outer, null, o.lw, o.lh);
60
+ if (o.clip)
61
+ draw.backend.setClip(o.clip);
62
+ draw.maskDepth--;
63
+ draw.alpha = o.alpha;
64
+ draw.blend(o.blend);
65
+ }
66
+ /** @internal Draw a pooled target over the whole destination, 1:1 and untransformed, through `shader` (default none). 1:1 means `smooth` only matters to shaders sampling between texels. */
67
+ export function whole(draw, t, o, shader = null, smooth = false) {
68
+ const outer = draw.shader;
69
+ if (outer !== shader)
70
+ draw.backend.setShader(shader);
71
+ const m = draw.tmp;
72
+ m[0] = o.lw;
73
+ m[1] = 0;
74
+ m[2] = 0;
75
+ m[3] = o.lh;
76
+ m[4] = 0;
77
+ m[5] = 0;
78
+ draw.quads++;
79
+ draw.backend.quad(m, t, 0, 0, t.width, t.height, 0xffffffff, 0, smooth);
80
+ if (outer !== shader)
81
+ draw.backend.setShader(outer);
82
+ }
83
+ //# sourceMappingURL=offscreen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offscreen.js","sourceRoot":"","sources":["../src/offscreen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import type { TextureSource } from "./backend.js";
2
+ import type { Color } from "./color.js";
3
+ import type { Draw, Frame } from "./draw.js";
4
+ /** Options for `nineSlice` and `tiled`. */
5
+ export interface PanelDrawOptions {
6
+ /** Multiplied with the global alpha. */
7
+ alpha?: number;
8
+ /** Colour multiplier. Default white. */
9
+ tint?: Color;
10
+ /** 0..1 mix toward white. */
11
+ flash?: number;
12
+ /** Linear filtering. Default: the renderer's setting. */
13
+ smooth?: boolean;
14
+ }
15
+ export interface TiledDrawOptions extends PanelDrawOptions {
16
+ /** Scroll the pattern, in source pixels before `scale` (wraps). */
17
+ offsetX?: number;
18
+ offsetY?: number;
19
+ /** Tile size multiplier. Default 1. */
20
+ scale?: number;
21
+ }
22
+ /**
23
+ * Stretch a frame over a `w × h` box at `x, y` (top-left) without stretching its corners: the classic UI panel.
24
+ * `insets` are the corner sizes in source pixels, one number or `[left, top, right, bottom]`. Edges stretch,
25
+ * the centre fills, and corners shrink evenly if the box is smaller than they are. Nine quads, any backend.
26
+ *
27
+ * ```ts
28
+ * import { nineSlice } from "spryte";
29
+ * nineSlice(draw, panel, 8, 8, 120, 48, 6);
30
+ * ```
31
+ */
32
+ export declare function nineSlice(draw: Draw, frame: Frame | TextureSource, x: number, y: number, w: number, h: number, insets: number | readonly [number, number, number, number], o?: PanelDrawOptions): void;
33
+ /**
34
+ * Fill a `w × h` box at `x, y` (top-left) with a frame repeated edge to edge: scrolling backgrounds, floors,
35
+ * water. `offsetX/offsetY` scroll the pattern. Works on frames inside an atlas (no texture wrapping), one
36
+ * quad per visible tile, on any backend.
37
+ *
38
+ * ```ts
39
+ * import { tiled } from "spryte";
40
+ * tiled(draw, water, 0, 120, 320, 60, { offsetX: t * 20 });
41
+ * ```
42
+ */
43
+ export declare function tiled(draw: Draw, frame: Frame | TextureSource, x: number, y: number, w: number, h: number, o?: TiledDrawOptions): void;
44
+ //# sourceMappingURL=panels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panels.d.ts","sourceRoot":"","sources":["../src/panels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAE7C,2CAA2C;AAC3C,MAAM,WAAW,gBAAgB;IAC/B,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,IAAI,CAAC,EAAE,KAAK,CAAC;IACb,6BAA6B;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAiB,SAAQ,gBAAgB;IACxD,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,GAAG,aAAa,EAC5B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAC1D,CAAC,GAAE,gBAAuB,GACzB,IAAI,CAwBN;AAED;;;;;;;;;GASG;AACH,wBAAgB,KAAK,CACnB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,GAAG,aAAa,EAC5B,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,CAAC,GAAE,gBAAuB,GACzB,IAAI,CA2BN"}
package/dist/panels.js ADDED
@@ -0,0 +1,97 @@
1
+ const NONE = Object.freeze({});
2
+ /**
3
+ * Stretch a frame over a `w × h` box at `x, y` (top-left) without stretching its corners: the classic UI panel.
4
+ * `insets` are the corner sizes in source pixels, one number or `[left, top, right, bottom]`. Edges stretch,
5
+ * the centre fills, and corners shrink evenly if the box is smaller than they are. Nine quads, any backend.
6
+ *
7
+ * ```ts
8
+ * import { nineSlice } from "spryte";
9
+ * nineSlice(draw, panel, 8, 8, 120, 48, 6);
10
+ * ```
11
+ */
12
+ export function nineSlice(draw, frame, x, y, w, h, insets, o = NONE) {
13
+ const f = "image" in frame ? frame : draw.wholeImage(frame);
14
+ const [l, t, r, b] = typeof insets === "number" ? [insets, insets, insets, insets] : insets;
15
+ // Corners keep their size unless they don't fit.
16
+ const kx = Math.min(1, w / Math.max(l + r, 1e-9));
17
+ const ky = Math.min(1, h / Math.max(t + b, 1e-9));
18
+ const xs = [x, x + l * kx, x + w - r * kx, x + w];
19
+ const ys = [y, y + t * ky, y + h - b * ky, y + h];
20
+ const us = [f.x, f.x + l, f.x + f.w - r, f.x + f.w];
21
+ const vs = [f.y, f.y + t, f.y + f.h - b, f.y + f.h];
22
+ const color = draw.spriteColor(o);
23
+ const smooth = o.smooth ?? draw.smooth;
24
+ for (let j = 0; j < 3; j++)
25
+ for (let i = 0; i < 3; i++) {
26
+ const pw = xs[i + 1] - xs[i];
27
+ const ph = ys[j + 1] - ys[j];
28
+ const sw = us[i + 1] - us[i];
29
+ const sh = vs[j + 1] - vs[j];
30
+ if (pw <= 0 || ph <= 0 || sw <= 0 || sh <= 0)
31
+ continue;
32
+ draw.local(xs[i], ys[j], pw, ph);
33
+ if (!smooth)
34
+ snapEdges(draw);
35
+ draw.quads++;
36
+ draw.backend.quad(draw.tmp, f.image, us[i], vs[j], sw, sh, color, o.flash ?? 0, smooth);
37
+ }
38
+ }
39
+ /**
40
+ * Fill a `w × h` box at `x, y` (top-left) with a frame repeated edge to edge: scrolling backgrounds, floors,
41
+ * water. `offsetX/offsetY` scroll the pattern. Works on frames inside an atlas (no texture wrapping), one
42
+ * quad per visible tile, on any backend.
43
+ *
44
+ * ```ts
45
+ * import { tiled } from "spryte";
46
+ * tiled(draw, water, 0, 120, 320, 60, { offsetX: t * 20 });
47
+ * ```
48
+ */
49
+ export function tiled(draw, frame, x, y, w, h, o = NONE) {
50
+ const f = "image" in frame ? frame : draw.wholeImage(frame);
51
+ const k = o.scale ?? 1;
52
+ const tw = f.w * k;
53
+ const th = f.h * k;
54
+ if (!(tw > 0 && th > 0 && w > 0 && h > 0))
55
+ return;
56
+ const color = draw.spriteColor(o);
57
+ const smooth = o.smooth ?? draw.smooth;
58
+ const flash = o.flash ?? 0;
59
+ const tiles = (Math.ceil(w / tw) + 1) * (Math.ceil(h / th) + 1);
60
+ if (tiles > 1_000_000)
61
+ throw new Error(`spryte: tiled() would draw ${tiles} tiles; use a larger frame or scale`);
62
+ const ox = ((((o.offsetX ?? 0) * k) % tw) + tw) % tw;
63
+ const oy = ((((o.offsetY ?? 0) * k) % th) + th) % th;
64
+ for (let ty = y - oy; ty < y + h; ty += th) {
65
+ const y0 = Math.max(ty, y);
66
+ const y1 = Math.min(ty + th, y + h);
67
+ if (y1 <= y0)
68
+ continue;
69
+ for (let tx = x - ox; tx < x + w; tx += tw) {
70
+ const x0 = Math.max(tx, x);
71
+ const x1 = Math.min(tx + tw, x + w);
72
+ if (x1 <= x0)
73
+ continue;
74
+ draw.local(x0, y0, x1 - x0, y1 - y0);
75
+ if (!smooth)
76
+ snapEdges(draw);
77
+ draw.quads++;
78
+ draw.backend.quad(draw.tmp, f.image, f.x + (x0 - tx) / k, f.y + (y0 - ty) / k, (x1 - x0) / k, (y1 - y0) / k, color, flash, smooth);
79
+ }
80
+ }
81
+ }
82
+ /**
83
+ * Pixel art: put an unrotated quad's edges on whole units, like `sprite()`. Neighbouring quads share edges,
84
+ * so they round the same way and never gap or overlap.
85
+ */
86
+ function snapEdges(draw) {
87
+ const t = draw.tmp;
88
+ if (t[1] !== 0 || t[2] !== 0)
89
+ return;
90
+ const x0 = Math.round(t[4]);
91
+ const y0 = Math.round(t[5]);
92
+ t[0] = Math.round(t[4] + t[0]) - x0;
93
+ t[3] = Math.round(t[5] + t[3]) - y0;
94
+ t[4] = x0;
95
+ t[5] = y0;
96
+ }
97
+ //# sourceMappingURL=panels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panels.js","sourceRoot":"","sources":["../src/panels.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * spryte inside a Phaser 4 game: an `Extern` game object draws with spryte in Phaser's own frame and depth order,
3
+ * on the WebGL2 context the game runs on. Phaser makes a WebGL1 context by itself, so the game is created on one
4
+ * from `createPhaserContext()`. Nothing here depends on Phaser: the types describe the parts of Phaser 4 it touches.
5
+ *
6
+ * ```ts
7
+ * import { createPhaserContext, spryteExtern } from "spryte/phaser";
8
+ *
9
+ * const game = new Phaser.Game({ type: Phaser.WEBGL, ...createPhaserContext(), scene: Bullets });
10
+ * class Bullets extends Phaser.Scene {
11
+ * create() {
12
+ * spryteExtern(this.add.extern().setDepth(5), (draw) => draw.sprites(bullet, positions, count));
13
+ * }
14
+ * }
15
+ * ```
16
+ */
17
+ import type { Draw } from "./draw.js";
18
+ import { type SharedRendererOptions } from "./shared.js";
19
+ export interface PhaserDrawingContext {
20
+ framebuffer: {
21
+ webGLFramebuffer: WebGLFramebuffer | null;
22
+ } | null;
23
+ width: number;
24
+ height: number;
25
+ /** Phaser's cached GL state for this destination: framebuffer, viewport, scissor, stencil, blend, colour mask. */
26
+ state: unknown;
27
+ }
28
+ export interface PhaserWebGLRenderer {
29
+ gl: WebGLRenderingContext | WebGL2RenderingContext;
30
+ glWrapper: {
31
+ update(state: unknown, force?: boolean): void;
32
+ };
33
+ }
34
+ export interface PhaserMatrix {
35
+ a: number;
36
+ b: number;
37
+ c: number;
38
+ d: number;
39
+ e: number;
40
+ f: number;
41
+ }
42
+ /** The parts of `Phaser.GameObjects.Extern` the helper uses. */
43
+ export interface PhaserExtern {
44
+ render(renderer: PhaserWebGLRenderer, drawingContext: PhaserDrawingContext, calcMatrix: PhaserMatrix, displayList?: unknown, displayListIndex?: number): void;
45
+ once?(event: string, fn: () => void): unknown;
46
+ }
47
+ export interface PhaserSpryte {
48
+ /** The `Draw`, from the first frame on (spryte is created in the Extern's first render, where Phaser expects GL state to change). */
49
+ readonly draw: Draw | null;
50
+ /** Free spryte's GPU objects. Called for you when the Extern is destroyed. */
51
+ dispose(): void;
52
+ }
53
+ /**
54
+ * Draw with spryte in an `Extern`'s slot: `render` is called each frame with a `Draw` whose transform is the
55
+ * Extern's `calcMatrix` (the camera, and any Container it's in), so world coordinates are Phaser's. Filters on the
56
+ * Extern or its camera, camera viewports and `Stencil` masks apply, since spryte draws into Phaser's drawing context
57
+ * under its state. The game must run on a WebGL2 context (`createPhaserContext`).
58
+ */
59
+ export declare function spryteExtern(extern: PhaserExtern, render: (draw: Draw) => void, options?: SharedRendererOptions): PhaserSpryte;
60
+ /**
61
+ * A WebGL2 context for Phaser to run on, with its shaders translated to GLSL ES 3.00 (`shimShaders`). Spread the
62
+ * result into the game config, with `type: Phaser.WEBGL`. `attributes` are the context's, defaulting to Phaser's
63
+ * (opaque, antialiased, premultiplied, with a stencil buffer, on the high-performance GPU). `gl` is the context;
64
+ * `context` is the same object, typed to fit whatever Phaser's config declares (a 2D context, in 4.2.1).
65
+ */
66
+ export declare function createPhaserContext(canvas?: HTMLCanvasElement, attributes?: WebGLContextAttributes): {
67
+ canvas: HTMLCanvasElement;
68
+ context: never;
69
+ gl: WebGL2RenderingContext;
70
+ };
71
+ /**
72
+ * Translate every GLSL ES 1.00 shader compiled on `gl` to ES 3.00. Phaser 4's shaders are ES 1.00, and on a WebGL2
73
+ * context the ones that use derivatives (`Gradient`, noise objects with `noiseNormalMap`, `smoothPixelArt`) fail
74
+ * to compile, since `OES_standard_derivatives` is a WebGL1 extension (Phaser 4.2.1). Install it before
75
+ * `new Phaser.Game`; `createPhaserContext` does. Shaders that already declare `#version 300 es` pass through.
76
+ */
77
+ export declare function shimShaders(gl: WebGL2RenderingContext): void;
78
+ /** @internal GLSL ES 1.00 to 3.00, for the constructs Phaser's shaders use. Exported for tests. */
79
+ export declare function toEs300(source: string, fragment: boolean): string;
80
+ //# sourceMappingURL=phaser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phaser.d.ts","sourceRoot":"","sources":["../src/phaser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAA6C,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEpG,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE;QAAE,gBAAgB,EAAE,gBAAgB,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,kHAAkH;IAClH,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,qBAAqB,GAAG,sBAAsB,CAAC;IACnD,SAAS,EAAE;QAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;KAAE,CAAC;CAC9D;AAED,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,gEAAgE;AAChE,MAAM,WAAW,YAAY;IAC3B,MAAM,CACJ,QAAQ,EAAE,mBAAmB,EAC7B,cAAc,EAAE,oBAAoB,EACpC,UAAU,EAAE,YAAY,EACxB,WAAW,CAAC,EAAE,OAAO,EACrB,gBAAgB,CAAC,EAAE,MAAM,GACxB,IAAI,CAAC;IACR,IAAI,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC;CAC/C;AAED,MAAM,WAAW,YAAY;IAC3B,qIAAqI;IACrI,QAAQ,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAC3B,8EAA8E;IAC9E,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,EAAE,OAAO,GAAE,qBAA0B,GAAG,YAAY,CA2BlI;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,GAAE,iBAAoD,EAC5D,UAAU,GAAE,sBAA2B,GACtC;IAAE,MAAM,EAAE,iBAAiB,CAAC;IAAC,OAAO,EAAE,KAAK,CAAC;IAAC,EAAE,EAAE,sBAAsB,CAAA;CAAE,CAY3E;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EAAE,EAAE,sBAAsB,GAAG,IAAI,CAmB5D;AAUD,mGAAmG;AACnG,wBAAgB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,MAAM,CASjE"}
package/dist/phaser.js ADDED
@@ -0,0 +1,100 @@
1
+ import { createSharedRenderer } from "./shared.js";
2
+ /**
3
+ * Draw with spryte in an `Extern`'s slot: `render` is called each frame with a `Draw` whose transform is the
4
+ * Extern's `calcMatrix` (the camera, and any Container it's in), so world coordinates are Phaser's. Filters on the
5
+ * Extern or its camera, camera viewports and `Stencil` masks apply, since spryte draws into Phaser's drawing context
6
+ * under its state. The game must run on a WebGL2 context (`createPhaserContext`).
7
+ */
8
+ export function spryteExtern(extern, render, options = {}) {
9
+ let shared = null;
10
+ extern.render = (renderer, context, m) => {
11
+ const gl = renderer.gl;
12
+ if (typeof WebGL2RenderingContext === "undefined" || !(gl instanceof WebGL2RenderingContext))
13
+ throw new Error("spryte/phaser: Phaser is on a WebGL1 context. Create the game with `...createPhaserContext()` in its config.");
14
+ shared ??= createSharedRenderer(gl, options);
15
+ // Phaser's full state for this destination, forced: it has only reset blend, VAO and textures for the Extern.
16
+ renderer.glWrapper.update(context.state, true);
17
+ shared.target(context.framebuffer?.webGLFramebuffer ?? null, context.width, context.height);
18
+ const draw = shared.draw;
19
+ draw.begin(null, context.width, context.height, 1);
20
+ draw.transform(m.a, m.b, m.c, m.d, m.e, m.f);
21
+ render(draw);
22
+ draw.end();
23
+ };
24
+ const dispose = () => {
25
+ shared?.draw.dispose();
26
+ shared = null;
27
+ };
28
+ extern.once?.("destroy", dispose);
29
+ return {
30
+ get draw() {
31
+ return shared?.draw ?? null;
32
+ },
33
+ dispose,
34
+ };
35
+ }
36
+ /**
37
+ * A WebGL2 context for Phaser to run on, with its shaders translated to GLSL ES 3.00 (`shimShaders`). Spread the
38
+ * result into the game config, with `type: Phaser.WEBGL`. `attributes` are the context's, defaulting to Phaser's
39
+ * (opaque, antialiased, premultiplied, with a stencil buffer, on the high-performance GPU). `gl` is the context;
40
+ * `context` is the same object, typed to fit whatever Phaser's config declares (a 2D context, in 4.2.1).
41
+ */
42
+ export function createPhaserContext(canvas = document.createElement("canvas"), attributes = {}) {
43
+ const gl = canvas.getContext("webgl2", {
44
+ alpha: false,
45
+ antialias: true,
46
+ premultipliedAlpha: true,
47
+ stencil: true,
48
+ powerPreference: "high-performance",
49
+ ...attributes,
50
+ });
51
+ if (!gl)
52
+ throw new Error("spryte/phaser: WebGL2 is unavailable in this browser");
53
+ shimShaders(gl);
54
+ return { canvas, context: gl, gl };
55
+ }
56
+ /**
57
+ * Translate every GLSL ES 1.00 shader compiled on `gl` to ES 3.00. Phaser 4's shaders are ES 1.00, and on a WebGL2
58
+ * context the ones that use derivatives (`Gradient`, noise objects with `noiseNormalMap`, `smoothPixelArt`) fail
59
+ * to compile, since `OES_standard_derivatives` is a WebGL1 extension (Phaser 4.2.1). Install it before
60
+ * `new Phaser.Game`; `createPhaserContext` does. Shaders that already declare `#version 300 es` pass through.
61
+ */
62
+ export function shimShaders(gl) {
63
+ const types = new WeakMap();
64
+ const createShader = gl.createShader.bind(gl);
65
+ gl.createShader = (type) => {
66
+ const shader = createShader(type);
67
+ if (shader)
68
+ types.set(shader, type);
69
+ return shader;
70
+ };
71
+ const shaderSource = gl.shaderSource.bind(gl);
72
+ gl.shaderSource = (shader, source) => shaderSource(shader, /^\s*#version\s+300/.test(source) ? source : toEs300(source, types.get(shader) === gl.FRAGMENT_SHADER));
73
+ // Uniforms and attributes renamed in the source are looked up and bound by their new names.
74
+ const getUniformLocation = gl.getUniformLocation.bind(gl);
75
+ gl.getUniformLocation = (program, name) => getUniformLocation(program, renameIdentifier(name));
76
+ const getAttribLocation = gl.getAttribLocation.bind(gl);
77
+ gl.getAttribLocation = (program, name) => getAttribLocation(program, renameIdentifier(name));
78
+ const bindAttribLocation = gl.bindAttribLocation.bind(gl);
79
+ gl.bindAttribLocation = (program, index, name) => bindAttribLocation(program, index, renameIdentifier(name));
80
+ }
81
+ /** Identifiers that are keywords or built-in functions in ES 3.00 but were free in ES 1.00. */
82
+ const RESERVED = /\b(sample|centroid|smooth|layout|patch|uint|uvec[234]|texture)\b/g;
83
+ /** A uniform or attribute name (`smooth`, `smooth[0]`, `light.sample`) as `toEs300` renamed it. */
84
+ function renameIdentifier(name) {
85
+ return name.replace(RESERVED, "$1_");
86
+ }
87
+ /** @internal GLSL ES 1.00 to 3.00, for the constructs Phaser's shaders use. Exported for tests. */
88
+ export function toEs300(source, fragment) {
89
+ let out = source
90
+ .replace(/^[ \t]*#version\s+100.*$/m, "")
91
+ .replace(/^[ \t]*#extension\s+GL_(OES_standard_derivatives|EXT_shader_texture_lod)\b.*$/gm, "")
92
+ .replace(RESERVED, "$1_")
93
+ .replace(/\btexture(2D|Cube)(Lod|Proj)?(EXT)?\b/g, (_, _dim, fn) => (fn ? `texture${fn}` : "texture"));
94
+ if (fragment)
95
+ out = out.replace(/\bvarying\b/g, "in").replace(/\bgl_FragColor\b/g, "spryte_FragColor");
96
+ else
97
+ out = out.replace(/\battribute\b/g, "in").replace(/\bvarying\b/g, "out");
98
+ return `#version 300 es\n${fragment ? "out highp vec4 spryte_FragColor;\n" : ""}${out}`;
99
+ }
100
+ //# sourceMappingURL=phaser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phaser.js","sourceRoot":"","sources":["../src/phaser.ts"],"names":[],"mappings":"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"}
package/dist/renderer.js CHANGED
@@ -45,6 +45,7 @@ function pending(ctx) {
45
45
  raw: { kind: "2d", ctx },
46
46
  begin: noop,
47
47
  quad: noop,
48
+ path: noop,
48
49
  quads: noop,
49
50
  copies: noop,
50
51
  setBlend: noop,
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAe5C;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,MAAyB,EAAE,OAAO,GAAoB,EAAE;IACrF,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC;IACzC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,qGAAqG;QACrG,sGAAsG;QACtG,qFAAqF;QACrF,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE;YACrC,KAAK,EAAE,OAAO,CAAC,WAAW,IAAI,KAAK;YACnC,SAAS,EAAE,KAAK;YAChB,kBAAkB,EAAE,IAAI;YACxB,eAAe,EAAE,kBAAkB;SACpC,CAAC,CAAC;QACH,IAAI,EAAE;YAAE,OAAO,IAAI,IAAI,CAAC,IAAI,aAAa,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;QACvE,IAAI,MAAM,KAAK,QAAQ;YACrB,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAC;IACrH,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,IAAI,KAAK,EAAE,CAAC,CAAC;IAC7E,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,sGAAsG,CAAC,CAAC;IAClI,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;IAC5D,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,EAClD,CAAC,KAAK,EAAE,EAAE;QACR,MAAM,IAAI,KAAK,CAAC,+CAA+C,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC,CACF,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,GAA6B;IAC5C,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IACtB,OAAO;QACL,IAAI,EAAE,IAAI;QACV,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;QACxB,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,IAAI;QACb,GAAG,EAAE,IAAI;QACT,MAAM,EAAE,IAAI;QACZ,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAe5C;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,MAAyB,EAAE,OAAO,GAAoB,EAAE;IACrF,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC;IACzC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,qGAAqG;QACrG,sGAAsG;QACtG,qFAAqF;QACrF,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE;YACrC,KAAK,EAAE,OAAO,CAAC,WAAW,IAAI,KAAK;YACnC,SAAS,EAAE,KAAK;YAChB,kBAAkB,EAAE,IAAI;YACxB,eAAe,EAAE,kBAAkB;SACpC,CAAC,CAAC;QACH,IAAI,EAAE;YAAE,OAAO,IAAI,IAAI,CAAC,IAAI,aAAa,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;QACvE,IAAI,MAAM,KAAK,QAAQ;YACrB,MAAM,IAAI,KAAK,CAAC,+FAA+F,CAAC,CAAC;IACrH,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,WAAW,IAAI,KAAK,EAAE,CAAC,CAAC;IAC7E,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,sGAAsG,CAAC,CAAC;IAClI,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;IAC5D,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CACvC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,EAClD,CAAC,KAAK,EAAE,EAAE;QACR,MAAM,IAAI,KAAK,CAAC,+CAA+C,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC,CACF,CAAC;IACF,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,SAAS,OAAO,CAAC,GAA6B;IAC5C,MAAM,IAAI,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IACtB,OAAO;QACL,IAAI,EAAE,IAAI;QACV,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;QACxB,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,IAAI;QACV,IAAI,EAAE,IAAI;QACV,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,IAAI;QACd,OAAO,EAAE,IAAI;QACb,GAAG,EAAE,IAAI;QACT,MAAM,EAAE,IAAI;QACZ,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;QACf,SAAS,EAAE,IAAI;QACf,aAAa,EAAE,IAAI;QACnB,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC"}
@@ -0,0 +1,64 @@
1
+ import type { Matrix } from "./backend.js";
2
+ import { type Color } from "./color.js";
3
+ import type { Draw } from "./draw.js";
4
+ /**
5
+ * Filled polygon through `points` (x0, y0, x1, y1, …), antialiased. Concave is fine; it closes itself and
6
+ * shouldn't cross itself. `count` defaults to every pair in `points`.
7
+ *
8
+ * ```ts
9
+ * import { polygon } from "spryte";
10
+ * polygon(draw, [0, 0, 20, 0, 10, 16], "#cffb2d");
11
+ * ```
12
+ */
13
+ export declare function polygon(draw: Draw, points: ArrayLike<number>, color: Color, count?: number): void;
14
+ /** Line through `points` (x0, y0, x1, y1, …), `width` wide, with mitred joins and flat ends. `closed` joins the last point to the first. */
15
+ export declare function polyline(draw: Draw, points: ArrayLike<number>, width: number, color: Color, closed?: boolean, count?: number): void;
16
+ /** Rectangle with rounded corners: filled, or outlined when `lineWidth` is given (the outline is centred on the edge). */
17
+ export declare function roundRect(draw: Draw, x: number, y: number, w: number, h: number, radius: number, color: Color, lineWidth?: number): void;
18
+ /** Circle outline, `width` wide, centred on `radius`. */
19
+ export declare function ring(draw: Draw, x: number, y: number, radius: number, width: number, color: Color): void;
20
+ /**
21
+ * Indexed triangles for the WebGL2 backend's `path()`: x, y, u, v (floats), a colour (RGBA bytes) and coverage,
22
+ * flash and texture unit (bytes) per vertex, 24 bytes. Sprites can join as textured quads (`sprite`). Edges get a feather one device pixel wide fading to coverage 0, which antialiases without MSAA.
23
+ * @internal
24
+ */
25
+ export declare class ShapeBuffer {
26
+ data: ArrayBuffer;
27
+ f32: Float32Array<ArrayBuffer>;
28
+ u32: Uint32Array<ArrayBuffer>;
29
+ indices: Uint32Array<ArrayBuffer>;
30
+ /** Vertices and indices written. */
31
+ count: number;
32
+ icount: number;
33
+ private m;
34
+ private color;
35
+ private xs;
36
+ private ys;
37
+ private nx;
38
+ private ny;
39
+ /** The inner ring of a fill, in the points' units (for ear clipping). */
40
+ private ix;
41
+ private iy;
42
+ /** Fill (`width` 0) or stroke `n` points. `aa` is one device pixel in the points' units; `color` is RGBA bytes in memory order. */
43
+ add(m: Matrix, points: ArrayLike<number>, n: number, closed: boolean, width: number, color: number, aa: number): void;
44
+ /** Copy points, dropping repeats; returns how many are left. Closed shapes also drop a last point equal to the first. */
45
+ private load;
46
+ /** Miter normals (left of travel) scaled so offsetting by 1 moves each edge by 1, clamped at MITER. */
47
+ private normals;
48
+ private fill;
49
+ private stroke;
50
+ /** Room for `v` more vertices and `i` more indices; returns the first new vertex's index. */
51
+ private reserve;
52
+ /** Two triangles joining edge (a, b) to edge (c, d). */
53
+ private quad;
54
+ private tri;
55
+ /** A textured quad: the unit square through `m`, sampling `u0, v0, u1, v1` from texture `unit`. */
56
+ sprite(m: Matrix, u0: number, v0: number, u1: number, v1: number, color: number, flash: number, unit: number): void;
57
+ private vertex;
58
+ }
59
+ /**
60
+ * Triangulate a simple polygon wound so its interior is on the left (positive signed area in y-down space).
61
+ * O(n²), fine for UI and debug shapes. Self-intersecting input still produces triangles, just not exact ones.
62
+ */
63
+ export declare function earClip(xs: ArrayLike<number>, ys: ArrayLike<number>, n: number, tri: (a: number, b: number, c: number) => void): void;
64
+ //# sourceMappingURL=shapes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shapes.d.ts","sourceRoot":"","sources":["../src/shapes.ts"],"names":[],"mappings":"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"}