@lightningjs/renderer 2.0.0 → 2.1.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 (40) hide show
  1. package/dist/exports/canvas.d.ts +2 -0
  2. package/dist/exports/canvas.js +2 -0
  3. package/dist/exports/canvas.js.map +1 -1
  4. package/dist/exports/index.d.ts +1 -1
  5. package/dist/exports/index.js +1 -1
  6. package/dist/exports/inspector.d.ts +3 -0
  7. package/dist/exports/inspector.js +3 -0
  8. package/dist/exports/inspector.js.map +1 -1
  9. package/dist/exports/utils.d.ts +2 -0
  10. package/dist/exports/utils.js +2 -0
  11. package/dist/exports/utils.js.map +1 -1
  12. package/dist/src/core/CoreNode.d.ts +8 -2
  13. package/dist/src/core/CoreNode.js +71 -23
  14. package/dist/src/core/CoreNode.js.map +1 -1
  15. package/dist/src/core/Stage.js +4 -4
  16. package/dist/src/core/Stage.js.map +1 -1
  17. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js +2 -1
  18. package/dist/src/core/renderers/canvas/CanvasCoreTexture.js.map +1 -1
  19. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +2 -1
  20. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  21. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +10 -6
  22. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
  23. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +2 -1
  24. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
  25. package/dist/src/main-api/Renderer.d.ts +1 -1
  26. package/dist/src/main-api/Renderer.js +1 -1
  27. package/dist/src/main-api/Renderer.js.map +1 -1
  28. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  29. package/exports/canvas.ts +2 -0
  30. package/exports/index.ts +1 -1
  31. package/exports/inspector.ts +4 -0
  32. package/exports/utils.ts +2 -0
  33. package/package.json +1 -1
  34. package/src/core/CoreNode.ts +109 -39
  35. package/src/core/Stage.ts +4 -4
  36. package/src/core/renderers/canvas/CanvasCoreTexture.ts +4 -1
  37. package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +2 -1
  38. package/src/core/renderers/webgl/WebGlCoreRenderer.ts +11 -6
  39. package/src/core/renderers/webgl/shaders/DynamicShader.ts +1 -0
  40. package/src/main-api/Renderer.ts +2 -2
@@ -178,6 +178,11 @@ export enum UpdateType {
178
178
  */
179
179
  ParentRenderTexture = 4096,
180
180
 
181
+ /**
182
+ * Render Bounds update
183
+ */
184
+ RenderBounds = 8192,
185
+
181
186
  /**
182
187
  * None
183
188
  */
@@ -738,6 +743,10 @@ export class CoreNode extends EventEmitter {
738
743
  this.rtt = props.rtt;
739
744
 
740
745
  this.updateScaleRotateTransform();
746
+
747
+ this.setUpdateType(
748
+ UpdateType.Local | UpdateType.RenderBounds | UpdateType.RenderState,
749
+ );
741
750
  }
742
751
 
743
752
  //#region Textures
@@ -988,16 +997,42 @@ export class CoreNode extends EventEmitter {
988
997
 
989
998
  this.calculateRenderCoords();
990
999
  this.updateBoundingRect();
991
- this.setUpdateType(
992
- UpdateType.Clipping | UpdateType.RenderState | UpdateType.Children,
993
- );
1000
+
1001
+ this.setUpdateType(UpdateType.RenderState | UpdateType.Children);
1002
+
1003
+ if (this.clipping === true) {
1004
+ this.setUpdateType(UpdateType.Clipping);
1005
+ }
1006
+
994
1007
  childUpdateType |= UpdateType.Global;
995
1008
  }
996
1009
 
1010
+ if (this.updateType & UpdateType.RenderBounds) {
1011
+ this.createRenderBounds();
1012
+ this.setUpdateType(UpdateType.RenderState);
1013
+ this.setUpdateType(UpdateType.Children);
1014
+ }
1015
+
1016
+ if (this.updateType & UpdateType.RenderState) {
1017
+ this.updateRenderState();
1018
+ this.setUpdateType(UpdateType.IsRenderable);
1019
+ }
1020
+
1021
+ if (this.updateType & UpdateType.IsRenderable) {
1022
+ this.updateIsRenderable();
1023
+ }
1024
+
1025
+ if (this.renderState === CoreNodeRenderState.OutOfBounds) {
1026
+ this.updateType = 0;
1027
+ return;
1028
+ }
1029
+
997
1030
  if (this.updateType & UpdateType.Clipping) {
998
1031
  this.calculateClippingRect(parentClippingRect);
999
1032
  this.setUpdateType(UpdateType.Children);
1033
+
1000
1034
  childUpdateType |= UpdateType.Clipping;
1035
+ childUpdateType |= UpdateType.RenderBounds;
1001
1036
  }
1002
1037
 
1003
1038
  if (this.updateType & UpdateType.WorldAlpha) {
@@ -1050,17 +1085,8 @@ export class CoreNode extends EventEmitter {
1050
1085
  }
1051
1086
  }
1052
1087
 
1053
- if (this.updateType & UpdateType.RenderState) {
1054
- this.updateRenderState(parentClippingRect);
1055
- this.setUpdateType(UpdateType.IsRenderable);
1056
- }
1057
-
1058
- if (this.updateType & UpdateType.IsRenderable) {
1059
- this.updateIsRenderable();
1060
- }
1061
-
1062
1088
  // No need to update zIndex if there is no parent
1063
- if (parent && this.updateType & UpdateType.CalculatedZIndex) {
1089
+ if (parent !== null && this.updateType & UpdateType.CalculatedZIndex) {
1064
1090
  this.calculateZIndex();
1065
1091
  // Tell parent to re-sort children
1066
1092
  parent.setUpdateType(UpdateType.ZIndexSortedChildren);
@@ -1068,8 +1094,8 @@ export class CoreNode extends EventEmitter {
1068
1094
 
1069
1095
  if (
1070
1096
  this.updateType & UpdateType.Children &&
1071
- this.children.length &&
1072
- !this.rtt
1097
+ this.children.length > 0 &&
1098
+ this.rtt === false
1073
1099
  ) {
1074
1100
  this.children.forEach((child) => {
1075
1101
  // Trigger the depenedent update types on the child
@@ -1151,39 +1177,78 @@ export class CoreNode extends EventEmitter {
1151
1177
  return false;
1152
1178
  }
1153
1179
 
1154
- checkRenderBounds(parentClippingRect: RectWithValid): CoreNodeRenderState {
1180
+ checkRenderBounds(): CoreNodeRenderState {
1155
1181
  assertTruthy(this.renderBound);
1156
- const rectW = parentClippingRect.width || this.stage.root.width;
1157
- const rectH = parentClippingRect.height || this.stage.root.height;
1158
- this.strictBound = createBound(
1159
- parentClippingRect.x,
1160
- parentClippingRect.y,
1161
- parentClippingRect.x + rectW,
1162
- parentClippingRect.y + rectH,
1163
- this.strictBound,
1164
- );
1182
+ assertTruthy(this.strictBound);
1183
+ assertTruthy(this.preloadBound);
1165
1184
 
1166
1185
  if (boundInsideBound(this.renderBound, this.strictBound)) {
1167
1186
  return CoreNodeRenderState.InViewport;
1168
1187
  }
1169
1188
 
1189
+ if (boundInsideBound(this.renderBound, this.preloadBound)) {
1190
+ return CoreNodeRenderState.InBounds;
1191
+ }
1192
+
1193
+ return CoreNodeRenderState.OutOfBounds;
1194
+ }
1195
+
1196
+ createPreloadBounds(strictBound: Bound): Bound {
1170
1197
  const renderM = this.stage.boundsMargin;
1171
- this.preloadBound = createBound(
1172
- this.strictBound.x1 - renderM[3],
1173
- this.strictBound.y1 - renderM[0],
1174
- this.strictBound.x2 + renderM[1],
1175
- this.strictBound.y2 + renderM[2],
1198
+ return createBound(
1199
+ strictBound.x1 - renderM[3],
1200
+ strictBound.y1 - renderM[0],
1201
+ strictBound.x2 + renderM[1],
1202
+ strictBound.y2 + renderM[2],
1176
1203
  this.preloadBound,
1177
1204
  );
1205
+ }
1178
1206
 
1179
- if (boundInsideBound(this.renderBound, this.preloadBound)) {
1180
- return CoreNodeRenderState.InBounds;
1207
+ createRenderBounds(): void {
1208
+ assertTruthy(this.stage);
1209
+
1210
+ // no clipping, use parent's bounds
1211
+ if (this.clipping === false) {
1212
+ if (this.parent !== null) {
1213
+ this.strictBound =
1214
+ this.parent.strictBound ??
1215
+ createBound(0, 0, this.stage.root.width, this.stage.root.height);
1216
+
1217
+ this.preloadBound =
1218
+ this.parent.preloadBound ??
1219
+ this.createPreloadBounds(this.strictBound);
1220
+ return;
1221
+ } else {
1222
+ this.strictBound = createBound(
1223
+ 0,
1224
+ 0,
1225
+ this.stage.root.width,
1226
+ this.stage.root.height,
1227
+ );
1228
+
1229
+ this.preloadBound = this.createPreloadBounds(this.strictBound);
1230
+ return;
1231
+ }
1181
1232
  }
1182
- return CoreNodeRenderState.OutOfBounds;
1233
+
1234
+ // clipping is enabled create our own bounds
1235
+ const { x, y, width, height } = this.props;
1236
+ const { tx, ty } = this.globalTransform || {};
1237
+ const _x = tx ?? x;
1238
+ const _y = ty ?? y;
1239
+ this.strictBound = createBound(
1240
+ _x,
1241
+ _y,
1242
+ _x + width,
1243
+ _y + height,
1244
+ this.strictBound,
1245
+ );
1246
+
1247
+ this.preloadBound = this.createPreloadBounds(this.strictBound);
1183
1248
  }
1184
1249
 
1185
- updateRenderState(parentClippingRect: RectWithValid) {
1186
- const renderState = this.checkRenderBounds(parentClippingRect);
1250
+ updateRenderState() {
1251
+ const renderState = this.checkRenderBounds();
1187
1252
 
1188
1253
  if (renderState === this.renderState) {
1189
1254
  return;
@@ -1300,7 +1365,7 @@ export class CoreNode extends EventEmitter {
1300
1365
 
1301
1366
  const isRotated = gt.tb !== 0 || gt.tc !== 0;
1302
1367
 
1303
- if (clipping && !isRotated) {
1368
+ if (clipping === true && isRotated === false) {
1304
1369
  clippingRect.x = gt.tx;
1305
1370
  clippingRect.y = gt.ty;
1306
1371
  clippingRect.width = this.width * gt.ta;
@@ -1310,10 +1375,10 @@ export class CoreNode extends EventEmitter {
1310
1375
  clippingRect.valid = false;
1311
1376
  }
1312
1377
 
1313
- if (parentClippingRect.valid && clippingRect.valid) {
1378
+ if (parentClippingRect.valid === true && clippingRect.valid === true) {
1314
1379
  // Intersect parent clipping rect with node clipping rect
1315
1380
  intersectRect(parentClippingRect, clippingRect, clippingRect);
1316
- } else if (parentClippingRect.valid) {
1381
+ } else if (parentClippingRect.valid === true) {
1317
1382
  // Copy parent clipping rect
1318
1383
  copyRect(parentClippingRect, clippingRect);
1319
1384
  clippingRect.valid = true;
@@ -1659,7 +1724,9 @@ export class CoreNode extends EventEmitter {
1659
1724
 
1660
1725
  set clipping(value: boolean) {
1661
1726
  this.props.clipping = value;
1662
- this.setUpdateType(UpdateType.Clipping);
1727
+ this.setUpdateType(
1728
+ UpdateType.Clipping | UpdateType.RenderBounds | UpdateType.Children,
1729
+ );
1663
1730
  }
1664
1731
 
1665
1732
  get color(): number {
@@ -1825,6 +1892,9 @@ export class CoreNode extends EventEmitter {
1825
1892
  }
1826
1893
  }
1827
1894
  this.updateScaleRotateTransform();
1895
+
1896
+ // fetch render bounds from parent
1897
+ this.setUpdateType(UpdateType.RenderBounds | UpdateType.Children);
1828
1898
  }
1829
1899
 
1830
1900
  get preventCleanup(): boolean {
package/src/core/Stage.ts CHANGED
@@ -381,20 +381,20 @@ export class Stage {
381
381
  }
382
382
 
383
383
  addQuads(node: CoreNode) {
384
- assertTruthy(this.renderer && node.globalTransform);
384
+ assertTruthy(this.renderer);
385
385
 
386
- if (node.isRenderable) {
386
+ if (node.isRenderable === true) {
387
387
  node.renderQuads(this.renderer);
388
388
  }
389
389
 
390
390
  for (let i = 0; i < node.children.length; i++) {
391
391
  const child = node.children[i];
392
392
 
393
- if (!child) {
393
+ if (child === undefined) {
394
394
  continue;
395
395
  }
396
396
 
397
- if (child?.worldAlpha === 0) {
397
+ if (child.worldAlpha === 0) {
398
398
  continue;
399
399
  }
400
400
 
@@ -131,7 +131,10 @@ export class CanvasCoreTexture extends CoreContextTexture {
131
131
  if (ctx) ctx.putImageData(data, 0, 0);
132
132
  this.image = canvas;
133
133
  return { width: data.width, height: data.height };
134
- } else if (data instanceof ImageBitmap) {
134
+ } else if (
135
+ typeof ImageBitmap !== 'undefined' &&
136
+ data instanceof ImageBitmap
137
+ ) {
135
138
  this.image = data;
136
139
  return { width: data.width, height: data.height };
137
140
  }
@@ -134,7 +134,8 @@ export class WebGlCoreCtxTexture extends CoreContextTexture {
134
134
  // If textureData is null, the texture is empty (0, 0) and we don't need to
135
135
  // upload any data to the GPU.
136
136
  if (
137
- textureData.data instanceof ImageBitmap ||
137
+ (typeof ImageBitmap !== 'undefined' &&
138
+ textureData.data instanceof ImageBitmap) ||
138
139
  textureData.data instanceof ImageData ||
139
140
  // not using typeof HTMLImageElement due to web worker
140
141
  isHTMLImageElement(textureData.data)
@@ -254,13 +254,18 @@ export class WebGlCoreRenderer extends CoreRenderer {
254
254
 
255
255
  /**
256
256
  * If the shader props contain any automatic properties, update it with the
257
- * current dimensions that will be used to render the quad.
257
+ * current dimensions and or alpha that will be used to render the quad.
258
258
  */
259
- if (shaderProps && hasOwn(shaderProps, '$dimensions')) {
260
- const dimensions = shaderProps.$dimensions as Dimensions;
261
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
262
- dimensions.width = width;
263
- dimensions.height = height;
259
+ if (shaderProps !== null) {
260
+ if (hasOwn(shaderProps, '$dimensions')) {
261
+ const dimensions = shaderProps.$dimensions as Dimensions;
262
+ dimensions.width = width;
263
+ dimensions.height = height;
264
+ }
265
+
266
+ if (hasOwn(shaderProps, '$alpha')) {
267
+ shaderProps.$alpha = alpha;
268
+ }
264
269
  }
265
270
 
266
271
  texture = texture ?? this.defaultTexture;
@@ -172,6 +172,7 @@ export class DynamicShader extends WebGlCoreShader {
172
172
  propsB: Required<DynamicShaderProps>,
173
173
  ): boolean {
174
174
  if (
175
+ propsA.$alpha !== propsB.$alpha ||
175
176
  propsA.$dimensions.width !== propsB.$dimensions.width ||
176
177
  propsA.$dimensions.height !== propsB.$dimensions.height ||
177
178
  propsA.effects.length !== propsB.effects.length
@@ -192,7 +192,7 @@ export interface RendererMainSettings {
192
192
  * in the renderer and allow inspection of the state of the nodes.
193
193
  *
194
194
  */
195
- inspector: typeof Inspector | undefined;
195
+ inspector?: typeof Inspector | false;
196
196
 
197
197
  /**
198
198
  * Renderer Engine
@@ -330,7 +330,7 @@ export class RendererMain extends EventEmitter {
330
330
  numImageWorkers:
331
331
  settings.numImageWorkers !== undefined ? settings.numImageWorkers : 2,
332
332
  enableContextSpy: settings.enableContextSpy ?? false,
333
- inspector: settings.inspector,
333
+ inspector: settings.inspector ?? false,
334
334
  renderEngine: settings.renderEngine,
335
335
  quadBufferSize: settings.quadBufferSize ?? 4 * 1024 * 1024,
336
336
  fontEngines: settings.fontEngines,