@codexo/exojs 0.10.0 → 0.11.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 (90) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/dist/esm/core/dev.d.ts +21 -0
  3. package/dist/esm/core/dev.js +18 -0
  4. package/dist/esm/core/dev.js.map +1 -0
  5. package/dist/esm/particles/modules/AlphaFadeOverLifetime.d.ts +2 -2
  6. package/dist/esm/particles/modules/AlphaFadeOverLifetime.js +5 -1
  7. package/dist/esm/particles/modules/AlphaFadeOverLifetime.js.map +1 -1
  8. package/dist/esm/rendering/TransformBuffer.d.ts +44 -0
  9. package/dist/esm/rendering/TransformBuffer.js +64 -0
  10. package/dist/esm/rendering/TransformBuffer.js.map +1 -1
  11. package/dist/esm/rendering/gradient/Gradient.d.ts +35 -2
  12. package/dist/esm/rendering/gradient/Gradient.js +51 -5
  13. package/dist/esm/rendering/gradient/Gradient.js.map +1 -1
  14. package/dist/esm/rendering/gradient/LinearGradient.d.ts +11 -3
  15. package/dist/esm/rendering/gradient/LinearGradient.js +23 -0
  16. package/dist/esm/rendering/gradient/LinearGradient.js.map +1 -1
  17. package/dist/esm/rendering/gradient/RadialGradient.d.ts +11 -3
  18. package/dist/esm/rendering/gradient/RadialGradient.js +19 -0
  19. package/dist/esm/rendering/gradient/RadialGradient.js.map +1 -1
  20. package/dist/esm/rendering/index.d.ts +1 -1
  21. package/dist/esm/rendering/pass/RenderPassCoordinator.d.ts +2 -2
  22. package/dist/esm/rendering/pass/RenderPassDescriptor.d.ts +2 -2
  23. package/dist/esm/rendering/pass/RenderPassDescriptor.js +1 -1
  24. package/dist/esm/rendering/plan/RenderCommand.d.ts +21 -2
  25. package/dist/esm/rendering/plan/RenderCommand.js +34 -1
  26. package/dist/esm/rendering/plan/RenderCommand.js.map +1 -1
  27. package/dist/esm/rendering/plan/RenderInstruction.d.ts +51 -0
  28. package/dist/esm/rendering/plan/RenderInstruction.js +45 -0
  29. package/dist/esm/rendering/plan/RenderInstruction.js.map +1 -0
  30. package/dist/esm/rendering/plan/RenderPlanPlayer.d.ts +4 -0
  31. package/dist/esm/rendering/plan/RenderPlanPlayer.js +58 -7
  32. package/dist/esm/rendering/plan/RenderPlanPlayer.js.map +1 -1
  33. package/dist/esm/rendering/primitives/Graphics.d.ts +70 -5
  34. package/dist/esm/rendering/primitives/Graphics.js +172 -14
  35. package/dist/esm/rendering/primitives/Graphics.js.map +1 -1
  36. package/dist/esm/rendering/sprite/spriteMaterialSources.d.ts +13 -8
  37. package/dist/esm/rendering/sprite/spriteMaterialSources.js +35 -14
  38. package/dist/esm/rendering/sprite/spriteMaterialSources.js.map +1 -1
  39. package/dist/esm/rendering/text/BitmapText.d.ts +2 -0
  40. package/dist/esm/rendering/text/BitmapText.js +8 -1
  41. package/dist/esm/rendering/text/BitmapText.js.map +1 -1
  42. package/dist/esm/rendering/text/BmFont.js +3 -0
  43. package/dist/esm/rendering/text/BmFont.js.map +1 -1
  44. package/dist/esm/rendering/text/GlyphSdf.d.ts +14 -0
  45. package/dist/esm/rendering/text/GlyphSdf.js +41 -11
  46. package/dist/esm/rendering/text/GlyphSdf.js.map +1 -1
  47. package/dist/esm/rendering/text/TextStyle.d.ts +5 -0
  48. package/dist/esm/rendering/text/TextStyle.js +1 -1
  49. package/dist/esm/rendering/text/TextStyle.js.map +1 -1
  50. package/dist/esm/rendering/texture/RenderTexture.js.map +1 -1
  51. package/dist/esm/rendering/webgl2/WebGl2Backend.d.ts +23 -1
  52. package/dist/esm/rendering/webgl2/WebGl2Backend.js +50 -0
  53. package/dist/esm/rendering/webgl2/WebGl2Backend.js.map +1 -1
  54. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js +3 -3
  55. package/dist/esm/rendering/webgl2/WebGl2MeshRenderer.js.map +1 -1
  56. package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.d.ts +8 -0
  57. package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.js +8 -0
  58. package/dist/esm/rendering/webgl2/WebGl2ParticleRenderer.js.map +1 -1
  59. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.d.ts +2 -0
  60. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js +62 -39
  61. package/dist/esm/rendering/webgl2/WebGl2SpriteRenderer.js.map +1 -1
  62. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.d.ts +7 -0
  63. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.js +7 -0
  64. package/dist/esm/rendering/webgl2/WebGl2TextRenderer.js.map +1 -1
  65. package/dist/esm/rendering/webgl2/glsl/sprite.vert.js +1 -1
  66. package/dist/esm/rendering/webgl2/glsl/text-color.frag.js +1 -1
  67. package/dist/esm/rendering/webgpu/WebGpuBackend.d.ts +16 -3
  68. package/dist/esm/rendering/webgpu/WebGpuBackend.js +49 -4
  69. package/dist/esm/rendering/webgpu/WebGpuBackend.js.map +1 -1
  70. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js +53 -41
  71. package/dist/esm/rendering/webgpu/WebGpuMeshRenderer.js.map +1 -1
  72. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.d.ts +7 -0
  73. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js +17 -11
  74. package/dist/esm/rendering/webgpu/WebGpuParticleRenderer.js.map +1 -1
  75. package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.d.ts +2 -2
  76. package/dist/esm/rendering/webgpu/WebGpuPassCoordinator.js +2 -2
  77. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.d.ts +9 -1
  78. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js +122 -77
  79. package/dist/esm/rendering/webgpu/WebGpuSpriteRenderer.js.map +1 -1
  80. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.d.ts +7 -0
  81. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.js +22 -13
  82. package/dist/esm/rendering/webgpu/WebGpuTextRenderer.js.map +1 -1
  83. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.d.ts +32 -0
  84. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js +58 -12
  85. package/dist/esm/rendering/webgpu/WebGpuTransformStorage.js.map +1 -1
  86. package/dist/esm/resources/Loader.js +1 -1
  87. package/dist/esm/resources/Loader.js.map +1 -1
  88. package/dist/exo.esm.js +1022 -265
  89. package/dist/exo.esm.js.map +1 -1
  90. package/package.json +9 -5
package/CHANGELOG.md CHANGED
@@ -4,6 +4,89 @@ All notable changes to ExoJS are documented in this file.
4
4
 
5
5
  The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
6
 
7
+ ## [Unreleased]
8
+
9
+ Release notes are curated at release time, not per pull request. When a version
10
+ is cut, this section is renamed to `## [x.y.z] - YYYY-MM-DD` and filled from the
11
+ merged pull requests and commits since the previous tag (each with its commit /
12
+ PR link); `pnpm release:notes` then renders that section into the published
13
+ GitHub release with a `PREVIOUS_TAG...CURRENT_TAG` compare link.
14
+
15
+ ## [0.11.0] - 2026-06-04
16
+
17
+ ### Added
18
+
19
+ - **WebGPU geometry stencil completion.** WebGPU now supports geometric stencil
20
+ clipping across custom-material pipelines (Sprite, Mesh, Graphics), reaching
21
+ pixel parity with WebGL2 for all default and custom material paths. (#41, #43)
22
+
23
+ - **Graphics gradient fills.** `Graphics` primitives now accept `LinearGradient`
24
+ and `RadialGradient` fills via `fillGradient` and `strokeGradient` style
25
+ properties. `Gradient` was promoted to a `Color`-like value object with
26
+ `lerp()` and `toArray()` methods. A `graphics-gradient` example demonstrates
27
+ cross-backend gradient rendering with pixel-validated test coverage.
28
+ (#52, #53, #55, #56, #57)
29
+
30
+ - **`BitmapText` diagnostics and demo.** Added `BitmapText` rendering with BMFont
31
+ diagnostics utilities and a `bitmap-text-basic` example demonstrating bitmap
32
+ font rendering, character set inspection, and layout options. (#66)
33
+
34
+ - **`assert()` dev diagnostics.** Added a lightweight assertion utility
35
+ (`assert(condition, message)`) for development-time invariant checking.
36
+ Assertions are stripped in production builds. (#67)
37
+
38
+ - **TypeScript-first examples migration.** All 117 example files converted from
39
+ JavaScript to TypeScript across the full examples tree: application-scenes,
40
+ sprites-textures, input, text-fonts, scene-graph, tweens-animation, filters,
41
+ debug-layer, audio-basics, audio-fx, beat-detection, particles, performance,
42
+ geometry-graphics, render-targets, custom-renderers, and showcase. The
43
+ playground example pilot added type-safe example loading.
44
+ (#68, #69, #70, #71, #72, #73, #74, #75, #76, #77, #78, #79)
45
+
46
+ - **`@assets` import-map module.** Examples can now reference bundled assets via
47
+ `@assets/...` import paths, with the `Loader` supporting absolute-path
48
+ resolution for this scheme. (#65)
49
+
50
+ - **Multi-browser + dark-mode smoke support.** The example smoke test runner now
51
+ supports dark color-scheme canvases and resolves a WebGPU feature-flag conflict
52
+ during multi-browser runs.
53
+
54
+ ### Performance
55
+
56
+ - **Render pipeline hot-path profiling.** Instrumented the render-plan path to
57
+ identify and eliminate bottlenecks in render command processing and group
58
+ compaction. (#80)
59
+
60
+ - **Batched transform storage writes.** `TransformBuffer` uploads are now batched
61
+ by render group, reducing per-node `device.writeBuffer` calls and improving
62
+ render-plan playback throughput. WebGPU transform storage is pre-reserved
63
+ before playback to eliminate mid-frame reallocation. (#44, #45, #46, #48, #50)
64
+
65
+ ### Fixed
66
+
67
+ - **GLSL reserved word.** Fixed a WebGL2 text shader that used `text` as a
68
+ variable name (a reserved word in GLSL ES 3.00), resolving compilation failures
69
+ on strict drivers. (#60)
70
+
71
+ - **SDF text baseline alignment.** Corrected SDF tile height computation to use
72
+ font-level metrics, fixing vertical misalignment in multi-font and mixed-size
73
+ text layouts. (#62, #63)
74
+
75
+ - **WebGPU mesh tint normalisation.** Mesh tint values on the WebGPU path are now
76
+ normalised to the 0-1 range before upload, matching WebGL2 behaviour. (#54)
77
+
78
+ - **WebGPU Uint16 index-buffer alignment.** `Uint16` index-buffer writes are now
79
+ aligned to 4-byte boundaries on WebGPU, preventing alignment violations on
80
+ hardware that enforces `COPY_DST` buffer offset restrictions.
81
+
82
+ - **Loader `@assets/` absolute-path resolution.** The `Loader` now correctly
83
+ resolves absolute paths when using the `@assets/` import-map scheme, fixing
84
+ failed asset loads in playground and bundled example deployments. (#65)
85
+
86
+ - **Example runtime health.** Repaired broken examples across the catalog
87
+ including text layout rendering, playground navigation stability, style option
88
+ migration, and smoke test failures. (#58, #59, #61, #64)
89
+
7
90
  ## [0.10.0] - 2026-05-31
8
91
 
9
92
  ### Breaking — RenderingContext and Scene.draw migration
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Assert `condition` at dev/test time. Throws with `[ExoJS] message` when the
3
+ * condition is falsy and `__DEV__` is true. No-op in production builds.
4
+ */
5
+ export declare function assert(condition: boolean, message: string): asserts condition;
6
+ /**
7
+ * Assert that `value` is neither `null` nor `undefined`. Returns the value so
8
+ * it can be used inline in an expression. No-op in production builds (returns
9
+ * the value cast to `T` without checking).
10
+ */
11
+ export declare function assertDefined<T>(value: T | null | undefined, message: string): T;
12
+ /** @internal — alias for {@link assert}; kept for backward compatibility. */
13
+ export declare function invariant(condition: boolean, message: string): asserts condition;
14
+ /**
15
+ * Print a `console.warn` at most once per unique `key`.
16
+ * Subsequent calls with the same key are silenced to avoid per-frame spam.
17
+ * No-op in production builds.
18
+ */
19
+ export declare function warnOnce(key: string, message: string): void;
20
+ /** @internal — clears the warned-keys set. For unit tests only. */
21
+ export declare function _resetWarnOnce(): void;
@@ -0,0 +1,18 @@
1
+ // Internal dev/diagnostic utilities. Guards are stripped in production builds
2
+ // when false is replaced with `false` by the rollup replace plugin.
3
+ /**
4
+ * Assert `condition` at dev/test time. Throws with `[ExoJS] message` when the
5
+ * condition is falsy and `false` is true. No-op in production builds.
6
+ */
7
+ function assert(condition, message) {
8
+ }
9
+ /**
10
+ * Print a `console.warn` at most once per unique `key`.
11
+ * Subsequent calls with the same key are silenced to avoid per-frame spam.
12
+ * No-op in production builds.
13
+ */
14
+ function warnOnce(key, message) {
15
+ }
16
+
17
+ export { assert, warnOnce };
18
+ //# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.js","sources":["../../../../src/core/dev.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;AACA;AAIA;;;AAGG;AACG,SAAU,MAAM,CAAC,SAAkB,EAAE,OAAe,EAAA;AAI1D;AAmBA;;;;AAIG;AACG,SAAU,QAAQ,CAAC,GAAW,EAAE,OAAe,EAAA;AAMrD;;;;"}
@@ -1,4 +1,4 @@
1
- import type { Curve } from '@/particles/distributions/Curve';
1
+ import { Curve } from '@/particles/distributions/Curve';
2
2
  import type { ParticleSystem } from '@/particles/ParticleSystem';
3
3
  import { UpdateModule } from './UpdateModule';
4
4
  import type { WgslContribution } from './WgslContribution';
@@ -17,7 +17,7 @@ import type { WgslContribution } from './WgslContribution';
17
17
  */
18
18
  export declare class AlphaFadeOverLifetime extends UpdateModule {
19
19
  curve: Curve;
20
- constructor(curve: Curve);
20
+ constructor(curve?: Curve);
21
21
  apply(system: ParticleSystem, _dt: number): void;
22
22
  wgsl(): WgslContribution;
23
23
  uploadTextures(device: GPUDevice, textures: ReadonlyMap<string, GPUTexture>): void;
@@ -1,3 +1,4 @@
1
+ import { Curve } from '../distributions/Curve.js';
1
2
  import { UpdateModule } from './UpdateModule.js';
2
3
 
3
4
  /// <reference types="@webgpu/types" />
@@ -17,7 +18,10 @@ const lookupSize = 256;
17
18
  */
18
19
  class AlphaFadeOverLifetime extends UpdateModule {
19
20
  curve;
20
- constructor(curve) {
21
+ constructor(curve = new Curve([
22
+ { t: 0, v: 1 },
23
+ { t: 1, v: 0 },
24
+ ])) {
21
25
  super();
22
26
  this.curve = curve;
23
27
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AlphaFadeOverLifetime.js","sources":["../../../../../src/particles/modules/AlphaFadeOverLifetime.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAAA;AAQA,MAAM,UAAU,GAAG,GAAG;AAEtB;;;;;;;;;;;;AAYG;AACG,MAAO,qBAAsB,SAAQ,YAAY,CAAA;AAC9C,IAAA,KAAK;AAEZ,IAAA,WAAA,CAAmB,KAAY,EAAA;AAC7B,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;IACpB;IAEgB,KAAK,CAAC,MAAsB,EAAE,GAAW,EAAA;QACvD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM;AACtD,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK;AAExB,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;YAClC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;YAClC,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC3B,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG;AAE3D,YAAA,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,KAAK,SAAS,IAAI,EAAE,CAAC;QACxD;IACF;IAEgB,IAAI,GAAA;QAClB,OAAO;AACL,YAAA,GAAG,EAAE,uBAAuB;YAC5B,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AACjD,YAAA,IAAI,EAAE;;;;;AAKC,YAAA,CAAA;SACR;IACH;IAEgB,cAAc,CAAC,MAAiB,EAAE,QAAyC,EAAA;QACzF,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;AAErC,QAAA,IAAI,OAAO,KAAK,SAAS,EAAE;YACzB;QACF;AAEA,QAAA,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC;AAEzC,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE;AACnC,YAAA,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC;QACrD;AAEA,QAAA,MAAM,CAAC,KAAK,CAAC,YAAY,CACvB,EAAE,OAAO,EAAE,EACX,IAAI,CAAC,MAAM,EACX,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,UAAU,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,EAC3D,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,CACxD;IACH;AACD;;;;"}
1
+ {"version":3,"file":"AlphaFadeOverLifetime.js","sources":["../../../../../src/particles/modules/AlphaFadeOverLifetime.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAAA;AAQA,MAAM,UAAU,GAAG,GAAG;AAEtB;;;;;;;;;;;;AAYG;AACG,MAAO,qBAAsB,SAAQ,YAAY,CAAA;AAC9C,IAAA,KAAK;IAEZ,WAAA,CACE,KAAA,GAAe,IAAI,KAAK,CAAC;AACvB,QAAA,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;AACd,QAAA,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE;KACf,CAAC,EAAA;AAEF,QAAA,KAAK,EAAE;AACP,QAAA,IAAI,CAAC,KAAK,GAAG,KAAK;IACpB;IAEgB,KAAK,CAAC,MAAsB,EAAE,GAAW,EAAA;QACvD,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,MAAM;AACtD,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK;AAExB,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE;YAClC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;YAClC,MAAM,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC3B,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,GAAG;AAE3D,YAAA,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,UAAU,KAAK,SAAS,IAAI,EAAE,CAAC;QACxD;IACF;IAEgB,IAAI,GAAA;QAClB,OAAO;AACL,YAAA,GAAG,EAAE,uBAAuB;YAC5B,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;AACjD,YAAA,IAAI,EAAE;;;;;AAKC,YAAA,CAAA;SACR;IACH;IAEgB,cAAc,CAAC,MAAiB,EAAE,QAAyC,EAAA;QACzF,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC;AAErC,QAAA,IAAI,OAAO,KAAK,SAAS,EAAE;YACzB;QACF;AAEA,QAAA,MAAM,IAAI,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC;AAEzC,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE;AACnC,YAAA,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC;QACrD;AAEA,QAAA,MAAM,CAAC,KAAK,CAAC,YAAY,CACvB,EAAE,OAAO,EAAE,EACX,IAAI,CAAC,MAAM,EACX,EAAE,MAAM,EAAE,CAAC,EAAE,WAAW,EAAE,UAAU,GAAG,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,EAC3D,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,CACxD;IACH;AACD;;;;"}
@@ -24,13 +24,57 @@ export declare class TransformBuffer {
24
24
  private _frameHash;
25
25
  private _lastCommittedHash;
26
26
  private _lastCommittedCount;
27
+ private _writeCount;
28
+ private _skippedWriteCount;
29
+ private _uploadCount;
30
+ private _uploadedRecordCount;
27
31
  get count(): number;
32
+ /**
33
+ * Number of transform rows written into the buffer (via {@link write} /
34
+ * {@link push}) since the last {@link begin}. Internal stat for profiling and
35
+ * regression guards; does not affect packing.
36
+ * @internal
37
+ */
38
+ get writeCount(): number;
39
+ /**
40
+ * Number of draw commands whose transform write was skipped since the last
41
+ * {@link begin} — recorded by the backend for renderers that opt out of the
42
+ * shared transform storage (`_consumesSharedTransform === false`).
43
+ * @internal
44
+ */
45
+ get skippedWriteCount(): number;
46
+ /**
47
+ * Number of GPU uploads (texture / storage writes) issued for this buffer
48
+ * since the last {@link begin}. Recorded by the backend at its upload
49
+ * boundary; an unchanged frame uploads zero times.
50
+ * @internal
51
+ */
52
+ get uploadCount(): number;
53
+ /**
54
+ * Total transform rows pushed to the GPU across all uploads since the last
55
+ * {@link begin}.
56
+ * @internal
57
+ */
58
+ get uploadedRecordCount(): number;
28
59
  get capacity(): number;
29
60
  get data(): Float32Array;
30
61
  get version(): number;
31
62
  begin(expectedCount?: number): this;
32
63
  push(transform: Matrix, tint: Color): number;
33
64
  write(slot: number, transform: Matrix, tint: Color): this;
65
+ /**
66
+ * Record that a draw command's transform write was intentionally skipped
67
+ * because its renderer opts out of the shared transform storage. Counts
68
+ * toward {@link skippedWriteCount} only — buffer contents are untouched.
69
+ * @internal
70
+ */
71
+ recordSkippedWrite(): this;
72
+ /**
73
+ * Record a GPU upload of `recordCount` transform rows. Called by the backend
74
+ * at its upload boundary after committing a snapshot; affects stats only.
75
+ * @internal
76
+ */
77
+ recordUpload(recordCount: number): this;
34
78
  commitSnapshot(minCount?: number): TransformBufferFrameSnapshot;
35
79
  private _ensureCapacity;
36
80
  private _hashFloat;
@@ -21,9 +21,48 @@ class TransformBuffer {
21
21
  _frameHash = hashOffset >>> 0;
22
22
  _lastCommittedHash = 0;
23
23
  _lastCommittedCount = -1;
24
+ _writeCount = 0;
25
+ _skippedWriteCount = 0;
26
+ _uploadCount = 0;
27
+ _uploadedRecordCount = 0;
24
28
  get count() {
25
29
  return this._count;
26
30
  }
31
+ /**
32
+ * Number of transform rows written into the buffer (via {@link write} /
33
+ * {@link push}) since the last {@link begin}. Internal stat for profiling and
34
+ * regression guards; does not affect packing.
35
+ * @internal
36
+ */
37
+ get writeCount() {
38
+ return this._writeCount;
39
+ }
40
+ /**
41
+ * Number of draw commands whose transform write was skipped since the last
42
+ * {@link begin} — recorded by the backend for renderers that opt out of the
43
+ * shared transform storage (`_consumesSharedTransform === false`).
44
+ * @internal
45
+ */
46
+ get skippedWriteCount() {
47
+ return this._skippedWriteCount;
48
+ }
49
+ /**
50
+ * Number of GPU uploads (texture / storage writes) issued for this buffer
51
+ * since the last {@link begin}. Recorded by the backend at its upload
52
+ * boundary; an unchanged frame uploads zero times.
53
+ * @internal
54
+ */
55
+ get uploadCount() {
56
+ return this._uploadCount;
57
+ }
58
+ /**
59
+ * Total transform rows pushed to the GPU across all uploads since the last
60
+ * {@link begin}.
61
+ * @internal
62
+ */
63
+ get uploadedRecordCount() {
64
+ return this._uploadedRecordCount;
65
+ }
27
66
  get capacity() {
28
67
  return this._data.length / floatsPerSlot;
29
68
  }
@@ -39,6 +78,10 @@ class TransformBuffer {
39
78
  }
40
79
  this._count = 0;
41
80
  this._frameHash = hashOffset >>> 0;
81
+ this._writeCount = 0;
82
+ this._skippedWriteCount = 0;
83
+ this._uploadCount = 0;
84
+ this._uploadedRecordCount = 0;
42
85
  return this;
43
86
  }
44
87
  push(transform, tint) {
@@ -72,6 +115,27 @@ class TransformBuffer {
72
115
  for (let i = 0; i < floatsPerSlot; i++) {
73
116
  this._frameHash = this._mix(this._frameHash, this._hashFloat(data[offset + i]));
74
117
  }
118
+ this._writeCount++;
119
+ return this;
120
+ }
121
+ /**
122
+ * Record that a draw command's transform write was intentionally skipped
123
+ * because its renderer opts out of the shared transform storage. Counts
124
+ * toward {@link skippedWriteCount} only — buffer contents are untouched.
125
+ * @internal
126
+ */
127
+ recordSkippedWrite() {
128
+ this._skippedWriteCount++;
129
+ return this;
130
+ }
131
+ /**
132
+ * Record a GPU upload of `recordCount` transform rows. Called by the backend
133
+ * at its upload boundary after committing a snapshot; affects stats only.
134
+ * @internal
135
+ */
136
+ recordUpload(recordCount) {
137
+ this._uploadCount++;
138
+ this._uploadedRecordCount += recordCount;
75
139
  return this;
76
140
  }
77
141
  commitSnapshot(minCount = 0) {
@@ -1 +1 @@
1
- {"version":3,"file":"TransformBuffer.js","sources":["../../../../src/rendering/TransformBuffer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TransformBuffer.js","sources":["../../../../src/rendering/TransformBuffer.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -1,6 +1,9 @@
1
1
  import type { Color } from '@/core/Color';
2
+ import type { Cloneable, Destroyable } from '@/core/types';
2
3
  import { DataTexture } from '@/rendering/texture/DataTexture';
3
4
  import type { SamplerOptions } from '@/rendering/texture/Sampler';
5
+ /** Discriminant identifying the concrete gradient kind (`gradient.type`). */
6
+ export type GradientType = 'linear' | 'radial';
4
7
  export interface GradientStop {
5
8
  offset: number;
6
9
  color: Color;
@@ -10,13 +13,34 @@ export interface GradientToTextureOptions {
10
13
  readonly samplerOptions?: Partial<SamplerOptions>;
11
14
  }
12
15
  /**
13
- * CPU-rasterized gradient base that can be converted into a {@link DataTexture}.
16
+ * CPU-rasterized gradient base. A {@link Color}-like paint value (not a
17
+ * {@link Drawable}): it owns a normalized list of color stops plus subclass
18
+ * geometry and supports the value-object contract — {@link Gradient.clone},
19
+ * {@link Gradient.copy}, and {@link Gradient.equals}. Stops are cloned on the
20
+ * way in, clamped to `0..1`, and kept sorted by offset.
21
+ *
22
+ * Convert a gradient into a sampleable {@link DataTexture} with
23
+ * {@link Gradient.toTexture}; wrap that texture in a `Sprite`/`Mesh` to draw it.
14
24
  */
15
- export declare abstract class Gradient {
25
+ export declare abstract class Gradient implements Cloneable, Destroyable {
26
+ /** Concrete gradient kind, e.g. `'linear'` or `'radial'`. */
27
+ abstract readonly type: GradientType;
16
28
  private _stops;
17
29
  private readonly _sample;
18
30
  protected constructor(stops: readonly GradientStop[]);
19
31
  get stops(): readonly GradientStop[];
32
+ /** Deep-clone into a new instance of the same concrete gradient type. */
33
+ abstract clone(): this;
34
+ /**
35
+ * Copy every value (stops and geometry) from a same-type `source` into this
36
+ * instance, replacing its current state. Returns `this` for chaining.
37
+ */
38
+ copy(source: this): this;
39
+ /**
40
+ * Structural value equality: same {@link GradientType}, same ordered stops
41
+ * (offset and {@link Color}), and same subclass geometry.
42
+ */
43
+ equals(other: Gradient): boolean;
20
44
  toTexture(width: number, height: number, options?: GradientToTextureOptions & {
21
45
  format?: 'rgba8';
22
46
  }): DataTexture<'rgba8'>;
@@ -25,10 +49,19 @@ export declare abstract class Gradient {
25
49
  }): DataTexture<'rgba32f'>;
26
50
  destroy(): void;
27
51
  protected abstract resolveT(u: number, v: number): number;
52
+ /** Copy the concrete subclass geometry from a same-type `source`. */
53
+ protected abstract _copyGeometry(source: this): void;
54
+ /**
55
+ * Compare the concrete subclass geometry against `other`. Only invoked once
56
+ * {@link Gradient.equals} has confirmed both sides share the same
57
+ * {@link GradientType}, so implementations may narrow `other` accordingly.
58
+ */
59
+ protected abstract _geometryEquals(other: Gradient): boolean;
28
60
  /**
29
61
  * Shared stop sampling logic ported from the legacy GLSL implementation.
30
62
  */
31
63
  protected sampleAt(t: number, out: Float32Array): void;
64
+ private static _normalizeStops;
32
65
  private _toRgba8Texture;
33
66
  private _toRgba32fTexture;
34
67
  }
@@ -3,20 +3,53 @@ import { DataTexture } from '../texture/DataTexture.js';
3
3
 
4
4
  const sortedStopOffset = (left, right) => left.offset - right.offset;
5
5
  /**
6
- * CPU-rasterized gradient base that can be converted into a {@link DataTexture}.
6
+ * CPU-rasterized gradient base. A {@link Color}-like paint value (not a
7
+ * {@link Drawable}): it owns a normalized list of color stops plus subclass
8
+ * geometry and supports the value-object contract — {@link Gradient.clone},
9
+ * {@link Gradient.copy}, and {@link Gradient.equals}. Stops are cloned on the
10
+ * way in, clamped to `0..1`, and kept sorted by offset.
11
+ *
12
+ * Convert a gradient into a sampleable {@link DataTexture} with
13
+ * {@link Gradient.toTexture}; wrap that texture in a `Sprite`/`Mesh` to draw it.
7
14
  */
8
15
  class Gradient {
9
16
  _stops;
10
17
  _sample = new Float32Array(4);
11
18
  constructor(stops) {
12
- if (stops.length < 2) {
13
- throw new Error('Gradient requires at least 2 color stops.');
14
- }
15
- this._stops = [...stops].map(stop => ({ offset: clamp(stop.offset, 0, 1), color: stop.color.clone() })).sort(sortedStopOffset);
19
+ this._stops = Gradient._normalizeStops(stops);
16
20
  }
17
21
  get stops() {
18
22
  return this._stops;
19
23
  }
24
+ /**
25
+ * Copy every value (stops and geometry) from a same-type `source` into this
26
+ * instance, replacing its current state. Returns `this` for chaining.
27
+ */
28
+ copy(source) {
29
+ this._stops = source._stops.map(stop => ({ offset: stop.offset, color: stop.color.clone() }));
30
+ this._copyGeometry(source);
31
+ return this;
32
+ }
33
+ /**
34
+ * Structural value equality: same {@link GradientType}, same ordered stops
35
+ * (offset and {@link Color}), and same subclass geometry.
36
+ */
37
+ equals(other) {
38
+ if (this === other) {
39
+ return true;
40
+ }
41
+ if (this.type !== other.type || this._stops.length !== other._stops.length) {
42
+ return false;
43
+ }
44
+ for (let i = 0; i < this._stops.length; i++) {
45
+ const own = this._stops[i];
46
+ const their = other._stops[i];
47
+ if (own.offset !== their.offset || !own.color.equals(their.color)) {
48
+ return false;
49
+ }
50
+ }
51
+ return this._geometryEquals(other);
52
+ }
20
53
  toTexture(width, height, options = {}) {
21
54
  if (!Number.isInteger(width) || !Number.isInteger(height) || width <= 0 || height <= 0) {
22
55
  throw new Error('Gradient.toTexture() width/height must be positive integers.');
@@ -59,6 +92,19 @@ class Gradient {
59
92
  out[2] = previousColor.b / 255;
60
93
  out[3] = previousColor.a;
61
94
  }
95
+ static _normalizeStops(stops) {
96
+ if (stops.length < 2) {
97
+ throw new Error('Gradient requires at least 2 color stops.');
98
+ }
99
+ return stops
100
+ .map(stop => {
101
+ if (!Number.isFinite(stop.offset)) {
102
+ throw new Error('Gradient stop offset must be a finite number.');
103
+ }
104
+ return { offset: clamp(stop.offset, 0, 1), color: stop.color.clone() };
105
+ })
106
+ .sort(sortedStopOffset);
107
+ }
62
108
  _toRgba8Texture(width, height, options) {
63
109
  const texture = new DataTexture({
64
110
  width,
@@ -1 +1 @@
1
- {"version":3,"file":"Gradient.js","sources":["../../../../../src/rendering/gradient/Gradient.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Gradient.js","sources":["../../../../../src/rendering/gradient/Gradient.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
@@ -1,10 +1,18 @@
1
- import { Gradient, type GradientStop } from './Gradient';
1
+ import { Gradient, type GradientStop, type GradientType } from './Gradient';
2
2
  /**
3
3
  * Linear gradient in UV space projected from `start` to `end`.
4
4
  */
5
5
  export declare class LinearGradient extends Gradient {
6
- private readonly _start;
7
- private readonly _end;
6
+ readonly type: GradientType;
7
+ private _start;
8
+ private _end;
8
9
  constructor(stops: readonly GradientStop[], start?: readonly [number, number], end?: readonly [number, number]);
10
+ /** Projection axis start point in UV space. */
11
+ get start(): readonly [number, number];
12
+ /** Projection axis end point in UV space. */
13
+ get end(): readonly [number, number];
14
+ clone(): this;
9
15
  protected resolveT(u: number, v: number): number;
16
+ protected _copyGeometry(source: LinearGradient): void;
17
+ protected _geometryEquals(other: Gradient): boolean;
10
18
  }
@@ -4,6 +4,7 @@ import { Gradient } from './Gradient.js';
4
4
  * Linear gradient in UV space projected from `start` to `end`.
5
5
  */
6
6
  class LinearGradient extends Gradient {
7
+ type = 'linear';
7
8
  _start;
8
9
  _end;
9
10
  constructor(stops, start = [0, 0], end = [1, 0]) {
@@ -11,6 +12,17 @@ class LinearGradient extends Gradient {
11
12
  this._start = [start[0], start[1]];
12
13
  this._end = [end[0], end[1]];
13
14
  }
15
+ /** Projection axis start point in UV space. */
16
+ get start() {
17
+ return [this._start[0], this._start[1]];
18
+ }
19
+ /** Projection axis end point in UV space. */
20
+ get end() {
21
+ return [this._end[0], this._end[1]];
22
+ }
23
+ clone() {
24
+ return new LinearGradient(this.stops, this._start, this._end);
25
+ }
14
26
  resolveT(u, v) {
15
27
  const axisX = this._end[0] - this._start[0];
16
28
  const axisY = this._end[1] - this._start[1];
@@ -20,6 +32,17 @@ class LinearGradient extends Gradient {
20
32
  }
21
33
  return ((u - this._start[0]) * axisX + (v - this._start[1]) * axisY) / lengthSquared;
22
34
  }
35
+ _copyGeometry(source) {
36
+ this._start = [source._start[0], source._start[1]];
37
+ this._end = [source._end[0], source._end[1]];
38
+ }
39
+ _geometryEquals(other) {
40
+ return (other instanceof LinearGradient &&
41
+ this._start[0] === other._start[0] &&
42
+ this._start[1] === other._start[1] &&
43
+ this._end[0] === other._end[0] &&
44
+ this._end[1] === other._end[1]);
45
+ }
23
46
  }
24
47
 
25
48
  export { LinearGradient };
@@ -1 +1 @@
1
- {"version":3,"file":"LinearGradient.js","sources":["../../../../../src/rendering/gradient/LinearGradient.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;AAEG;AACG,MAAO,cAAe,SAAQ,QAAQ,CAAA;AACzB,IAAA,MAAM;AACN,IAAA,IAAI;AAErB,IAAA,WAAA,CAAmB,KAA8B,EAAE,KAAA,GAAmC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAA,GAAiC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAA;QACnI,KAAK,CAAC,KAAK,CAAC;AAEZ,QAAA,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAClC,QAAA,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9B;IAEmB,QAAQ,CAAC,CAAS,EAAE,CAAS,EAAA;AAC9C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3C,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK;AAEnD,QAAA,IAAI,aAAa,IAAI,QAAQ,EAAE;AAC7B,YAAA,OAAO,CAAC;QACV;AAEA,QAAA,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,aAAa;IACtF;AACD;;;;"}
1
+ {"version":3,"file":"LinearGradient.js","sources":["../../../../../src/rendering/gradient/LinearGradient.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAEA;;AAEG;AACG,MAAO,cAAe,SAAQ,QAAQ,CAAA;IAC1B,IAAI,GAAiB,QAAQ;AAErC,IAAA,MAAM;AACN,IAAA,IAAI;AAEZ,IAAA,WAAA,CAAmB,KAA8B,EAAE,KAAA,GAAmC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,GAAA,GAAiC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAA;QACnI,KAAK,CAAC,KAAK,CAAC;AAEZ,QAAA,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AAClC,QAAA,IAAI,CAAC,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9B;;AAGA,IAAA,IAAW,KAAK,GAAA;AACd,QAAA,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACzC;;AAGA,IAAA,IAAW,GAAG,GAAA;AACZ,QAAA,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrC;IAEO,KAAK,GAAA;AACV,QAAA,OAAO,IAAI,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAS;IACvE;IAEmB,QAAQ,CAAC,CAAS,EAAE,CAAS,EAAA;AAC9C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC3C,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC3C,MAAM,aAAa,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK;AAEnD,QAAA,IAAI,aAAa,IAAI,QAAQ,EAAE;AAC7B,YAAA,OAAO,CAAC;QACV;AAEA,QAAA,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,aAAa;IACtF;AAEmB,IAAA,aAAa,CAAC,MAAsB,EAAA;AACrD,QAAA,IAAI,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAClD,QAAA,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9C;AAEmB,IAAA,eAAe,CAAC,KAAe,EAAA;QAChD,QACE,KAAK,YAAY,cAAc;YAC/B,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAClC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;AAC9B,YAAA,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IAElC;AACD;;;;"}
@@ -1,10 +1,18 @@
1
- import { Gradient, type GradientStop } from './Gradient';
1
+ import { Gradient, type GradientStop, type GradientType } from './Gradient';
2
2
  /**
3
3
  * Radial gradient in UV space around `center` with normalized radius.
4
4
  */
5
5
  export declare class RadialGradient extends Gradient {
6
- private readonly _center;
7
- private readonly _radius;
6
+ readonly type: GradientType;
7
+ private _center;
8
+ private _radius;
8
9
  constructor(stops: readonly GradientStop[], center?: readonly [number, number], radius?: number);
10
+ /** Gradient center in UV space. */
11
+ get center(): readonly [number, number];
12
+ /** Normalized radius (UV units, clamped to be non-negative). */
13
+ get radius(): number;
14
+ clone(): this;
9
15
  protected resolveT(u: number, v: number): number;
16
+ protected _copyGeometry(source: RadialGradient): void;
17
+ protected _geometryEquals(other: Gradient): boolean;
10
18
  }