@lightningjs/renderer 1.0.0-rc.0 → 1.0.0-rc.1

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 (35) hide show
  1. package/dist/exports/index.d.ts +2 -0
  2. package/dist/exports/index.js +2 -0
  3. package/dist/exports/index.js.map +1 -1
  4. package/dist/src/core/CoreNode.d.ts +3 -4
  5. package/dist/src/core/CoreNode.js +14 -16
  6. package/dist/src/core/CoreNode.js.map +1 -1
  7. package/dist/src/core/CoreShaderManager.d.ts +1 -1
  8. package/dist/src/core/Stage.js +1 -1
  9. package/dist/src/core/Stage.js.map +1 -1
  10. package/dist/src/core/animations/CoreAnimation.d.ts +1 -1
  11. package/dist/src/core/animations/CoreAnimation.js +28 -26
  12. package/dist/src/core/animations/CoreAnimation.js.map +1 -1
  13. package/dist/src/core/renderers/webgl/shaders/DynamicShader.d.ts +1 -58
  14. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
  15. package/dist/src/core/renderers/webgl/shaders/effects/ShaderEffect.d.ts +58 -0
  16. package/dist/src/core/renderers/webgl/shaders/effects/ShaderEffect.js.map +1 -1
  17. package/dist/src/main-api/DynamicShaderController.d.ts +6 -5
  18. package/dist/src/main-api/DynamicShaderController.js +3 -0
  19. package/dist/src/main-api/DynamicShaderController.js.map +1 -1
  20. package/dist/src/main-api/INode.d.ts +1 -1
  21. package/dist/src/main-api/Renderer.d.ts +44 -4
  22. package/dist/src/main-api/Renderer.js +42 -2
  23. package/dist/src/main-api/Renderer.js.map +1 -1
  24. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  25. package/exports/index.ts +2 -0
  26. package/package.json +1 -1
  27. package/src/core/CoreNode.ts +18 -19
  28. package/src/core/CoreShaderManager.ts +2 -2
  29. package/src/core/Stage.ts +1 -1
  30. package/src/core/animations/CoreAnimation.ts +35 -33
  31. package/src/core/renderers/webgl/shaders/DynamicShader.ts +2 -59
  32. package/src/core/renderers/webgl/shaders/effects/ShaderEffect.ts +60 -0
  33. package/src/main-api/DynamicShaderController.ts +12 -5
  34. package/src/main-api/INode.ts +3 -2
  35. package/src/main-api/Renderer.ts +48 -5
package/exports/index.ts CHANGED
@@ -39,6 +39,8 @@
39
39
 
40
40
  export * from '../src/main-api/INode.js';
41
41
  export * from '../src/main-api/Renderer.js';
42
+ export * from '../src/main-api/ShaderController.js';
43
+ export * from '../src/main-api/DynamicShaderController.js';
42
44
  export * from '../src/common/IAnimationController.js';
43
45
  export * from '../src/common/CommonTypes.js';
44
46
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightningjs/renderer",
3
- "version": "1.0.0-rc.0",
3
+ "version": "1.0.0-rc.1",
4
4
  "description": "Lightning 3 Renderer",
5
5
  "type": "module",
6
6
  "main": "./dist/exports/index.js",
@@ -644,7 +644,7 @@ export interface CoreNodeAnimateProps extends NumberProps<CoreNodeProps> {
644
644
  export class CoreNode extends EventEmitter {
645
645
  readonly children: CoreNode[] = [];
646
646
  protected _id: number = getNewId();
647
- readonly props: Required<CoreNodeProps>;
647
+ readonly props: CoreNodeProps;
648
648
 
649
649
  public updateType = UpdateType.All;
650
650
 
@@ -673,7 +673,6 @@ export class CoreNode extends EventEmitter {
673
673
  public calcZIndex = 0;
674
674
  public hasRTTupdates = false;
675
675
  public parentHasRenderTexture = false;
676
- private _src = '';
677
676
 
678
677
  constructor(readonly stage: Stage, props: CoreNodeProps) {
679
678
  super();
@@ -682,19 +681,14 @@ export class CoreNode extends EventEmitter {
682
681
  ...props,
683
682
  parent: null,
684
683
  texture: null,
685
- shader: stage.defShaderCtr,
686
- src: '',
684
+ src: null,
687
685
  rtt: false,
688
- data: props.data || {},
689
686
  };
690
687
 
691
688
  // Assign props to instance
692
689
  this.parent = props.parent;
693
- this.shader = props.shader;
694
690
  this.texture = props.texture;
695
- this.src = props.src || '';
696
- // FIXME
697
- // this.data = props.data;
691
+ this.src = props.src;
698
692
  this.rtt = props.rtt;
699
693
 
700
694
  this.updateScaleRotateTransform();
@@ -1062,7 +1056,7 @@ export class CoreNode extends EventEmitter {
1062
1056
  return false;
1063
1057
  }
1064
1058
 
1065
- if (this.props.shader === this.stage.defShaderCtr) {
1059
+ if (this.props.shader !== this.stage.defShaderCtr) {
1066
1060
  return true;
1067
1061
  }
1068
1062
 
@@ -1312,12 +1306,19 @@ export class CoreNode extends EventEmitter {
1312
1306
  this.props.texture = null;
1313
1307
  this.props.shader = this.stage.defShaderCtr;
1314
1308
 
1309
+ const children = [...this.children];
1310
+ for (let i = 0; i < children.length; i++) {
1311
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
1312
+ children[i]!.destroy();
1313
+ }
1314
+ // This very action will also remove the node from the parent's children array
1315
+ this.parent = null;
1316
+
1315
1317
  if (this.rtt) {
1316
1318
  this.stage.renderer.removeRTTNode(this);
1317
1319
  }
1318
1320
 
1319
1321
  this.removeAllListeners();
1320
- this.parent = null;
1321
1322
  }
1322
1323
 
1323
1324
  renderQuads(renderer: CoreRenderer): void {
@@ -1823,21 +1824,19 @@ export class CoreNode extends EventEmitter {
1823
1824
 
1824
1825
  this.props.shader = value;
1825
1826
 
1826
- if (value === this.stage.defShaderCtr) {
1827
- this.setUpdateType(UpdateType.IsRenderable);
1828
- }
1827
+ this.setUpdateType(UpdateType.IsRenderable);
1829
1828
  }
1830
1829
 
1831
- get src(): string {
1832
- return this._src;
1830
+ get src(): string | null {
1831
+ return this.props.src;
1833
1832
  }
1834
1833
 
1835
- set src(imageUrl: string) {
1836
- if (this._src === imageUrl) {
1834
+ set src(imageUrl: string | null) {
1835
+ if (this.props.src === imageUrl) {
1837
1836
  return;
1838
1837
  }
1839
1838
 
1840
- this._src = imageUrl;
1839
+ this.props.src = imageUrl;
1841
1840
 
1842
1841
  if (!imageUrl) {
1843
1842
  this.texture = null;
@@ -230,7 +230,7 @@ export class CoreShaderManager {
230
230
  }
231
231
 
232
232
  loadDynamicShader<
233
- T extends DynamicEffects<[...{ name: string; type: keyof EffectMap }[]]>,
233
+ T extends DynamicEffects<[...{ name?: string; type: keyof EffectMap }[]]>,
234
234
  >(props: DynamicShaderProps): DynamicShaderController<T> {
235
235
  if (!this.renderer) {
236
236
  throw new Error(`Renderer is not been defined`);
@@ -270,7 +270,7 @@ export class CoreShaderManager {
270
270
  }
271
271
 
272
272
  private _createDynShaderCtr<
273
- T extends DynamicEffects<[...{ name: string; type: keyof EffectMap }[]]>,
273
+ T extends DynamicEffects<[...{ name?: string; type: keyof EffectMap }[]]>,
274
274
  >(
275
275
  shader: InstanceType<ShaderMap['DynamicShader']>,
276
276
  props: ExtractProps<ShaderMap['DynamicShader']>,
package/src/core/Stage.ts CHANGED
@@ -548,7 +548,7 @@ export class Stage {
548
548
  shader: props.shader ?? this.defShaderCtr,
549
549
  // Since setting the `src` will trigger a texture load, we need to set it after
550
550
  // we set the texture. Otherwise, problems happen.
551
- src: props.src ?? '',
551
+ src: props.src ?? null,
552
552
  scale: props.scale ?? null,
553
553
  scaleX: props.scaleX ?? props.scale ?? 1,
554
554
  scaleY: props.scaleY ?? props.scale ?? 1,
@@ -45,7 +45,7 @@ export class CoreAnimation extends EventEmitter {
45
45
  private timingFunction: (t: number) => number | undefined;
46
46
 
47
47
  propValuesMap: PropValuesMap = {};
48
- dynPropValuesMap: PropValuesMap = {};
48
+ dynPropValuesMap: PropValuesMap | undefined = undefined;
49
49
 
50
50
  constructor(
51
51
  private node: CoreNode,
@@ -76,16 +76,15 @@ export class CoreAnimation extends EventEmitter {
76
76
  } else {
77
77
  const shaderPropKeys = Object.keys(props.shaderProps!);
78
78
  const spLength = shaderPropKeys.length;
79
- let j = 0;
80
- for (; j < spLength; j++) {
79
+ this.dynPropValuesMap = {};
80
+ for (let j = 0; j < spLength; j++) {
81
81
  const effectName = shaderPropKeys[j]!;
82
82
  const effect = props.shaderProps![effectName]!;
83
83
  this.dynPropValuesMap[effectName] = {};
84
84
  const effectProps = Object.entries(effect);
85
85
  const eLength = effectProps.length;
86
86
 
87
- let k = 0;
88
- for (; k < eLength; k++) {
87
+ for (let k = 0; k < eLength; k++) {
89
88
  const [key, value] = effectProps[k]!;
90
89
  this.dynPropValuesMap[effectName]![key] = {
91
90
  start: node.shader.props[effectName][key],
@@ -145,16 +144,17 @@ export class CoreAnimation extends EventEmitter {
145
144
  );
146
145
  }
147
146
 
148
- const dynEntries = Object.keys(this.dynPropValuesMap);
149
- const dynEntriesL = dynEntries.length;
150
- if (dynEntriesL > 0) {
151
- let i = 0;
152
- for (; i < dynEntriesL; i++) {
153
- const key = dynEntries[i]!;
154
- this.restoreValues(
155
- this.node.shader.props[key],
156
- this.dynPropValuesMap[key]!,
157
- );
147
+ if (this.dynPropValuesMap !== undefined) {
148
+ const dynEntries = Object.keys(this.dynPropValuesMap);
149
+ const dynEntriesL = dynEntries.length;
150
+ if (dynEntriesL > 0) {
151
+ for (let i = 0; i < dynEntriesL; i++) {
152
+ const key = dynEntries[i]!;
153
+ this.restoreValues(
154
+ this.node.shader.props[key],
155
+ this.dynPropValuesMap[key]!,
156
+ );
157
+ }
158
158
  }
159
159
  }
160
160
  }
@@ -182,13 +182,14 @@ export class CoreAnimation extends EventEmitter {
182
182
  this.reverseValues(this.propValuesMap['shaderProps']);
183
183
  }
184
184
 
185
- const dynEntries = Object.keys(this.dynPropValuesMap);
186
- const dynEntriesL = dynEntries.length;
187
- if (dynEntriesL > 0) {
188
- let i = 0;
189
- for (; i < dynEntriesL; i++) {
190
- const key = dynEntries[i]!;
191
- this.reverseValues(this.dynPropValuesMap[key]!);
185
+ if (this.dynPropValuesMap !== undefined) {
186
+ const dynEntries = Object.keys(this.dynPropValuesMap);
187
+ const dynEntriesL = dynEntries.length;
188
+ if (dynEntriesL > 0) {
189
+ for (let i = 0; i < dynEntriesL; i++) {
190
+ const key = dynEntries[i]!;
191
+ this.reverseValues(this.dynPropValuesMap[key]!);
192
+ }
192
193
  }
193
194
  }
194
195
 
@@ -309,17 +310,18 @@ export class CoreAnimation extends EventEmitter {
309
310
  );
310
311
  }
311
312
 
312
- const dynEntries = Object.keys(this.dynPropValuesMap);
313
- const dynEntriesL = dynEntries.length;
314
- if (dynEntriesL > 0) {
315
- let i = 0;
316
- for (; i < dynEntriesL; i++) {
317
- const key = dynEntries[i]!;
318
- this.updateValues(
319
- this.node.shader.props[key],
320
- this.dynPropValuesMap[key]!,
321
- easing,
322
- );
313
+ if (this.dynPropValuesMap !== undefined) {
314
+ const dynEntries = Object.keys(this.dynPropValuesMap);
315
+ const dynEntriesL = dynEntries.length;
316
+ if (dynEntriesL > 0) {
317
+ for (let i = 0; i < dynEntriesL; i++) {
318
+ const key = dynEntries[i]!;
319
+ this.updateValues(
320
+ this.node.shader.props[key],
321
+ this.dynPropValuesMap[key]!,
322
+ easing,
323
+ );
324
+ }
323
325
  }
324
326
  }
325
327
 
@@ -16,7 +16,6 @@
16
16
  * See the License for the specific language governing permissions and
17
17
  * limitations under the License.
18
18
  */
19
- import type { ExtractProps } from '../../../CoreTextureManager.js';
20
19
  import type { WebGlCoreRenderer } from '../WebGlCoreRenderer.js';
21
20
  import {
22
21
  WebGlCoreShader,
@@ -27,70 +26,14 @@ import type { UniformInfo } from '../internal/ShaderUtils.js';
27
26
  import type { WebGlCoreCtxTexture } from '../WebGlCoreCtxTexture.js';
28
27
  import {
29
28
  ShaderEffect,
29
+ type EffectDescUnion,
30
30
  type ShaderEffectUniform,
31
31
  type ShaderEffectValueMap,
32
+ type BaseEffectDesc,
32
33
  } from './effects/ShaderEffect.js';
33
34
  import type { EffectMap } from '../../../CoreShaderManager.js';
34
35
  import { assertTruthy } from '../../../../utils.js';
35
36
 
36
- export interface BaseEffectDesc {
37
- name: string;
38
- type: keyof EffectMap;
39
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
- props: Record<string, any>;
41
- }
42
-
43
- export interface EffectDesc<
44
- T extends { name: string; type: keyof EffectMap } = {
45
- name: string;
46
- type: keyof EffectMap;
47
- },
48
- > extends BaseEffectDesc {
49
- name: T['name'];
50
- type: T['type'];
51
- props: ExtractProps<EffectMap[T['type']]>;
52
- }
53
-
54
- /**
55
- * Allows the `keyof EffectMap` to be mapped over and form an discriminated
56
- * union of all the EffectDescs structures individually.
57
- *
58
- * @remarks
59
- * When used like the following:
60
- * ```
61
- * MapEffectDescs<keyof EffectMap>[]
62
- * ```
63
- * The resultant type will be a discriminated union like so:
64
- * ```
65
- * (
66
- * {
67
- * name: 'effect1',
68
- * type: 'radius',
69
- * props?: {
70
- * radius?: number | number[];
71
- * }
72
- * } |
73
- * {
74
- * name: 'effect2',
75
- * type: 'border',
76
- * props?: {
77
- * width?: number;
78
- * color?: number;
79
- * }
80
- * } |
81
- * // ...
82
- * )[]
83
- * ```
84
- * Which means TypeScript will now base its type checking on the `type` field
85
- * and will know exactly what the `props` field should be based on the `type`
86
- * field.
87
- */
88
- type MapEffectDescs<T extends keyof EffectMap> = T extends keyof EffectMap
89
- ? EffectDesc<{ type: T; name: string }>
90
- : never;
91
-
92
- export type EffectDescUnion = MapEffectDescs<keyof EffectMap>;
93
-
94
37
  export interface DynamicShaderProps
95
38
  extends DimensionsShaderProp,
96
39
  AlphaShaderProp {
@@ -1,3 +1,5 @@
1
+ import type { EffectMap } from '../../../../CoreShaderManager.js';
2
+ import type { ExtractProps } from '../../../../CoreTextureManager.js';
1
3
  import type {
2
4
  AlphaShaderProp,
3
5
  DimensionsShaderProp,
@@ -7,6 +9,64 @@ import type {
7
9
  UniformMethodMap,
8
10
  } from '../../internal/ShaderUtils.js';
9
11
 
12
+ export interface BaseEffectDesc {
13
+ name?: string;
14
+ type: keyof EffectMap;
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ props: Record<string, any>;
17
+ }
18
+
19
+ export interface EffectDesc<
20
+ T extends { name?: string; type: keyof EffectMap } = {
21
+ name?: string;
22
+ type: keyof EffectMap;
23
+ },
24
+ > extends BaseEffectDesc {
25
+ name?: T['name'];
26
+ type: T['type'];
27
+ props: ExtractProps<EffectMap[T['type']]>;
28
+ }
29
+
30
+ /**
31
+ * Allows the `keyof EffectMap` to be mapped over and form an discriminated
32
+ * union of all the EffectDescs structures individually.
33
+ *
34
+ * @remarks
35
+ * When used like the following:
36
+ * ```
37
+ * MapEffectDescs<keyof EffectMap>[]
38
+ * ```
39
+ * The resultant type will be a discriminated union like so:
40
+ * ```
41
+ * (
42
+ * {
43
+ * name: 'effect1',
44
+ * type: 'radius',
45
+ * props?: {
46
+ * radius?: number | number[];
47
+ * }
48
+ * } |
49
+ * {
50
+ * name: 'effect2',
51
+ * type: 'border',
52
+ * props?: {
53
+ * width?: number;
54
+ * color?: number;
55
+ * }
56
+ * } |
57
+ * // ...
58
+ * )[]
59
+ * ```
60
+ * Which means TypeScript will now base its type checking on the `type` field
61
+ * and will know exactly what the `props` field should be based on the `type`
62
+ * field.
63
+ */
64
+ type MapEffectDescs<T extends keyof EffectMap> = T extends keyof EffectMap
65
+ ? EffectDesc<{ type: T; name: string }>
66
+ : never;
67
+
68
+ export type EffectDescUnion = MapEffectDescs<keyof EffectMap>;
69
+
10
70
  export interface ShaderEffectUniform {
11
71
  value: number | number[] | boolean | string;
12
72
  type: string;
@@ -5,23 +5,27 @@ import type {
5
5
  ShaderMap,
6
6
  } from '../core/CoreShaderManager.js';
7
7
  import type { ExtractProps } from '../core/CoreTextureManager.js';
8
- import type { EffectDesc } from '../core/renderers/webgl/shaders/DynamicShader.js';
8
+ import type { EffectDesc } from '../core/renderers/webgl/shaders/effects/ShaderEffect.js';
9
9
  import type { BaseShaderController } from './ShaderController.js';
10
10
 
11
+ type OptionalName<T> = T extends string ? T : never;
12
+
11
13
  type MapEffectProps<
12
- Effects extends [...{ name: string; type: keyof EffectMap }[]],
14
+ Effects extends [...{ name?: string; type: keyof EffectMap }[]],
13
15
  > = {
14
- [K in Effects[number] as K['name']]: ExtractProps<EffectMap[K['type']]>;
16
+ [K in Effects[number] as OptionalName<K['name']>]: ExtractProps<
17
+ EffectMap[K['type']]
18
+ >;
15
19
  };
16
20
 
17
21
  export type DynamicEffects<
18
- T extends [...{ name: string; type: keyof EffectMap }[]],
22
+ T extends [...{ name?: string; type: keyof EffectMap }[]],
19
23
  > = {
20
24
  [K in keyof T]: EffectDesc<T[K]>;
21
25
  };
22
26
 
23
27
  export class DynamicShaderController<
24
- Effects extends [...{ name: string; type: keyof EffectMap }[]],
28
+ Effects extends [...{ name?: string; type: keyof EffectMap }[]],
25
29
  > implements BaseShaderController
26
30
  {
27
31
  private resolvedProps: ExtractProps<ShaderMap['DynamicShader']>;
@@ -47,6 +51,9 @@ export class DynamicShaderController<
47
51
  props: effectProps,
48
52
  type: effectType,
49
53
  } = effects[i]!;
54
+ if (effectName === undefined) {
55
+ continue;
56
+ }
50
57
  const definedEffectProps = {};
51
58
  const propEntries = Object.keys(effectProps);
52
59
  const propEntriesLength = propEntries.length;
@@ -57,8 +57,9 @@ export interface INode<SC extends BaseShaderController = BaseShaderController>
57
57
  /**
58
58
  * Properties used to animate() a Node
59
59
  */
60
- export interface INodeAnimateProps<SC extends BaseShaderController>
61
- extends Omit<CoreNodeAnimateProps, 'shaderProps'> {
60
+ export interface INodeAnimateProps<
61
+ SC extends BaseShaderController = BaseShaderController,
62
+ > extends Omit<CoreNodeAnimateProps, 'shaderProps'> {
62
63
  shaderProps: Partial<SC['props']>;
63
64
  }
64
65
 
@@ -29,7 +29,7 @@ import { Inspector } from './Inspector.js';
29
29
  import { assertTruthy, isProductionEnvironment } from '../utils.js';
30
30
  import { Stage } from '../core/Stage.js';
31
31
  import { CoreNode, type CoreNodeProps } from '../core/CoreNode.js';
32
- import { CoreTextNode, type CoreTextNodeProps } from '../core/CoreTextNode.js';
32
+ import { type CoreTextNodeProps } from '../core/CoreTextNode.js';
33
33
  import type {
34
34
  BaseShaderController,
35
35
  ShaderController,
@@ -42,7 +42,7 @@ import type {
42
42
  import type {
43
43
  EffectDesc,
44
44
  EffectDescUnion,
45
- } from '../core/renderers/webgl/shaders/DynamicShader.js';
45
+ } from '../core/renderers/webgl/shaders/effects/ShaderEffect.js';
46
46
  import type { TextureMemoryManagerSettings } from '../core/TextureMemoryManager.js';
47
47
 
48
48
  /**
@@ -470,18 +470,61 @@ export class RendererMain extends EventEmitter {
470
470
  return this.stage.shManager.loadShader(shaderType, props);
471
471
  }
472
472
 
473
+ /**
474
+ * Create a new Dynamic Shader controller
475
+ *
476
+ * @remarks
477
+ * A Dynamic Shader is a shader that can be composed of an array of mulitple
478
+ * effects. Each effect can be animated or changed after creation (provided
479
+ * the effect is given a name).
480
+ *
481
+ * Example:
482
+ * ```ts
483
+ * renderer.createNode({
484
+ * shader: renderer.createDynamicShader([
485
+ * renderer.createEffect('radius', {
486
+ * radius: 0
487
+ * }, 'effect1'),
488
+ * renderer.createEffect('border', {
489
+ * color: 0xff00ffff,
490
+ * width: 10,
491
+ * }, 'effect2'),
492
+ * ]),
493
+ * });
494
+ * ```
495
+ *
496
+ * @param effects
497
+ * @returns
498
+ */
473
499
  createDynamicShader<
474
- T extends DynamicEffects<[...{ name: string; type: keyof EffectMap }[]]>,
500
+ T extends DynamicEffects<[...{ name?: string; type: keyof EffectMap }[]]>,
475
501
  >(effects: [...T]): DynamicShaderController<T> {
476
502
  return this.stage.shManager.loadDynamicShader({
477
503
  effects: effects as EffectDescUnion[],
478
504
  });
479
505
  }
480
506
 
481
- createEffect<Name extends string, Type extends keyof EffectMap>(
482
- name: Name,
507
+ /**
508
+ * Create an effect to be used in a Dynamic Shader
509
+ *
510
+ * @remark
511
+ * The {name} parameter is optional but required if you want to animate the effect
512
+ * or change the effect's properties after creation.
513
+ *
514
+ * See {@link createDynamicShader} for an example.
515
+ *
516
+ * @param type
517
+ * @param props
518
+ * @param name
519
+ * @returns
520
+ */
521
+ createEffect<
522
+ Type extends keyof EffectMap,
523
+ Name extends string | undefined = undefined,
524
+ >(
483
525
  type: Type,
484
526
  props: EffectDesc<{ name: Name; type: Type }>['props'],
527
+ name?: Name,
485
528
  ): EffectDesc<{ name: Name; type: Type }> {
486
529
  return {
487
530
  name,