@lightningjs/renderer 0.6.0 → 0.7.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 (204) hide show
  1. package/README.md +1 -1
  2. package/dist/src/common/CommonTypes.d.ts +8 -0
  3. package/dist/src/core/CoreNode.d.ts +63 -15
  4. package/dist/src/core/CoreNode.js +266 -117
  5. package/dist/src/core/CoreNode.js.map +1 -1
  6. package/dist/src/core/CoreTextNode.d.ts +11 -0
  7. package/dist/src/core/CoreTextNode.js +58 -0
  8. package/dist/src/core/CoreTextNode.js.map +1 -1
  9. package/dist/src/core/CoreTextureManager.d.ts +3 -1
  10. package/dist/src/core/CoreTextureManager.js +4 -1
  11. package/dist/src/core/CoreTextureManager.js.map +1 -1
  12. package/dist/src/core/Stage.d.ts +12 -2
  13. package/dist/src/core/Stage.js +36 -24
  14. package/dist/src/core/Stage.js.map +1 -1
  15. package/dist/src/core/animations/CoreAnimation.js +11 -2
  16. package/dist/src/core/animations/CoreAnimation.js.map +1 -1
  17. package/dist/src/core/lib/ContextSpy.d.ts +12 -0
  18. package/dist/src/core/lib/ContextSpy.js +38 -0
  19. package/dist/src/core/lib/ContextSpy.js.map +1 -0
  20. package/dist/src/core/lib/ImageWorker.d.ts +16 -0
  21. package/dist/src/core/lib/ImageWorker.js +111 -0
  22. package/dist/src/core/lib/ImageWorker.js.map +1 -0
  23. package/dist/src/core/lib/WebGlContext.d.ts +414 -0
  24. package/dist/src/core/lib/WebGlContext.js +640 -0
  25. package/dist/src/core/lib/WebGlContext.js.map +1 -0
  26. package/dist/src/core/lib/WebGlContextWrapper.d.ts +500 -0
  27. package/dist/src/core/lib/WebGlContextWrapper.js +784 -0
  28. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -0
  29. package/dist/src/core/platform.js +4 -0
  30. package/dist/src/core/platform.js.map +1 -1
  31. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.d.ts +2 -1
  32. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js +2 -2
  33. package/dist/src/core/renderers/webgl/WebGlCoreCtxSubTexture.js.map +1 -1
  34. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.d.ts +3 -2
  35. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +23 -21
  36. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  37. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.d.ts +3 -2
  38. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js +9 -13
  39. package/dist/src/core/renderers/webgl/WebGlCoreRenderOp.js.map +1 -1
  40. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.d.ts +4 -1
  41. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js +33 -31
  42. package/dist/src/core/renderers/webgl/WebGlCoreRenderer.js.map +1 -1
  43. package/dist/src/core/renderers/webgl/WebGlCoreShader.d.ts +2 -1
  44. package/dist/src/core/renderers/webgl/WebGlCoreShader.js +24 -24
  45. package/dist/src/core/renderers/webgl/WebGlCoreShader.js.map +1 -1
  46. package/dist/src/core/renderers/webgl/internal/RendererUtils.d.ts +8 -5
  47. package/dist/src/core/renderers/webgl/internal/RendererUtils.js +11 -13
  48. package/dist/src/core/renderers/webgl/internal/RendererUtils.js.map +1 -1
  49. package/dist/src/core/renderers/webgl/internal/ShaderUtils.d.ts +3 -2
  50. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js +15 -15
  51. package/dist/src/core/renderers/webgl/internal/ShaderUtils.js.map +1 -1
  52. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js +3 -6
  53. package/dist/src/core/renderers/webgl/shaders/DefaultShader.js.map +1 -1
  54. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js +3 -3
  55. package/dist/src/core/renderers/webgl/shaders/DefaultShaderBatched.js.map +1 -1
  56. package/dist/src/core/renderers/webgl/shaders/DynamicShader.d.ts +1 -0
  57. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +32 -12
  58. package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
  59. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js +3 -3
  60. package/dist/src/core/renderers/webgl/shaders/RoundedRectangle.js.map +1 -1
  61. package/dist/src/core/renderers/webgl/shaders/SdfShader.js +3 -3
  62. package/dist/src/core/renderers/webgl/shaders/SdfShader.js.map +1 -1
  63. package/dist/src/core/renderers/webgl/shaders/effects/BorderEffect.js +1 -1
  64. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.d.ts +14 -1
  65. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js +15 -5
  66. package/dist/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.js.map +1 -1
  67. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js +7 -8
  68. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.js.map +1 -1
  69. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.d.ts +2 -1
  70. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js +4 -2
  71. package/dist/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.js.map +1 -1
  72. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js +40 -13
  73. package/dist/src/core/text-rendering/renderers/CanvasTextRenderer.js.map +1 -1
  74. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.d.ts +1 -1
  75. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js +6 -6
  76. package/dist/src/core/text-rendering/renderers/LightningTextTextureRenderer.js.map +1 -1
  77. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.d.ts +3 -2
  78. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js +82 -50
  79. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.js.map +1 -1
  80. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.d.ts +8 -0
  81. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js +29 -0
  82. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/findNearestMultiple.js.map +1 -0
  83. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.d.ts +4 -3
  84. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js +15 -11
  85. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.js.map +1 -1
  86. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.d.ts +3 -2
  87. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js +30 -26
  88. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js.map +1 -1
  89. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.d.ts +19 -0
  90. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js +84 -0
  91. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/SdfBufferHelper.js.map +1 -0
  92. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.d.ts +8 -0
  93. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js +40 -0
  94. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutLine.js.map +1 -0
  95. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.d.ts +2 -0
  96. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js +41 -0
  97. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/layoutText2.js.map +1 -0
  98. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.d.ts +1 -0
  99. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js +4 -0
  100. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2/utils.js.map +1 -0
  101. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.d.ts +1 -0
  102. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js +2 -0
  103. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText2.js.map +1 -0
  104. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.d.ts +9 -0
  105. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js +32 -0
  106. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/roundUpToMultiple.js.map +1 -0
  107. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.d.ts +26 -0
  108. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.js +70 -0
  109. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.js.map +1 -0
  110. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.d.ts +16 -0
  111. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.js +39 -0
  112. package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.js.map +1 -0
  113. package/dist/src/core/text-rendering/renderers/TextRenderer.d.ts +50 -0
  114. package/dist/src/core/text-rendering/renderers/TextRenderer.js +19 -0
  115. package/dist/src/core/text-rendering/renderers/TextRenderer.js.map +1 -1
  116. package/dist/src/core/textures/ImageTexture.js +14 -9
  117. package/dist/src/core/textures/ImageTexture.js.map +1 -1
  118. package/dist/src/core/utils.d.ts +1 -6
  119. package/dist/src/core/utils.js +3 -2
  120. package/dist/src/core/utils.js.map +1 -1
  121. package/dist/src/main-api/ICoreDriver.d.ts +2 -1
  122. package/dist/src/main-api/RendererMain.d.ts +25 -0
  123. package/dist/src/main-api/RendererMain.js +14 -5
  124. package/dist/src/main-api/RendererMain.js.map +1 -1
  125. package/dist/src/render-drivers/main/MainCoreDriver.d.ts +2 -1
  126. package/dist/src/render-drivers/main/MainCoreDriver.js +6 -4
  127. package/dist/src/render-drivers/main/MainCoreDriver.js.map +1 -1
  128. package/dist/src/render-drivers/main/MainOnlyTextNode.d.ts +10 -0
  129. package/dist/src/render-drivers/main/MainOnlyTextNode.js +45 -0
  130. package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +1 -1
  131. package/dist/src/render-drivers/threadx/TextNodeStruct.d.ts +10 -0
  132. package/dist/src/render-drivers/threadx/TextNodeStruct.js +45 -0
  133. package/dist/src/render-drivers/threadx/TextNodeStruct.js.map +1 -1
  134. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.d.ts +2 -1
  135. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +8 -1
  136. package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -1
  137. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.d.ts +5 -0
  138. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js +5 -0
  139. package/dist/src/render-drivers/threadx/ThreadXMainTextNode.js.map +1 -1
  140. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.d.ts +4 -1
  141. package/dist/src/render-drivers/threadx/ThreadXRendererMessage.js.map +1 -1
  142. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.d.ts +5 -0
  143. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +10 -0
  144. package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +1 -1
  145. package/dist/src/render-drivers/threadx/worker/renderer.js +5 -3
  146. package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
  147. package/dist/src/utils.d.ts +2 -1
  148. package/dist/src/utils.js +22 -3
  149. package/dist/src/utils.js.map +1 -1
  150. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  151. package/package.json +3 -2
  152. package/src/common/CommonTypes.ts +9 -0
  153. package/src/core/CoreNode.ts +325 -148
  154. package/src/core/CoreTextNode.ts +72 -0
  155. package/src/core/CoreTextureManager.ts +4 -2
  156. package/src/core/Stage.ts +60 -34
  157. package/src/core/animations/CoreAnimation.ts +11 -2
  158. package/src/core/lib/ContextSpy.ts +41 -0
  159. package/src/core/lib/ImageWorker.ts +124 -0
  160. package/src/core/lib/WebGlContextWrapper.ts +965 -0
  161. package/src/core/platform.ts +5 -0
  162. package/src/core/renderers/webgl/WebGlCoreCtxSubTexture.ts +3 -2
  163. package/src/core/renderers/webgl/WebGlCoreCtxTexture.ts +29 -28
  164. package/src/core/renderers/webgl/WebGlCoreRenderOp.ts +10 -14
  165. package/src/core/renderers/webgl/WebGlCoreRenderer.ts +34 -63
  166. package/src/core/renderers/webgl/WebGlCoreShader.ts +34 -25
  167. package/src/core/renderers/webgl/internal/RendererUtils.ts +13 -16
  168. package/src/core/renderers/webgl/internal/ShaderUtils.ts +16 -15
  169. package/src/core/renderers/webgl/shaders/DefaultShader.ts +3 -7
  170. package/src/core/renderers/webgl/shaders/DefaultShaderBatched.ts +3 -3
  171. package/src/core/renderers/webgl/shaders/DynamicShader.ts +42 -14
  172. package/src/core/renderers/webgl/shaders/RoundedRectangle.ts +3 -3
  173. package/src/core/renderers/webgl/shaders/SdfShader.ts +3 -3
  174. package/src/core/renderers/webgl/shaders/effects/BorderEffect.ts +1 -1
  175. package/src/core/renderers/webgl/shaders/effects/GrayscaleEffect.ts +35 -5
  176. package/src/core/text-rendering/font-face-types/SdfTrFontFace/SdfTrFontFace.ts +7 -8
  177. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.test.ts +9 -3
  178. package/src/core/text-rendering/font-face-types/SdfTrFontFace/internal/SdfFontShaper.ts +4 -2
  179. package/src/core/text-rendering/renderers/CanvasTextRenderer.ts +44 -15
  180. package/src/core/text-rendering/renderers/LightningTextTextureRenderer.ts +7 -7
  181. package/src/core/text-rendering/renderers/SdfTextRenderer/SdfTextRenderer.ts +115 -63
  182. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/getStartConditions.ts +26 -18
  183. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.ts +40 -28
  184. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/measureText.test.ts +6 -1
  185. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/setRenderWindow.test.ts +205 -0
  186. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/{makeRenderWindow.ts → setRenderWindow.ts} +50 -21
  187. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/util.ts +40 -0
  188. package/src/core/text-rendering/renderers/TextRenderer.ts +73 -0
  189. package/src/core/textures/ImageTexture.ts +17 -9
  190. package/src/core/utils.ts +87 -85
  191. package/src/env.d.ts +7 -0
  192. package/src/main-api/ICoreDriver.ts +2 -1
  193. package/src/main-api/RendererMain.ts +43 -5
  194. package/src/render-drivers/main/MainCoreDriver.ts +8 -5
  195. package/src/render-drivers/main/MainOnlyTextNode.ts +55 -1
  196. package/src/render-drivers/threadx/TextNodeStruct.ts +45 -0
  197. package/src/render-drivers/threadx/ThreadXCoreDriver.ts +10 -2
  198. package/src/render-drivers/threadx/ThreadXMainTextNode.ts +10 -0
  199. package/src/render-drivers/threadx/ThreadXRendererMessage.ts +5 -1
  200. package/src/render-drivers/threadx/worker/ThreadXRendererTextNode.ts +15 -0
  201. package/src/render-drivers/threadx/worker/renderer.ts +6 -4
  202. package/src/utils.ts +25 -4
  203. package/src/core/scene/Scene.ts +0 -120
  204. package/src/core/text-rendering/renderers/SdfTextRenderer/internal/makeRenderWindow.test.ts +0 -136
@@ -16,21 +16,77 @@
16
16
  * See the License for the specific language governing permissions and
17
17
  * limitations under the License.
18
18
  */
19
- import { assertTruthy } from '../utils.js';
19
+ import { assertTruthy, mergeColorAlphaPremultiplied } from '../utils.js';
20
20
  import { EventEmitter } from '../common/EventEmitter.js';
21
21
  import { intersectRect } from './lib/utils.js';
22
22
  import { Matrix3d } from './lib/Matrix3d.js';
23
+ var UpdateType;
24
+ (function (UpdateType) {
25
+ /**
26
+ * Child updates
27
+ */
28
+ UpdateType[UpdateType["Children"] = 1] = "Children";
29
+ /**
30
+ * Scale/Rotate transform update
31
+ */
32
+ UpdateType[UpdateType["ScaleRotate"] = 2] = "ScaleRotate";
33
+ /**
34
+ * Translate transform update (x/y/width/height/pivot/mount)
35
+ */
36
+ UpdateType[UpdateType["Local"] = 4] = "Local";
37
+ /**
38
+ * Global transform update
39
+ */
40
+ UpdateType[UpdateType["Global"] = 8] = "Global";
41
+ /**
42
+ * Clipping rect update
43
+ */
44
+ UpdateType[UpdateType["Clipping"] = 16] = "Clipping";
45
+ /**
46
+ * Calculated ZIndex update
47
+ */
48
+ UpdateType[UpdateType["CalculatedZIndex"] = 32] = "CalculatedZIndex";
49
+ /**
50
+ * Z-Index Sorted Children update
51
+ */
52
+ UpdateType[UpdateType["ZIndexSortedChildren"] = 64] = "ZIndexSortedChildren";
53
+ /**
54
+ * Premultiplied Colors
55
+ */
56
+ UpdateType[UpdateType["PremultipliedColors"] = 128] = "PremultipliedColors";
57
+ /**
58
+ * World Alpha
59
+ *
60
+ * @remarks
61
+ * World Alpha = Parent World Alpha * Alpha
62
+ */
63
+ UpdateType[UpdateType["WorldAlpha"] = 256] = "WorldAlpha";
64
+ /**
65
+ * None
66
+ */
67
+ UpdateType[UpdateType["None"] = 0] = "None";
68
+ /**
69
+ * All
70
+ */
71
+ UpdateType[UpdateType["All"] = 511] = "All";
72
+ })(UpdateType || (UpdateType = {}));
23
73
  export class CoreNode extends EventEmitter {
24
74
  stage;
25
75
  children = [];
26
76
  props;
27
- recalculationType = 0;
28
- hasUpdates = true;
77
+ updateType = UpdateType.All;
29
78
  globalTransform;
30
79
  scaleRotateTransform;
31
80
  localTransform;
32
81
  clippingRect = null;
82
+ isRenderable = false;
33
83
  parentClippingRect = null;
84
+ worldAlpha = 1;
85
+ premultipliedColorTl = 0;
86
+ premultipliedColorTr = 0;
87
+ premultipliedColorBl = 0;
88
+ premultipliedColorBr = 0;
89
+ calcZIndex = 0;
34
90
  isComplex = false;
35
91
  constructor(stage, props) {
36
92
  super();
@@ -53,6 +109,7 @@ export class CoreNode extends EventEmitter {
53
109
  const texture = txManager.loadTexture(textureType, props, options);
54
110
  this.props.texture = texture;
55
111
  this.props.textureOptions = options;
112
+ this.checkIsRenderable();
56
113
  // If texture is already loaded / failed, trigger loaded event manually
57
114
  // so that users get a consistent event experience.
58
115
  // We do this in a microtask to allow listeners to be attached in the same
@@ -75,8 +132,12 @@ export class CoreNode extends EventEmitter {
75
132
  }
76
133
  this.props.texture = null;
77
134
  this.props.textureOptions = null;
135
+ this.checkIsRenderable();
78
136
  }
79
137
  onTextureLoaded = (target, dimensions) => {
138
+ // Texture was loaded. In case the RAF loop has already stopped, we request
139
+ // a render to ensure the texture is rendered.
140
+ this.stage.requestRender();
80
141
  this.emit('loaded', {
81
142
  type: 'texture',
82
143
  dimensions,
@@ -95,51 +156,33 @@ export class CoreNode extends EventEmitter {
95
156
  const { shader, props: p } = shManager.loadShader(shaderType, props);
96
157
  this.props.shader = shader;
97
158
  this.props.shaderProps = p;
98
- }
99
- setHasUpdates() {
100
- this.hasUpdates = true;
101
- }
102
- setChildrenHasUpdates() {
103
- this.children.forEach((child) => {
104
- child.setRecalculationType(2);
105
- });
106
- }
107
- setParentHasUpdates() {
108
- if (!this.props.parent) {
109
- return;
110
- }
111
- this.props.parent.setRecalculationType(1);
159
+ this.checkIsRenderable();
112
160
  }
113
161
  /**
114
162
  * Change types types is used to determine the scope of the changes being applied
115
- * 1 - alpha recalculation
116
- * 2 - translate recalculation
117
- * 4 - transform recalculation
118
- * 8 - z-index recalculation
163
+ *
164
+ * @remarks
165
+ * See {@link UpdateType} for more information on each type
119
166
  *
120
167
  * @param type
121
168
  */
122
- setRecalculationType(type) {
123
- this.recalculationType |= type;
124
- this.setHasUpdates();
125
- // always forcing parent updates so the root will have an hasUpdates flag
126
- this.setParentHasUpdates();
127
- if (type & 4) {
128
- this.setChildrenHasUpdates();
169
+ setUpdateType(type) {
170
+ this.updateType |= type;
171
+ // If we're updating this node at all, we need to inform the parent
172
+ // (and all ancestors) that their children need updating as well
173
+ const parent = this.props.parent;
174
+ if (parent && !(parent.updateType & UpdateType.Children)) {
175
+ parent.setUpdateType(UpdateType.Children);
129
176
  }
130
177
  }
131
178
  sortChildren() {
132
- this.children.sort((a, b) => a.zIndex - b.zIndex);
179
+ this.children.sort((a, b) => a.calcZIndex - b.calcZIndex);
133
180
  }
134
181
  updateScaleRotateTransform() {
135
- this.setRecalculationType(4);
136
182
  this.scaleRotateTransform = Matrix3d.rotate(this.props.rotation, this.scaleRotateTransform).scale(this.props.scaleX, this.props.scaleY);
137
- // do transformations when matrix is implemented
138
- this.updateLocalTransform();
139
183
  }
140
184
  updateLocalTransform() {
141
185
  assertTruthy(this.scaleRotateTransform);
142
- this.setRecalculationType(2);
143
186
  const pivotTranslateX = this.props.pivotX * this.props.width;
144
187
  const pivotTranslateY = this.props.pivotY * this.props.height;
145
188
  const mountTranslateX = this.props.mountX * this.props.width;
@@ -147,40 +190,143 @@ export class CoreNode extends EventEmitter {
147
190
  this.localTransform = Matrix3d.translate(pivotTranslateX - mountTranslateX + this.props.x, pivotTranslateY - mountTranslateY + this.props.y, this.localTransform)
148
191
  .multiply(this.scaleRotateTransform)
149
192
  .translate(-pivotTranslateX, -pivotTranslateY);
193
+ this.setUpdateType(UpdateType.Global);
150
194
  }
151
195
  /**
152
196
  * @todo: test for correct calculation flag
153
197
  * @param delta
154
198
  */
155
199
  update(delta, parentClippingRect = null) {
156
- assertTruthy(this.localTransform);
157
- const parentGlobalTransform = this.parent?.globalTransform;
158
- if (parentGlobalTransform) {
159
- this.globalTransform = Matrix3d.copy(parentGlobalTransform, this.globalTransform).multiply(this.localTransform);
200
+ if (this.updateType & UpdateType.ScaleRotate) {
201
+ this.updateScaleRotateTransform();
202
+ this.setUpdateType(UpdateType.Local);
203
+ }
204
+ if (this.updateType & UpdateType.Local) {
205
+ this.updateLocalTransform();
206
+ this.setUpdateType(UpdateType.Global);
207
+ }
208
+ const parent = this.props.parent;
209
+ let childUpdateType = UpdateType.None;
210
+ if (this.updateType & UpdateType.Global) {
211
+ assertTruthy(this.localTransform);
212
+ this.globalTransform = Matrix3d.copy(parent?.globalTransform || this.localTransform, this.globalTransform);
213
+ if (parent) {
214
+ this.globalTransform.multiply(this.localTransform);
215
+ }
216
+ this.setUpdateType(UpdateType.Clipping | UpdateType.Children);
217
+ childUpdateType |= UpdateType.Global;
160
218
  }
161
- else {
162
- this.globalTransform = Matrix3d.copy(this.localTransform, this.globalTransform);
219
+ if (this.updateType & UpdateType.Clipping) {
220
+ this.calculateClippingRect(parentClippingRect);
221
+ this.checkIsRenderable();
222
+ this.setUpdateType(UpdateType.Children);
223
+ childUpdateType |= UpdateType.Clipping;
163
224
  }
164
- this.calculateClippingRect(parentClippingRect);
165
- if (this.children.length) {
225
+ if (this.updateType & UpdateType.WorldAlpha) {
226
+ if (parent) {
227
+ this.worldAlpha = parent.worldAlpha * this.props.alpha;
228
+ }
229
+ else {
230
+ this.worldAlpha = this.props.alpha;
231
+ }
232
+ this.setUpdateType(UpdateType.Children | UpdateType.PremultipliedColors);
233
+ childUpdateType |= UpdateType.WorldAlpha;
234
+ }
235
+ if (this.updateType & UpdateType.PremultipliedColors) {
236
+ this.premultipliedColorTl = mergeColorAlphaPremultiplied(this.props.colorTl, this.worldAlpha, true);
237
+ // If all the colors are the same just sent them all to the same value
238
+ if (this.props.colorTl === this.props.colorTr &&
239
+ this.props.colorBl === this.props.colorBr &&
240
+ this.props.colorTl === this.props.colorBl) {
241
+ this.premultipliedColorTr =
242
+ this.premultipliedColorBl =
243
+ this.premultipliedColorBr =
244
+ this.premultipliedColorTl;
245
+ }
246
+ else {
247
+ this.premultipliedColorTr = mergeColorAlphaPremultiplied(this.props.colorTr, this.worldAlpha, true);
248
+ this.premultipliedColorBl = mergeColorAlphaPremultiplied(this.props.colorBl, this.worldAlpha, true);
249
+ this.premultipliedColorBr = mergeColorAlphaPremultiplied(this.props.colorBr, this.worldAlpha, true);
250
+ }
251
+ this.checkIsRenderable();
252
+ this.setUpdateType(UpdateType.Children);
253
+ childUpdateType |= UpdateType.PremultipliedColors;
254
+ }
255
+ // No need to update zIndex if there is no parent
256
+ if (parent && this.updateType & UpdateType.CalculatedZIndex) {
257
+ this.calculateZIndex();
258
+ // Tell parent to re-sort children
259
+ parent.setUpdateType(UpdateType.ZIndexSortedChildren);
260
+ }
261
+ if (this.updateType & UpdateType.Children && this.children.length) {
166
262
  this.children.forEach((child) => {
263
+ // Trigger the depenedent update types on the child
264
+ child.setUpdateType(childUpdateType);
265
+ // If child has no updates, skip
266
+ if (child.updateType === 0) {
267
+ return;
268
+ }
167
269
  child.update(delta, this.clippingRect);
168
270
  });
169
271
  }
170
- if (this.recalculationType & 8) {
272
+ // Sorting children MUST happen after children have been updated so
273
+ // that they have the oppotunity to update their calculated zIndex.
274
+ if (this.updateType & UpdateType.ZIndexSortedChildren) {
171
275
  // reorder z-index
172
276
  this.sortChildren();
173
277
  }
174
- // reset update flag
175
- this.hasUpdates = false;
176
- // reset recalculation type
177
- this.recalculationType = 0;
278
+ // reset update type
279
+ this.updateType = 0;
280
+ }
281
+ // This function checks if the current node is renderable based on certain properties.
282
+ // It returns true if any of the specified properties are truthy or if any color property is not 0, otherwise it returns false.
283
+ checkIsRenderable() {
284
+ if (this.props.texture) {
285
+ return (this.isRenderable = true);
286
+ }
287
+ if (!this.props.width || !this.props.height) {
288
+ return (this.isRenderable = false);
289
+ }
290
+ if (this.props.shader) {
291
+ return (this.isRenderable = true);
292
+ }
293
+ if (this.props.clipping) {
294
+ return (this.isRenderable = true);
295
+ }
296
+ if (this.props.color !== 0) {
297
+ return (this.isRenderable = true);
298
+ }
299
+ // Consider removing these checks and just using the color property check above.
300
+ // Maybe add a forceRender prop for nodes that should always render.
301
+ if (this.props.colorTop !== 0) {
302
+ return (this.isRenderable = true);
303
+ }
304
+ if (this.props.colorBottom !== 0) {
305
+ return (this.isRenderable = true);
306
+ }
307
+ if (this.props.colorLeft !== 0) {
308
+ return (this.isRenderable = true);
309
+ }
310
+ if (this.props.colorRight !== 0) {
311
+ return (this.isRenderable = true);
312
+ }
313
+ if (this.props.colorTl !== 0) {
314
+ return (this.isRenderable = true);
315
+ }
316
+ if (this.props.colorTr !== 0) {
317
+ return (this.isRenderable = true);
318
+ }
319
+ if (this.props.colorBl !== 0) {
320
+ return (this.isRenderable = true);
321
+ }
322
+ if (this.props.colorBr !== 0) {
323
+ return (this.isRenderable = true);
324
+ }
325
+ return (this.isRenderable = false);
178
326
  }
179
327
  /**
180
328
  * This function calculates the clipping rectangle for a node.
181
329
  *
182
- * If the node's globalTransform is not set, the function returns immediately.
183
- * If the node's props do not require clipping and there is no parent clipping rectangle, the node's clipping rectangle is set to null.
184
330
  * If the parent clipping rectangle has not changed and the node's clipping rectangle is already set, the function returns immediately.
185
331
  *
186
332
  * The function then checks if the node is rotated. If the node requires clipping and is not rotated, a new clipping rectangle is created based on the node's global transform and dimensions.
@@ -189,13 +335,7 @@ export class CoreNode extends EventEmitter {
189
335
  * Finally, the node's parentClippingRect and clippingRect properties are updated.
190
336
  */
191
337
  calculateClippingRect(parentClippingRect = null) {
192
- if (!this.globalTransform) {
193
- return;
194
- }
195
- if (!this.props.clipping && !parentClippingRect) {
196
- this.clippingRect = null;
197
- return;
198
- }
338
+ assertTruthy(this.globalTransform);
199
339
  if (this.parentClippingRect === parentClippingRect && this.clippingRect) {
200
340
  return;
201
341
  }
@@ -218,18 +358,29 @@ export class CoreNode extends EventEmitter {
218
358
  this.parentClippingRect = parentClippingRect;
219
359
  this.clippingRect = clippingRect;
220
360
  }
361
+ calculateZIndex() {
362
+ const props = this.props;
363
+ const z = props.zIndex || 0;
364
+ const p = props.parent?.zIndex || 0;
365
+ let zIndex = z;
366
+ if (props.parent?.zIndexLocked) {
367
+ zIndex = z < p ? z : p;
368
+ }
369
+ this.calcZIndex = zIndex;
370
+ }
221
371
  renderQuads(renderer) {
222
- const { width, height, colorTl, colorTr, colorBl, colorBr, texture, textureOptions, shader, shaderProps, } = this.props;
372
+ const { width, height, texture, textureOptions, shader, shaderProps } = this.props;
373
+ const { premultipliedColorTl, premultipliedColorTr, premultipliedColorBl, premultipliedColorBr, } = this;
223
374
  const { zIndex, worldAlpha, globalTransform: gt, clippingRect } = this;
224
375
  assertTruthy(gt);
225
376
  // add to list of renderables to be sorted before rendering
226
377
  renderer.addQuad({
227
378
  width,
228
379
  height,
229
- colorTl,
230
- colorTr,
231
- colorBl,
232
- colorBr,
380
+ colorTl: premultipliedColorTl,
381
+ colorTr: premultipliedColorTr,
382
+ colorBl: premultipliedColorBl,
383
+ colorBr: premultipliedColorBr,
233
384
  texture,
234
385
  textureOptions,
235
386
  zIndex,
@@ -257,7 +408,7 @@ export class CoreNode extends EventEmitter {
257
408
  set x(value) {
258
409
  if (this.props.x !== value) {
259
410
  this.props.x = value;
260
- this.updateLocalTransform();
411
+ this.setUpdateType(UpdateType.Local);
261
412
  }
262
413
  }
263
414
  get absX() {
@@ -273,7 +424,7 @@ export class CoreNode extends EventEmitter {
273
424
  set y(value) {
274
425
  if (this.props.y !== value) {
275
426
  this.props.y = value;
276
- this.updateLocalTransform();
427
+ this.setUpdateType(UpdateType.Local);
277
428
  }
278
429
  }
279
430
  get width() {
@@ -282,7 +433,7 @@ export class CoreNode extends EventEmitter {
282
433
  set width(value) {
283
434
  if (this.props.width !== value) {
284
435
  this.props.width = value;
285
- this.updateLocalTransform();
436
+ this.setUpdateType(UpdateType.Local);
286
437
  }
287
438
  }
288
439
  get height() {
@@ -291,7 +442,7 @@ export class CoreNode extends EventEmitter {
291
442
  set height(value) {
292
443
  if (this.props.height !== value) {
293
444
  this.props.height = value;
294
- this.updateLocalTransform();
445
+ this.setUpdateType(UpdateType.Local);
295
446
  }
296
447
  }
297
448
  get scale() {
@@ -311,7 +462,7 @@ export class CoreNode extends EventEmitter {
311
462
  set scaleX(value) {
312
463
  if (this.props.scaleX !== value) {
313
464
  this.props.scaleX = value;
314
- this.updateScaleRotateTransform();
465
+ this.setUpdateType(UpdateType.ScaleRotate);
315
466
  }
316
467
  }
317
468
  get scaleY() {
@@ -320,41 +471,37 @@ export class CoreNode extends EventEmitter {
320
471
  set scaleY(value) {
321
472
  if (this.props.scaleY !== value) {
322
473
  this.props.scaleY = value;
323
- this.updateScaleRotateTransform();
474
+ this.setUpdateType(UpdateType.ScaleRotate);
324
475
  }
325
476
  }
326
- get worldScaleX() {
327
- return (this.props.scaleX * (this.props.parent?.worldScaleX ?? 1) ||
328
- this.props.scaleX);
329
- }
330
- get worldScaleY() {
331
- return (this.props.scaleY * (this.props.parent?.worldScaleY ?? 1) ||
332
- this.props.scaleY);
333
- }
334
477
  get mount() {
335
478
  return this.props.mount;
336
479
  }
337
480
  set mount(value) {
338
- // if (this.props.mountX !== value || this.props.mountY !== value) {
339
- this.props.mountX = value;
340
- this.props.mountY = value;
341
- this.props.mount = value;
342
- this.updateLocalTransform();
343
- // }
481
+ if (this.props.mountX !== value || this.props.mountY !== value) {
482
+ this.props.mountX = value;
483
+ this.props.mountY = value;
484
+ this.props.mount = value;
485
+ this.setUpdateType(UpdateType.Local);
486
+ }
344
487
  }
345
488
  get mountX() {
346
489
  return this.props.mountX;
347
490
  }
348
491
  set mountX(value) {
349
- this.props.mountX = value;
350
- this.updateLocalTransform();
492
+ if (this.props.mountX !== value) {
493
+ this.props.mountX = value;
494
+ this.setUpdateType(UpdateType.Local);
495
+ }
351
496
  }
352
497
  get mountY() {
353
498
  return this.props.mountY;
354
499
  }
355
500
  set mountY(value) {
356
- this.props.mountY = value;
357
- this.updateLocalTransform();
501
+ if (this.props.mountY !== value) {
502
+ this.props.mountY = value;
503
+ this.setUpdateType(UpdateType.Local);
504
+ }
358
505
  }
359
506
  get pivot() {
360
507
  return this.props.pivot;
@@ -363,22 +510,27 @@ export class CoreNode extends EventEmitter {
363
510
  if (this.props.pivotX !== value || this.props.pivotY !== value) {
364
511
  this.props.pivotX = value;
365
512
  this.props.pivotY = value;
366
- this.updateLocalTransform();
513
+ this.props.pivot = value;
514
+ this.setUpdateType(UpdateType.Local);
367
515
  }
368
516
  }
369
517
  get pivotX() {
370
518
  return this.props.pivotX;
371
519
  }
372
520
  set pivotX(value) {
373
- this.props.pivotX = value;
374
- this.updateLocalTransform();
521
+ if (this.props.pivotX !== value) {
522
+ this.props.pivotX = value;
523
+ this.setUpdateType(UpdateType.Local);
524
+ }
375
525
  }
376
526
  get pivotY() {
377
527
  return this.props.pivotY;
378
528
  }
379
529
  set pivotY(value) {
380
- this.props.pivotY = value;
381
- this.updateLocalTransform();
530
+ if (this.props.pivotY !== value) {
531
+ this.props.pivotY = value;
532
+ this.setUpdateType(UpdateType.Local);
533
+ }
382
534
  }
383
535
  get rotation() {
384
536
  return this.props.rotation;
@@ -386,7 +538,7 @@ export class CoreNode extends EventEmitter {
386
538
  set rotation(value) {
387
539
  if (this.props.rotation !== value) {
388
540
  this.props.rotation = value;
389
- this.updateScaleRotateTransform();
541
+ this.setUpdateType(UpdateType.ScaleRotate);
390
542
  }
391
543
  }
392
544
  get alpha() {
@@ -394,20 +546,14 @@ export class CoreNode extends EventEmitter {
394
546
  }
395
547
  set alpha(value) {
396
548
  this.props.alpha = value;
397
- this.setRecalculationType(1);
398
- }
399
- get worldAlpha() {
400
- const props = this.props;
401
- const parent = props.parent;
402
- return props.alpha * (parent?.worldAlpha || 1);
549
+ this.setUpdateType(UpdateType.PremultipliedColors | UpdateType.WorldAlpha);
403
550
  }
404
551
  get clipping() {
405
552
  return this.props.clipping;
406
553
  }
407
554
  set clipping(value) {
408
555
  this.props.clipping = value;
409
- this.clippingRect = null;
410
- this.setRecalculationType(4);
556
+ this.setUpdateType(UpdateType.Clipping);
411
557
  }
412
558
  get color() {
413
559
  return this.props.color;
@@ -423,7 +569,7 @@ export class CoreNode extends EventEmitter {
423
569
  this.colorBr = value;
424
570
  }
425
571
  this.props.color = value;
426
- this.setRecalculationType(2);
572
+ this.setUpdateType(UpdateType.PremultipliedColors);
427
573
  }
428
574
  get colorTop() {
429
575
  return this.props.colorTop;
@@ -434,7 +580,7 @@ export class CoreNode extends EventEmitter {
434
580
  this.colorTr = value;
435
581
  }
436
582
  this.props.colorTop = value;
437
- this.setRecalculationType(2);
583
+ this.setUpdateType(UpdateType.PremultipliedColors);
438
584
  }
439
585
  get colorBottom() {
440
586
  return this.props.colorBottom;
@@ -445,7 +591,7 @@ export class CoreNode extends EventEmitter {
445
591
  this.colorBr = value;
446
592
  }
447
593
  this.props.colorBottom = value;
448
- this.setRecalculationType(2);
594
+ this.setUpdateType(UpdateType.PremultipliedColors);
449
595
  }
450
596
  get colorLeft() {
451
597
  return this.props.colorLeft;
@@ -456,7 +602,7 @@ export class CoreNode extends EventEmitter {
456
602
  this.colorBl = value;
457
603
  }
458
604
  this.props.colorLeft = value;
459
- this.setRecalculationType(2);
605
+ this.setUpdateType(UpdateType.PremultipliedColors);
460
606
  }
461
607
  get colorRight() {
462
608
  return this.props.colorRight;
@@ -467,35 +613,35 @@ export class CoreNode extends EventEmitter {
467
613
  this.colorBr = value;
468
614
  }
469
615
  this.props.colorRight = value;
470
- this.setRecalculationType(2);
616
+ this.setUpdateType(UpdateType.PremultipliedColors);
471
617
  }
472
618
  get colorTl() {
473
619
  return this.props.colorTl;
474
620
  }
475
621
  set colorTl(value) {
476
622
  this.props.colorTl = value;
477
- this.setRecalculationType(2);
623
+ this.setUpdateType(UpdateType.PremultipliedColors);
478
624
  }
479
625
  get colorTr() {
480
626
  return this.props.colorTr;
481
627
  }
482
628
  set colorTr(value) {
483
629
  this.props.colorTr = value;
484
- this.setRecalculationType(2);
630
+ this.setUpdateType(UpdateType.PremultipliedColors);
485
631
  }
486
632
  get colorBl() {
487
633
  return this.props.colorBl;
488
634
  }
489
635
  set colorBl(value) {
490
636
  this.props.colorBl = value;
491
- this.setRecalculationType(2);
637
+ this.setUpdateType(UpdateType.PremultipliedColors);
492
638
  }
493
639
  get colorBr() {
494
640
  return this.props.colorBr;
495
641
  }
496
642
  set colorBr(value) {
497
643
  this.props.colorBr = value;
498
- this.setRecalculationType(2);
644
+ this.setUpdateType(UpdateType.PremultipliedColors);
499
645
  }
500
646
  // we're only interested in parent zIndex to test
501
647
  // if we should use node zIndex is higher then parent zIndex
@@ -504,19 +650,20 @@ export class CoreNode extends EventEmitter {
504
650
  }
505
651
  set zIndexLocked(value) {
506
652
  this.props.zIndexLocked = value;
653
+ this.setUpdateType(UpdateType.CalculatedZIndex | UpdateType.Children);
654
+ this.children.forEach((child) => {
655
+ child.setUpdateType(UpdateType.CalculatedZIndex);
656
+ });
507
657
  }
508
658
  get zIndex() {
509
- const props = this.props;
510
- const z = props.zIndex || 0;
511
- const p = props.parent?.zIndex || 0;
512
- if (props.parent?.zIndexLocked) {
513
- return z < p ? z : p;
514
- }
515
- return z;
659
+ return this.props.zIndex;
516
660
  }
517
661
  set zIndex(value) {
518
662
  this.props.zIndex = value;
519
- this.props.parent?.setRecalculationType(8);
663
+ this.setUpdateType(UpdateType.CalculatedZIndex | UpdateType.Children);
664
+ this.children.forEach((child) => {
665
+ child.setUpdateType(UpdateType.CalculatedZIndex);
666
+ });
520
667
  }
521
668
  get parent() {
522
669
  return this.props.parent;
@@ -534,8 +681,10 @@ export class CoreNode extends EventEmitter {
534
681
  }
535
682
  if (newParent) {
536
683
  newParent.children.push(this);
537
- // force parent to recalculate z-index for its children
538
- newParent.setRecalculationType(8);
684
+ // Since this node has a new parent, to be safe, have it do a full update.
685
+ this.setUpdateType(UpdateType.All);
686
+ // Tell parent that it's children need to be updated and sorted.
687
+ newParent.setUpdateType(UpdateType.Children | UpdateType.ZIndexSortedChildren);
539
688
  }
540
689
  this.updateScaleRotateTransform();
541
690
  }