@lightningjs/renderer 3.0.0-beta22 → 3.0.0-beta23

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 (166) hide show
  1. package/README.md +93 -0
  2. package/dist/exports/platform.d.ts +7 -0
  3. package/dist/exports/platform.js +27 -0
  4. package/dist/exports/platform.js.map +1 -0
  5. package/dist/src/core/AutosizeManager.d.ts +29 -0
  6. package/dist/src/core/AutosizeManager.js +169 -0
  7. package/dist/src/core/AutosizeManager.js.map +1 -0
  8. package/dist/src/core/CoreNode.js +10 -14
  9. package/dist/src/core/CoreNode.js.map +1 -1
  10. package/dist/src/core/CoreTextureManager.d.ts +0 -13
  11. package/dist/src/core/CoreTextureManager.js +4 -78
  12. package/dist/src/core/CoreTextureManager.js.map +1 -1
  13. package/dist/src/core/Stage.js +2 -12
  14. package/dist/src/core/Stage.js.map +1 -1
  15. package/dist/src/core/animations/Animation.d.ts +21 -0
  16. package/dist/src/core/animations/Animation.js +194 -0
  17. package/dist/src/core/animations/Animation.js.map +1 -0
  18. package/dist/src/core/animations/CoreAnimationController.d.ts +1 -1
  19. package/dist/src/core/animations/CoreAnimationController.js +4 -2
  20. package/dist/src/core/animations/CoreAnimationController.js.map +1 -1
  21. package/dist/src/core/animations/Playback.d.ts +64 -0
  22. package/dist/src/core/animations/Playback.js +169 -0
  23. package/dist/src/core/animations/Playback.js.map +1 -0
  24. package/dist/src/core/animations/Transition.d.ts +27 -0
  25. package/dist/src/core/animations/Transition.js +52 -0
  26. package/dist/src/core/animations/Transition.js.map +1 -0
  27. package/dist/src/core/animations/utils.d.ts +2 -0
  28. package/dist/src/core/animations/utils.js +136 -0
  29. package/dist/src/core/animations/utils.js.map +1 -0
  30. package/dist/src/core/lib/collectionUtils.js +3 -2
  31. package/dist/src/core/lib/collectionUtils.js.map +1 -1
  32. package/dist/src/core/lib/utils.d.ts +0 -5
  33. package/dist/src/core/lib/utils.js +0 -63
  34. package/dist/src/core/lib/utils.js.map +1 -1
  35. package/dist/src/core/platforms/GlContextWrapper.d.ts +136 -0
  36. package/dist/src/core/platforms/GlContextWrapper.js +32 -0
  37. package/dist/src/core/platforms/GlContextWrapper.js.map +1 -0
  38. package/dist/src/core/platforms/Platform.d.ts +74 -13
  39. package/dist/src/core/platforms/Platform.js +18 -0
  40. package/dist/src/core/platforms/Platform.js.map +1 -1
  41. package/dist/src/core/platforms/web/WebGlContextWrapper.d.ts +776 -0
  42. package/dist/src/core/platforms/web/WebGlContextWrapper.js +1208 -0
  43. package/dist/src/core/platforms/web/WebGlContextWrapper.js.map +1 -0
  44. package/dist/src/core/platforms/web/WebPlatform.d.ts +13 -2
  45. package/dist/src/core/platforms/web/WebPlatform.js +109 -8
  46. package/dist/src/core/platforms/web/WebPlatform.js.map +1 -1
  47. package/dist/src/core/platforms/web/WebPlatformChrome50.d.ts +17 -0
  48. package/dist/src/core/platforms/web/WebPlatformChrome50.js +50 -0
  49. package/dist/src/core/platforms/web/WebPlatformChrome50.js.map +1 -0
  50. package/dist/src/core/platforms/web/WebPlatformLegacy.d.ts +18 -0
  51. package/dist/src/core/platforms/web/WebPlatformLegacy.js +99 -0
  52. package/dist/src/core/platforms/web/WebPlatformLegacy.js.map +1 -0
  53. package/dist/src/core/platforms/web/WebPlatformNext.d.ts +21 -0
  54. package/dist/src/core/platforms/web/WebPlatformNext.js +52 -0
  55. package/dist/src/core/platforms/web/WebPlatformNext.js.map +1 -0
  56. package/dist/src/core/platforms/web/lib/ImageWorker.d.ts +15 -0
  57. package/dist/src/core/platforms/web/lib/ImageWorker.js +189 -0
  58. package/dist/src/core/platforms/web/lib/ImageWorker.js.map +1 -0
  59. package/dist/src/core/platforms/web/lib/createImageBitmap.d.ts +1 -0
  60. package/dist/src/core/platforms/web/lib/createImageBitmap.js +27 -0
  61. package/dist/src/core/platforms/web/lib/createImageBitmap.js.map +1 -0
  62. package/dist/src/core/platforms/web/lib/textureCompression.d.ts +26 -0
  63. package/dist/src/core/platforms/web/lib/textureCompression.js +301 -0
  64. package/dist/src/core/platforms/web/lib/textureCompression.js.map +1 -0
  65. package/dist/src/core/platforms/web/lib/textureSvg.d.ts +7 -0
  66. package/dist/src/core/platforms/web/lib/textureSvg.js +51 -0
  67. package/dist/src/core/platforms/web/lib/textureSvg.js.map +1 -0
  68. package/dist/src/core/platforms/web/lib/utils.d.ts +5 -0
  69. package/dist/src/core/platforms/web/lib/utils.js +86 -0
  70. package/dist/src/core/platforms/web/lib/utils.js.map +1 -0
  71. package/dist/src/core/renderers/CoreRenderer.d.ts +1 -9
  72. package/dist/src/core/renderers/CoreRenderer.js +2 -4
  73. package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
  74. package/dist/src/core/renderers/canvas/CanvasRenderer.d.ts +3 -2
  75. package/dist/src/core/renderers/canvas/CanvasRenderer.js +4 -3
  76. package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -1
  77. package/dist/src/core/renderers/webgl/SdfRenderOp.js +3 -2
  78. package/dist/src/core/renderers/webgl/SdfRenderOp.js.map +1 -1
  79. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.d.ts +2 -2
  80. package/dist/src/core/renderers/webgl/WebGlCtxRenderTexture.js.map +1 -1
  81. package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.d.ts +2 -2
  82. package/dist/src/core/renderers/webgl/WebGlCtxSubTexture.js.map +1 -1
  83. package/dist/src/core/renderers/webgl/WebGlCtxTexture.d.ts +3 -3
  84. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js +1 -2
  85. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js.map +1 -1
  86. package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +5 -5
  87. package/dist/src/core/renderers/webgl/WebGlRenderer.js +7 -8
  88. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
  89. package/dist/src/core/renderers/webgl/WebGlShaderNode.d.ts +2 -2
  90. package/dist/src/core/renderers/webgl/WebGlShaderProgram.d.ts +2 -2
  91. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -1
  92. package/dist/src/core/renderers/webgl/internal/RendererUtils.d.ts +4 -4
  93. package/dist/src/core/renderers/webgl/internal/RendererUtils.js.map +1 -1
  94. package/dist/src/core/renderers/webgl/internal/ShaderUtils.d.ts +3 -3
  95. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -1
  96. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js +24 -8
  97. package/dist/src/core/renderers/webgl/shaders/effects/LinearGradientEffect.js.map +1 -1
  98. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js +25 -8
  99. package/dist/src/core/renderers/webgl/shaders/effects/RadialGradientEffect.js.map +1 -1
  100. package/dist/src/core/shaders/webgl/Border.js +6 -4
  101. package/dist/src/core/shaders/webgl/Border.js.map +1 -1
  102. package/dist/src/core/shaders/webgl/RoundedWithBorder.js +6 -4
  103. package/dist/src/core/shaders/webgl/RoundedWithBorder.js.map +1 -1
  104. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js +6 -4
  105. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js.map +1 -1
  106. package/dist/src/core/shaders/webgl/SdfShadowShader.d.ts +9 -0
  107. package/dist/src/core/shaders/webgl/SdfShadowShader.js +100 -0
  108. package/dist/src/core/shaders/webgl/SdfShadowShader.js.map +1 -0
  109. package/dist/src/core/text-rendering/CanvasFont.d.ts +1 -1
  110. package/dist/src/core/text-rendering/CanvasFont.js +2 -6
  111. package/dist/src/core/text-rendering/CanvasFont.js.map +1 -1
  112. package/dist/src/core/text-rendering/CoreFont.d.ts +1 -1
  113. package/dist/src/core/text-rendering/CoreFont.js +1 -1
  114. package/dist/src/core/text-rendering/CoreFont.js.map +1 -1
  115. package/dist/src/core/text-rendering/FontManager.js +2 -1
  116. package/dist/src/core/text-rendering/FontManager.js.map +1 -1
  117. package/dist/src/core/textures/ImageTexture.d.ts +24 -11
  118. package/dist/src/core/textures/ImageTexture.js +32 -95
  119. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  120. package/dist/src/core/textures/Texture.d.ts +1 -1
  121. package/dist/src/main-api/Renderer.js +18 -21
  122. package/dist/src/main-api/Renderer.js.map +1 -1
  123. package/dist/src/utils.d.ts +0 -2
  124. package/dist/src/utils.js +0 -36
  125. package/dist/src/utils.js.map +1 -1
  126. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  127. package/dist/tsconfig.tsbuildinfo +1 -0
  128. package/exports/platform.ts +31 -0
  129. package/package.json +3 -2
  130. package/src/core/CoreNode.ts +11 -15
  131. package/src/core/CoreTextureManager.ts +10 -103
  132. package/src/core/Stage.ts +1 -14
  133. package/src/core/animations/CoreAnimationController.ts +5 -2
  134. package/src/core/lib/collectionUtils.ts +3 -2
  135. package/src/core/lib/utils.ts +0 -78
  136. package/src/core/platforms/GlContextWrapper.ts +291 -0
  137. package/src/core/platforms/Platform.ts +121 -28
  138. package/src/core/{lib → platforms/web}/WebGlContextWrapper.ts +129 -4
  139. package/src/core/platforms/web/WebPlatform.ts +171 -22
  140. package/src/core/platforms/web/WebPlatformChrome50.ts +57 -0
  141. package/src/core/platforms/web/WebPlatformLegacy.ts +140 -0
  142. package/src/core/platforms/web/WebPlatformNext.ts +57 -0
  143. package/src/core/{lib → platforms/web/lib}/ImageWorker.ts +10 -74
  144. package/src/core/platforms/web/lib/createImageBitmap.ts +40 -0
  145. package/src/core/{lib → platforms/web/lib}/textureCompression.ts +19 -138
  146. package/src/core/{lib → platforms/web/lib}/textureSvg.ts +3 -15
  147. package/src/core/platforms/web/lib/utils.ts +105 -0
  148. package/src/core/renderers/CoreRenderer.ts +2 -11
  149. package/src/core/renderers/canvas/CanvasRenderer.ts +6 -4
  150. package/src/core/renderers/webgl/SdfRenderOp.ts +3 -2
  151. package/src/core/renderers/webgl/WebGlCtxRenderTexture.ts +2 -2
  152. package/src/core/renderers/webgl/WebGlCtxSubTexture.ts +2 -2
  153. package/src/core/renderers/webgl/WebGlCtxTexture.ts +3 -4
  154. package/src/core/renderers/webgl/WebGlRenderer.ts +12 -19
  155. package/src/core/renderers/webgl/WebGlShaderNode.ts +2 -2
  156. package/src/core/renderers/webgl/WebGlShaderProgram.ts +2 -2
  157. package/src/core/renderers/webgl/internal/RendererUtils.ts +4 -8
  158. package/src/core/renderers/webgl/internal/ShaderUtils.ts +3 -3
  159. package/src/core/shaders/webgl/Border.ts +6 -4
  160. package/src/core/shaders/webgl/RoundedWithBorder.ts +6 -4
  161. package/src/core/shaders/webgl/RoundedWithBorderAndShadow.ts +6 -4
  162. package/src/core/textures/ImageTexture.ts +42 -161
  163. package/src/core/textures/Texture.ts +1 -1
  164. package/src/main-api/Renderer.ts +24 -22
  165. package/src/utils.ts +0 -47
  166. package/src/core/lib/validateImageBitmap.ts +0 -87
@@ -19,9 +19,8 @@
19
19
 
20
20
  import type { Dimensions } from '../../../common/CommonTypes.js';
21
21
  import type { TextureMemoryManager } from '../../TextureMemoryManager.js';
22
- import type { WebGlContextWrapper } from '../../lib/WebGlContextWrapper.js';
22
+ import type { GlContextWrapper } from '../../platforms/GlContextWrapper.js';
23
23
  import type { Texture } from '../../textures/Texture.js';
24
- import { uploadCompressedTexture } from '../../lib/textureCompression.js';
25
24
  import { CoreContextTexture } from '../CoreContextTexture.js';
26
25
  import { isHTMLImageElement } from './internal/RendererUtils.js';
27
26
  import type { Bound } from '../../lib/utils.js';
@@ -53,7 +52,7 @@ export class WebGlCtxTexture extends CoreContextTexture {
53
52
  };
54
53
 
55
54
  constructor(
56
- protected glw: WebGlContextWrapper,
55
+ protected glw: GlContextWrapper,
57
56
  memManager: TextureMemoryManager,
58
57
  textureSource: Texture,
59
58
  ) {
@@ -239,7 +238,7 @@ export class WebGlCtxTexture extends CoreContextTexture {
239
238
  this.setTextureMemUse(TRANSPARENT_TEXTURE_DATA.byteLength);
240
239
  } else if ('mipmaps' in tdata && tdata.mipmaps) {
241
240
  const { mipmaps, type, blockInfo } = tdata;
242
- uploadCompressedTexture[type]!(glw, this._nativeCtxTexture, tdata);
241
+ glw['upload' + type]!(this._nativeCtxTexture, tdata);
243
242
 
244
243
  // Check for errors after compressed texture operations
245
244
  if (this.checkGLError() === true) {
@@ -17,12 +17,7 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
- import { createWebGLContext } from '../../../utils.js';
21
- import {
22
- CoreRenderer,
23
- type BufferInfo,
24
- type CoreRendererOptions,
25
- } from '../CoreRenderer.js';
20
+ import { CoreRenderer, type BufferInfo } from '../CoreRenderer.js';
26
21
  import type { SdfRenderOp } from './SdfRenderOp.js';
27
22
  import type { CoreContextTexture } from '../CoreContextTexture.js';
28
23
  import {
@@ -44,7 +39,6 @@ import { WebGlCtxSubTexture } from './WebGlCtxSubTexture.js';
44
39
  import { BufferCollection } from './internal/BufferCollection.js';
45
40
  import { compareRect, getNormalizedRgbaComponents } from '../../lib/utils.js';
46
41
  import { WebGlShaderProgram } from './WebGlShaderProgram.js';
47
- import { WebGlContextWrapper } from '../../lib/WebGlContextWrapper.js';
48
42
  import { RenderTexture } from '../../textures/RenderTexture.js';
49
43
  import { CoreNodeRenderState, CoreNode } from '../../CoreNode.js';
50
44
  import { WebGlCtxRenderTexture } from './WebGlCtxRenderTexture.js';
@@ -52,8 +46,9 @@ import { Default } from '../../shaders/webgl/Default.js';
52
46
  import type { WebGlShaderType } from './WebGlShaderNode.js';
53
47
  import { WebGlShaderNode } from './WebGlShaderNode.js';
54
48
  import type { Dimensions } from '../../../common/CommonTypes.js';
55
-
56
- export type WebGlRendererOptions = CoreRendererOptions;
49
+ import type { GlContextWrapper } from '../../platforms/GlContextWrapper.js';
50
+ import type { Platform } from '../../platforms/Platform.js';
51
+ import type { Stage } from '../../Stage.js';
57
52
 
58
53
  interface CoreWebGlSystem {
59
54
  parameters: CoreWebGlParameters;
@@ -64,7 +59,7 @@ export type WebGlRenderOp = CoreNode | SdfRenderOp;
64
59
 
65
60
  export class WebGlRenderer extends CoreRenderer {
66
61
  //// WebGL Native Context and Data
67
- glw: WebGlContextWrapper;
62
+ glw: GlContextWrapper;
68
63
  system: CoreWebGlSystem;
69
64
 
70
65
  //// Persistent data
@@ -106,8 +101,8 @@ export class WebGlRenderer extends CoreRenderer {
106
101
  */
107
102
  public renderToTextureActive = false;
108
103
 
109
- constructor(options: WebGlRendererOptions) {
110
- super(options);
104
+ constructor(stage: Stage) {
105
+ super(stage);
111
106
 
112
107
  this.quadBuffer = new ArrayBuffer(this.stage.options.quadBufferSize);
113
108
  this.fQuadBuffer = new Float32Array(this.quadBuffer);
@@ -115,13 +110,11 @@ export class WebGlRenderer extends CoreRenderer {
115
110
 
116
111
  this.mode = 'webgl';
117
112
 
118
- const gl = createWebGLContext(
119
- options.canvas,
120
- options.forceWebGL2,
121
- options.contextSpy,
122
- );
123
- const glw = (this.glw = new WebGlContextWrapper(gl));
124
- glw.viewport(0, 0, options.canvas.width, options.canvas.height);
113
+ const platform = this.stage.platform;
114
+ const canvas = platform.canvas!;
115
+
116
+ const glw = (this.glw = platform.createContext() as GlContextWrapper);
117
+ glw.viewport(0, 0, canvas.width, canvas.height);
125
118
 
126
119
  this.updateClearColor(this.stage.clearColor);
127
120
 
@@ -1,6 +1,6 @@
1
1
  import type { CoreNode } from '../../CoreNode.js';
2
2
  import { getNormalizedRgbaComponents } from '../../lib/utils.js';
3
- import type { WebGlContextWrapper } from '../../lib/WebGlContextWrapper.js';
3
+ import type { GlContextWrapper } from '../../platforms/GlContextWrapper.js';
4
4
  import type { Stage } from '../../Stage.js';
5
5
  import { CoreShaderNode, type CoreShaderType } from '../CoreShaderNode.js';
6
6
  import type {
@@ -40,7 +40,7 @@ export type WebGlShaderType<T extends object = Record<string, unknown>> =
40
40
  *
41
41
  * @warning don't use this in your shader type
42
42
  */
43
- onSdfBind?: (this: WebGlContextWrapper, props: T) => void;
43
+ onSdfBind?: (this: GlContextWrapper, props: T) => void;
44
44
  /**
45
45
  * This function is used to check if the shader can be reused based on quad info
46
46
  * @param props
@@ -16,7 +16,7 @@
16
16
  * See the License for the specific language governing permissions and
17
17
  * limitations under the License.
18
18
  */
19
- import type { WebGlContextWrapper } from '../../lib/WebGlContextWrapper.js';
19
+ import type { GlContextWrapper } from '../../platforms/GlContextWrapper.js';
20
20
  import { Default } from '../../shaders/webgl/Default.js';
21
21
  import type { CoreShaderProgram } from '../CoreShaderProgram.js';
22
22
  import type { WebGlCtxTexture } from './WebGlCtxTexture.js';
@@ -44,7 +44,7 @@ export class WebGlShaderProgram implements CoreShaderProgram {
44
44
  */
45
45
  protected vao: WebGLVertexArrayObject | undefined;
46
46
  protected renderer: WebGlRenderer;
47
- protected glw: WebGlContextWrapper;
47
+ protected glw: GlContextWrapper;
48
48
  protected attributeLocations: string[];
49
49
  protected uniformLocations: Record<string, WebGLUniformLocation> | null;
50
50
  protected lifecycle: Pick<WebGlShaderType, 'update' | 'canBatch'>;
@@ -17,7 +17,7 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
- import type { WebGlContextWrapper } from '../../../lib/WebGlContextWrapper.js';
20
+ import type { GlContextWrapper } from '../../../platforms/GlContextWrapper.js';
21
21
 
22
22
  export interface CoreWebGlParameters {
23
23
  MAX_RENDERBUFFER_SIZE: number;
@@ -36,9 +36,7 @@ export interface CoreWebGlParameters {
36
36
  * Get device specific webgl parameters
37
37
  * @param glw
38
38
  */
39
- export function getWebGlParameters(
40
- glw: WebGlContextWrapper,
41
- ): CoreWebGlParameters {
39
+ export function getWebGlParameters(glw: GlContextWrapper): CoreWebGlParameters {
42
40
  const params: CoreWebGlParameters = {
43
41
  MAX_RENDERBUFFER_SIZE: 0,
44
42
  MAX_TEXTURE_SIZE: 0,
@@ -81,9 +79,7 @@ export interface CoreWebGlExtensions {
81
79
  * Get device webgl extensions
82
80
  * @param glw
83
81
  */
84
- export function getWebGlExtensions(
85
- glw: WebGlContextWrapper,
86
- ): CoreWebGlExtensions {
82
+ export function getWebGlExtensions(glw: GlContextWrapper): CoreWebGlExtensions {
87
83
  const extensions: CoreWebGlExtensions = {
88
84
  ANGLE_instanced_arrays: null,
89
85
  WEBGL_compressed_texture_s3tc: null,
@@ -113,7 +109,7 @@ export function getWebGlExtensions(
113
109
  * @param glw
114
110
  * @param size
115
111
  */
116
- export function createIndexBuffer(glw: WebGlContextWrapper, size: number) {
112
+ export function createIndexBuffer(glw: GlContextWrapper, size: number) {
117
113
  const maxQuads = ~~(size / 80);
118
114
  const indices = new Uint16Array(maxQuads * 6);
119
115
 
@@ -17,7 +17,7 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
- import type { WebGlContextWrapper } from '../../../lib/WebGlContextWrapper.js';
20
+ import type { GlContextWrapper } from '../../../platforms/GlContextWrapper.js';
21
21
 
22
22
  //#region Types
23
23
  export interface AttributeInfo {
@@ -178,7 +178,7 @@ export interface ShaderProgramSources {
178
178
  //#endregion Types
179
179
 
180
180
  export function createShader(
181
- glw: WebGlContextWrapper,
181
+ glw: GlContextWrapper,
182
182
  type: number,
183
183
  source: string,
184
184
  ) {
@@ -204,7 +204,7 @@ export function createShader(
204
204
  }
205
205
 
206
206
  export function createProgram(
207
- glw: WebGlContextWrapper,
207
+ glw: GlContextWrapper,
208
208
  vertexShader: WebGLShader,
209
209
  fragmentShader: WebGLShader,
210
210
  ) {
@@ -66,10 +66,12 @@ export const Border: WebGlShaderType<BorderProps> = {
66
66
  vec2 edge = clamp(a_nodeCoords * 2.0 - vec2(1.0), -1.0, 1.0);
67
67
  v_edgeWidth = 1.0 / u_pixelRatio;
68
68
 
69
- float borderTop = u_borderWidth.x;
70
- float borderRight = u_borderWidth.y;
71
- float borderBottom = u_borderWidth.z;
72
- float borderLeft = u_borderWidth.w;
69
+ vec4 adjustedBorderWidth = u_borderWidth - 1.0 + clamp(u_borderWidth, -1.0, 1.0);
70
+
71
+ float borderTop = adjustedBorderWidth.x;
72
+ float borderRight = adjustedBorderWidth.y;
73
+ float borderBottom = adjustedBorderWidth.z;
74
+ float borderLeft = adjustedBorderWidth.w;
73
75
 
74
76
  v_outerBorderUv = vec2(0.0);
75
77
  v_innerBorderUv = vec2(0.0);
@@ -83,10 +83,12 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
83
83
  v_outerSize = vec2(0.0);
84
84
 
85
85
  if(v_borderZero == 0.0) {
86
- float borderTop = u_borderWidth.x;
87
- float borderRight = u_borderWidth.y;
88
- float borderBottom = u_borderWidth.z;
89
- float borderLeft = u_borderWidth.w;
86
+ vec4 adjustedBorderWidth = u_borderWidth - 1.0 + clamp(u_borderWidth, -1.0, 1.0);
87
+
88
+ float borderTop = adjustedBorderWidth.x;
89
+ float borderRight = adjustedBorderWidth.y;
90
+ float borderBottom = adjustedBorderWidth.z;
91
+ float borderLeft = adjustedBorderWidth.w;
90
92
 
91
93
  v_outerBorderUv = vec2(0.0);
92
94
  v_innerBorderUv = vec2(0.0);
@@ -92,10 +92,12 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
92
92
  v_outerSize = vec2(0.0);
93
93
 
94
94
  if(v_borderZero == 0.0) {
95
- float borderTop = u_borderWidth.x;
96
- float borderRight = u_borderWidth.y;
97
- float borderBottom = u_borderWidth.z;
98
- float borderLeft = u_borderWidth.w;
95
+ vec4 adjustedBorderWidth = u_borderWidth - 1.0 + clamp(u_borderWidth, -1.0, 1.0);
96
+
97
+ float borderTop = adjustedBorderWidth.x;
98
+ float borderRight = adjustedBorderWidth.y;
99
+ float borderBottom = adjustedBorderWidth.z;
100
+ float borderLeft = adjustedBorderWidth.w;
99
101
 
100
102
  v_outerBorderUv = vec2(0.0);
101
103
  v_innerBorderUv = vec2(0.0);
@@ -19,19 +19,8 @@
19
19
 
20
20
  import type { CoreTextureManager } from '../CoreTextureManager.js';
21
21
  import { Texture, TextureType, type TextureData } from './Texture.js';
22
- import {
23
- isCompressedTextureContainer,
24
- loadCompressedTexture,
25
- } from '../lib/textureCompression.js';
26
- import {
27
- convertUrlToAbsolute,
28
- dataURIToBlob,
29
- isBase64Image,
30
- } from '../lib/utils.js';
31
- import { isSvgImage, loadSvg } from '../lib/textureSvg.js';
32
- import { fetchJson } from '../lib/utils.js';
33
22
  import type { Platform } from '../platforms/Platform.js';
34
- import { isProductionEnvironment } from '../../utils.js';
23
+ import type { CompressedImageData } from '../platforms/web/lib/textureCompression.js';
35
24
 
36
25
  /**
37
26
  * Properties of the {@link ImageTexture}
@@ -117,6 +106,11 @@ export interface ImageTextureProps {
117
106
  maxRetryCount?: number;
118
107
  }
119
108
 
109
+ export interface ImageResponse {
110
+ data: ImageBitmap | ImageData | CompressedImageData | HTMLImageElement | null;
111
+ premultiplyAlpha: boolean | null;
112
+ }
113
+
120
114
  /**
121
115
  * Texture consisting of an image loaded from a URL
122
116
  *
@@ -148,125 +142,6 @@ export class ImageTexture extends Texture {
148
142
  this.maxRetryCount = props.maxRetryCount as number;
149
143
  }
150
144
 
151
- hasAlphaChannel(mimeType: string) {
152
- return mimeType.indexOf('image/png') !== -1;
153
- }
154
-
155
- async loadImageFallback(src: string | Blob, hasAlpha: boolean) {
156
- const img = new Image();
157
-
158
- if (typeof src === 'string' && isBase64Image(src) === false) {
159
- img.crossOrigin = 'anonymous';
160
- }
161
-
162
- return new Promise<{
163
- data: HTMLImageElement | null;
164
- premultiplyAlpha: boolean;
165
- }>((resolve, reject) => {
166
- img.onload = () => {
167
- resolve({ data: img, premultiplyAlpha: hasAlpha });
168
- };
169
-
170
- img.onerror = (err) => {
171
- const errorMessage =
172
- err instanceof Error
173
- ? err.message
174
- : err instanceof Event
175
- ? `Image loading failed for ${img.src}`
176
- : 'Unknown image loading error';
177
- reject(new Error(`Image loading failed: ${errorMessage}`));
178
- };
179
-
180
- if (src instanceof Blob) {
181
- img.src = URL.createObjectURL(src);
182
- } else {
183
- img.src = src;
184
- }
185
- });
186
- }
187
-
188
- async createImageBitmap(
189
- blob: Blob,
190
- premultiplyAlpha: boolean | null,
191
- sx: number | null,
192
- sy: number | null,
193
- sw: number | null,
194
- sh: number | null,
195
- ): Promise<{
196
- data: ImageBitmap | HTMLImageElement;
197
- premultiplyAlpha: boolean;
198
- }> {
199
- const hasAlphaChannel = premultiplyAlpha ?? blob.type.includes('image/png');
200
- const imageBitmapSupported = this.txManager.imageBitmapSupported;
201
-
202
- if (imageBitmapSupported.full === true && sw !== null && sh !== null) {
203
- // createImageBitmap with crop
204
- const bitmap = await this.platform.createImageBitmap(
205
- blob,
206
- sx || 0,
207
- sy || 0,
208
- sw,
209
- sh,
210
- {
211
- premultiplyAlpha: hasAlphaChannel ? 'premultiply' : 'none',
212
- colorSpaceConversion: 'none',
213
- imageOrientation: 'none',
214
- },
215
- );
216
- return { data: bitmap, premultiplyAlpha: hasAlphaChannel };
217
- } else if (imageBitmapSupported.basic === true) {
218
- // basic createImageBitmap without options or crop
219
- // this is supported for Chrome v50 to v52/54 that doesn't support options
220
- return {
221
- data: await this.platform.createImageBitmap(blob),
222
- premultiplyAlpha: hasAlphaChannel,
223
- };
224
- }
225
-
226
- // default createImageBitmap without crop but with options
227
- const bitmap = await this.platform.createImageBitmap(blob, {
228
- premultiplyAlpha: hasAlphaChannel ? 'premultiply' : 'none',
229
- colorSpaceConversion: 'none',
230
- imageOrientation: 'none',
231
- });
232
- return { data: bitmap, premultiplyAlpha: hasAlphaChannel };
233
- }
234
-
235
- async loadImage(src: string) {
236
- const { premultiplyAlpha, sx, sy, sw, sh } = this.props;
237
-
238
- if (this.txManager.hasCreateImageBitmap === true) {
239
- if (
240
- isBase64Image(src) === false &&
241
- this.txManager.hasWorker === true &&
242
- this.txManager.imageWorkerManager !== null
243
- ) {
244
- return this.txManager.imageWorkerManager.getImage(
245
- src,
246
- premultiplyAlpha,
247
- sx,
248
- sy,
249
- sw,
250
- sh,
251
- );
252
- }
253
-
254
- let blob;
255
-
256
- if (isBase64Image(src) === true) {
257
- blob = dataURIToBlob(src);
258
- } else {
259
- blob = await fetchJson(src, 'blob').then(
260
- (response) => response as Blob,
261
- );
262
- }
263
-
264
- return this.createImageBitmap(blob, premultiplyAlpha, sx, sy, sw, sh);
265
- }
266
-
267
- return this.loadImageFallback(src, premultiplyAlpha ?? true);
268
- }
269
-
270
145
  override async getTextureSource(): Promise<TextureData> {
271
146
  let resp: TextureData;
272
147
  try {
@@ -293,7 +168,10 @@ export class ImageTexture extends Texture {
293
168
  }
294
169
 
295
170
  determineImageTypeAndLoadImage() {
296
- const { src, premultiplyAlpha, type } = this.props;
171
+ const { src, premultiplyAlpha, type, w, h, sx, sy, sw, sh } = this.props;
172
+ const platform = this.platform;
173
+ const premultiply = premultiplyAlpha ?? true;
174
+
297
175
  if (src === null) {
298
176
  return {
299
177
  data: null,
@@ -302,13 +180,9 @@ export class ImageTexture extends Texture {
302
180
 
303
181
  if (typeof src !== 'string') {
304
182
  if (src instanceof Blob) {
305
- if (this.txManager.hasCreateImageBitmap === true) {
306
- const { sx, sy, sw, sh } = this.props;
307
- return this.createImageBitmap(src, premultiplyAlpha, sx, sy, sw, sh);
308
- } else {
309
- return this.loadImageFallback(src, premultiplyAlpha ?? true);
310
- }
183
+ return platform.createImage(src, premultiply, sx, sy, sw, sh);
311
184
  }
185
+
312
186
  if (src instanceof ImageData) {
313
187
  return {
314
188
  data: src,
@@ -321,45 +195,28 @@ export class ImageTexture extends Texture {
321
195
  };
322
196
  }
323
197
 
324
- const absoluteSrc = convertUrlToAbsolute(src);
325
198
  if (type === 'regular') {
326
- return this.loadImage(absoluteSrc);
199
+ return platform.loadImage(src, premultiply, sx, sy, sw, sh);
327
200
  }
328
201
 
329
202
  if (type === 'svg') {
330
- return loadSvg(
331
- absoluteSrc,
332
- this.props.w,
333
- this.props.h,
334
- this.props.sx,
335
- this.props.sy,
336
- this.props.sw,
337
- this.props.sh,
338
- );
203
+ return platform.loadSvg(src, w, h, sx, sy, sw, sh);
339
204
  }
340
205
 
341
206
  if (isSvgImage(src) === true) {
342
- return loadSvg(
343
- absoluteSrc,
344
- this.props.w,
345
- this.props.h,
346
- this.props.sx,
347
- this.props.sy,
348
- this.props.sw,
349
- this.props.sh,
350
- );
207
+ return platform.loadSvg(src, w, h, sx, sy, sw, sh);
351
208
  }
352
209
 
353
210
  if (type === 'compressed') {
354
- return loadCompressedTexture(absoluteSrc);
211
+ return platform.loadCompressedTexture(src);
355
212
  }
356
213
 
357
214
  if (isCompressedTextureContainer(src) === true) {
358
- return loadCompressedTexture(absoluteSrc);
215
+ return platform.loadCompressedTexture(src);
359
216
  }
360
217
 
361
218
  // default
362
- return this.loadImage(absoluteSrc);
219
+ return platform.loadImage(src, premultiply, sx, sy, sw, sh);
363
220
  }
364
221
 
365
222
  /**
@@ -409,3 +266,27 @@ export class ImageTexture extends Texture {
409
266
 
410
267
  static z$__type__Props: ImageTextureProps;
411
268
  }
269
+
270
+ /**
271
+ * Tests if the given location is a SVG
272
+ * @param url
273
+ * @remarks
274
+ * This function is used to determine if the given image url is a SVG
275
+ * image
276
+ * @returns
277
+ */
278
+ export function isSvgImage(url: string): boolean {
279
+ return /\.(svg)(\?.*)?$/.test(url);
280
+ }
281
+
282
+ /**
283
+ * Tests if the given location is a compressed texture container
284
+ * @param url
285
+ * @remarks
286
+ * This function is used to determine if the given image url is a compressed
287
+ * and only supports the following extensions: .ktx and .pvr
288
+ * @returns
289
+ */
290
+ export function isCompressedTextureContainer(src: string): boolean {
291
+ return /\.(ktx|pvr)$/.test(src);
292
+ }
@@ -60,7 +60,7 @@ export interface CompressedData {
60
60
  /**
61
61
  * Supported container types ('pvr' or 'ktx').
62
62
  */
63
- type: 'pvr' | 'ktx' | 'astc';
63
+ type: 'PVR' | 'KTX' | 'ASTC';
64
64
 
65
65
  /**
66
66
  * The width of the compressed texture in pixels. Defaults to 0.
@@ -19,7 +19,7 @@
19
19
 
20
20
  import type { ExtractProps, TextureMap } from '../core/CoreTextureManager.js';
21
21
  import { EventEmitter } from '../common/EventEmitter.js';
22
- import { isProductionEnvironment } from '../utils.js';
22
+ import { assertTruthy, isProductionEnvironment } from '../utils.js';
23
23
  import { Stage, type StageOptions } from '../core/Stage.js';
24
24
  import { CoreNode, type CoreNodeProps } from '../core/CoreNode.js';
25
25
  import { type CoreTextNodeProps } from '../core/CoreTextNode.js';
@@ -550,7 +550,7 @@ export class RendererMain extends EventEmitter {
550
550
  textureProcessingTimeLimit: settings.textureProcessingTimeLimit || 42,
551
551
  canvas: settings.canvas,
552
552
  createImageBitmapSupport: settings.createImageBitmapSupport || 'full',
553
- platform: settings.platform || null,
553
+ platform: settings.platform || WebPlatform,
554
554
  maxRetryCount: settings.maxRetryCount ?? 5,
555
555
  };
556
556
 
@@ -562,29 +562,28 @@ export class RendererMain extends EventEmitter {
562
562
  inspector,
563
563
  } = settings as RendererMainSettings;
564
564
 
565
- let platform;
566
- if (
567
- settings.platform !== undefined &&
568
- settings.platform !== null &&
569
- settings.platform.prototype instanceof Platform === true
570
- ) {
571
- // @ts-ignore - if Platform is a valid class, it will be used
572
- platform = new settings.platform();
573
- } else {
574
- platform = new WebPlatform();
575
- }
565
+ assertTruthy(
566
+ settings.platform,
567
+ 'A platform implementation must be provided in settings.platform',
568
+ );
576
569
 
577
- const canvas = settings.canvas || platform.createCanvas();
570
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
571
+ const platform = new (settings.platform as any)({
572
+ numImageWorkers: settings.numImageWorkers,
573
+ forceWebGL2: settings.forceWebGL2,
574
+ canvas: settings.canvas,
575
+ });
578
576
 
579
577
  const deviceLogicalWidth = appWidth * deviceLogicalPixelRatio;
580
578
  const deviceLogicalHeight = appHeight * deviceLogicalPixelRatio;
581
579
 
582
- this.canvas = canvas;
583
- canvas.width = deviceLogicalWidth * devicePhysicalPixelRatio;
584
- canvas.height = deviceLogicalHeight * devicePhysicalPixelRatio;
580
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unsafe-member-access
581
+ this.canvas = platform.canvas! as HTMLCanvasElement;
582
+ this.canvas.width = deviceLogicalWidth * devicePhysicalPixelRatio;
583
+ this.canvas.height = deviceLogicalHeight * devicePhysicalPixelRatio;
585
584
 
586
- canvas.style.width = `${deviceLogicalWidth}px`;
587
- canvas.style.height = `${deviceLogicalHeight}px`;
585
+ this.canvas.style.width = `${deviceLogicalWidth}px`;
586
+ this.canvas.style.height = `${deviceLogicalHeight}px`;
588
587
 
589
588
  // Initialize the stage
590
589
  this.stage = new Stage({
@@ -629,8 +628,8 @@ export class RendererMain extends EventEmitter {
629
628
  throw new Error('Could not find target element');
630
629
  }
631
630
 
632
- targetEl.appendChild(canvas);
633
- } else if (settings.canvas !== canvas) {
631
+ targetEl.appendChild(this.canvas);
632
+ } else if (settings.canvas !== this.canvas) {
634
633
  throw new Error(
635
634
  'New canvas element could not be appended to undefined target',
636
635
  );
@@ -638,7 +637,10 @@ export class RendererMain extends EventEmitter {
638
637
 
639
638
  // Initialize inspector (if enabled)
640
639
  if (inspector && isProductionEnvironment === false) {
641
- this.inspector = new inspector(canvas, settings as RendererMainSettings);
640
+ this.inspector = new inspector(
641
+ this.canvas,
642
+ settings as RendererMainSettings,
643
+ );
642
644
  }
643
645
  }
644
646
 
package/src/utils.ts CHANGED
@@ -17,53 +17,6 @@
17
17
  * limitations under the License.
18
18
  */
19
19
 
20
- import type { ContextSpy } from './core/lib/ContextSpy.js';
21
-
22
- export function createWebGLContext(
23
- canvas: HTMLCanvasElement | OffscreenCanvas,
24
- forceWebGL2 = false,
25
- contextSpy: ContextSpy | null,
26
- ): WebGLRenderingContext {
27
- const config: WebGLContextAttributes = {
28
- alpha: true,
29
- antialias: false,
30
- depth: false,
31
- stencil: true,
32
- desynchronized: false,
33
- // Disabled because it prevents Visual Regression Tests from working
34
- // failIfMajorPerformanceCaveat: true,
35
- powerPreference: 'high-performance',
36
- premultipliedAlpha: true,
37
- preserveDrawingBuffer: false,
38
- };
39
- const gl =
40
- // TODO: Remove this assertion once this issue is fixed in TypeScript
41
- // https://github.com/microsoft/TypeScript/issues/53614
42
- (canvas.getContext(forceWebGL2 ? 'webgl2' : 'webgl', config) ||
43
- canvas.getContext(
44
- 'experimental-webgl' as 'webgl',
45
- config,
46
- )) as unknown as WebGLRenderingContext | null;
47
- if (!gl) {
48
- throw new Error('Unable to create WebGL context');
49
- }
50
- if (contextSpy) {
51
- // Proxy the GL context to log all GL calls
52
- return new Proxy(gl, {
53
- get(target, prop) {
54
- const value = target[prop as never] as unknown;
55
- if (typeof value === 'function') {
56
- contextSpy.increment(String(prop));
57
- return value.bind(target);
58
- }
59
- return value;
60
- },
61
- });
62
- }
63
-
64
- return gl;
65
- }
66
-
67
20
  /**
68
21
  * Checks if we're in a development environment or not.
69
22
  *