@lightningjs/renderer 3.0.0-beta20 → 3.0.0-beta21

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 (152) hide show
  1. package/dist/src/core/CoreNode.d.ts +53 -7
  2. package/dist/src/core/CoreNode.js +175 -65
  3. package/dist/src/core/CoreNode.js.map +1 -1
  4. package/dist/src/core/CoreTextNode.d.ts +1 -1
  5. package/dist/src/core/CoreTextNode.js +3 -5
  6. package/dist/src/core/CoreTextNode.js.map +1 -1
  7. package/dist/src/core/CoreTextureManager.js +1 -1
  8. package/dist/src/core/CoreTextureManager.js.map +1 -1
  9. package/dist/src/core/Stage.d.ts +2 -1
  10. package/dist/src/core/Stage.js +9 -7
  11. package/dist/src/core/Stage.js.map +1 -1
  12. package/dist/src/core/TextureMemoryManager.d.ts +1 -1
  13. package/dist/src/core/TextureMemoryManager.js +3 -3
  14. package/dist/src/core/TextureMemoryManager.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/Playback.d.ts +64 -0
  19. package/dist/src/core/animations/Playback.js +169 -0
  20. package/dist/src/core/animations/Playback.js.map +1 -0
  21. package/dist/src/core/animations/Transition.d.ts +27 -0
  22. package/dist/src/core/animations/Transition.js +52 -0
  23. package/dist/src/core/animations/Transition.js.map +1 -0
  24. package/dist/src/core/animations/utils.d.ts +2 -0
  25. package/dist/src/core/animations/utils.js +136 -0
  26. package/dist/src/core/animations/utils.js.map +1 -0
  27. package/dist/src/core/lib/ImageWorker.d.ts +2 -2
  28. package/dist/src/core/lib/ImageWorker.js +30 -11
  29. package/dist/src/core/lib/ImageWorker.js.map +1 -1
  30. package/dist/src/core/lib/WebGlContextWrapper.js +1 -1
  31. package/dist/src/core/lib/WebGlContextWrapper.js.map +1 -1
  32. package/dist/src/core/lib/utils.d.ts +6 -2
  33. package/dist/src/core/lib/utils.js +21 -21
  34. package/dist/src/core/lib/utils.js.map +1 -1
  35. package/dist/src/core/renderers/CoreRenderer.d.ts +1 -31
  36. package/dist/src/core/renderers/CoreRenderer.js.map +1 -1
  37. package/dist/src/core/renderers/CoreShaderNode.d.ts +4 -0
  38. package/dist/src/core/renderers/CoreShaderNode.js +15 -0
  39. package/dist/src/core/renderers/CoreShaderNode.js.map +1 -1
  40. package/dist/src/core/renderers/canvas/CanvasRenderer.d.ts +3 -3
  41. package/dist/src/core/renderers/canvas/CanvasRenderer.js +38 -33
  42. package/dist/src/core/renderers/canvas/CanvasRenderer.js.map +1 -1
  43. package/dist/src/core/renderers/canvas/CanvasShaderNode.d.ts +1 -2
  44. package/dist/src/core/renderers/canvas/CanvasShaderNode.js.map +1 -1
  45. package/dist/src/core/renderers/webgl/SdfRenderOp.d.ts +33 -0
  46. package/dist/src/core/renderers/webgl/SdfRenderOp.js +97 -0
  47. package/dist/src/core/renderers/webgl/SdfRenderOp.js.map +1 -0
  48. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js +1 -1
  49. package/dist/src/core/renderers/webgl/WebGlCoreCtxTexture.js.map +1 -1
  50. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js +12 -8
  51. package/dist/src/core/renderers/webgl/WebGlCtxTexture.js.map +1 -1
  52. package/dist/src/core/renderers/webgl/WebGlRenderOp.d.ts +2 -3
  53. package/dist/src/core/renderers/webgl/WebGlRenderOp.js +1 -3
  54. package/dist/src/core/renderers/webgl/WebGlRenderOp.js.map +1 -1
  55. package/dist/src/core/renderers/webgl/WebGlRenderer.d.ts +6 -18
  56. package/dist/src/core/renderers/webgl/WebGlRenderer.js +48 -61
  57. package/dist/src/core/renderers/webgl/WebGlRenderer.js.map +1 -1
  58. package/dist/src/core/renderers/webgl/WebGlShaderNode.d.ts +2 -4
  59. package/dist/src/core/renderers/webgl/WebGlShaderNode.js.map +1 -1
  60. package/dist/src/core/renderers/webgl/WebGlShaderProgram.d.ts +3 -4
  61. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js +40 -29
  62. package/dist/src/core/renderers/webgl/WebGlShaderProgram.js.map +1 -1
  63. package/dist/src/core/shaders/canvas/Border.d.ts +8 -2
  64. package/dist/src/core/shaders/canvas/Border.js +62 -23
  65. package/dist/src/core/shaders/canvas/Border.js.map +1 -1
  66. package/dist/src/core/shaders/canvas/HolePunch.js +2 -1
  67. package/dist/src/core/shaders/canvas/HolePunch.js.map +1 -1
  68. package/dist/src/core/shaders/canvas/LinearGradient.js +5 -3
  69. package/dist/src/core/shaders/canvas/LinearGradient.js.map +1 -1
  70. package/dist/src/core/shaders/canvas/RadialGradient.js +7 -5
  71. package/dist/src/core/shaders/canvas/RadialGradient.js.map +1 -1
  72. package/dist/src/core/shaders/canvas/Rounded.js +2 -2
  73. package/dist/src/core/shaders/canvas/Rounded.js.map +1 -1
  74. package/dist/src/core/shaders/canvas/RoundedWithBorder.d.ts +6 -3
  75. package/dist/src/core/shaders/canvas/RoundedWithBorder.js +39 -9
  76. package/dist/src/core/shaders/canvas/RoundedWithBorder.js.map +1 -1
  77. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.d.ts +2 -3
  78. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.js +44 -7
  79. package/dist/src/core/shaders/canvas/RoundedWithBorderAndShadow.js.map +1 -1
  80. package/dist/src/core/shaders/canvas/RoundedWithShadow.js +5 -4
  81. package/dist/src/core/shaders/canvas/RoundedWithShadow.js.map +1 -1
  82. package/dist/src/core/shaders/canvas/Shadow.js +4 -2
  83. package/dist/src/core/shaders/canvas/Shadow.js.map +1 -1
  84. package/dist/src/core/shaders/canvas/utils/render.d.ts +1 -1
  85. package/dist/src/core/shaders/canvas/utils/render.js +31 -18
  86. package/dist/src/core/shaders/canvas/utils/render.js.map +1 -1
  87. package/dist/src/core/shaders/templates/BorderTemplate.d.ts +10 -0
  88. package/dist/src/core/shaders/templates/BorderTemplate.js +20 -0
  89. package/dist/src/core/shaders/templates/BorderTemplate.js.map +1 -1
  90. package/dist/src/core/shaders/webgl/Border.js +72 -14
  91. package/dist/src/core/shaders/webgl/Border.js.map +1 -1
  92. package/dist/src/core/shaders/webgl/RoundedWithBorder.js +101 -31
  93. package/dist/src/core/shaders/webgl/RoundedWithBorder.js.map +1 -1
  94. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js +102 -38
  95. package/dist/src/core/shaders/webgl/RoundedWithBorderAndShadow.js.map +1 -1
  96. package/dist/src/core/shaders/webgl/RoundedWithShadow.js +5 -4
  97. package/dist/src/core/shaders/webgl/RoundedWithShadow.js.map +1 -1
  98. package/dist/src/core/shaders/webgl/SdfShadowShader.d.ts +9 -0
  99. package/dist/src/core/shaders/webgl/SdfShadowShader.js +100 -0
  100. package/dist/src/core/shaders/webgl/SdfShadowShader.js.map +1 -0
  101. package/dist/src/core/shaders/webgl/Shadow.js +12 -6
  102. package/dist/src/core/shaders/webgl/Shadow.js.map +1 -1
  103. package/dist/src/core/text-rendering/SdfTextRenderer.js +12 -20
  104. package/dist/src/core/text-rendering/SdfTextRenderer.js.map +1 -1
  105. package/dist/src/core/utils.d.ts +1 -1
  106. package/dist/src/main-api/Inspector.d.ts +1 -1
  107. package/dist/src/main-api/Inspector.js +4 -1
  108. package/dist/src/main-api/Inspector.js.map +1 -1
  109. package/dist/src/main-api/Renderer.d.ts +10 -0
  110. package/dist/src/main-api/Renderer.js +2 -0
  111. package/dist/src/main-api/Renderer.js.map +1 -1
  112. package/dist/tsconfig.dist.tsbuildinfo +1 -1
  113. package/package.json +1 -1
  114. package/src/core/Autosizer.ts +224 -0
  115. package/src/core/CoreNode.test.ts +116 -2
  116. package/src/core/CoreNode.ts +247 -78
  117. package/src/core/CoreTextNode.ts +3 -5
  118. package/src/core/CoreTextureManager.ts +1 -1
  119. package/src/core/Stage.ts +10 -7
  120. package/src/core/TextureMemoryManager.ts +3 -3
  121. package/src/core/lib/ImageWorker.ts +36 -11
  122. package/src/core/lib/WebGlContextWrapper.ts +1 -1
  123. package/src/core/lib/utils.ts +28 -25
  124. package/src/core/renderers/CoreRenderer.ts +1 -32
  125. package/src/core/renderers/CoreShaderNode.ts +20 -0
  126. package/src/core/renderers/canvas/CanvasRenderer.ts +43 -51
  127. package/src/core/renderers/canvas/CanvasShaderNode.ts +1 -2
  128. package/src/core/renderers/webgl/SdfRenderOp.ts +105 -0
  129. package/src/core/renderers/webgl/WebGlCtxTexture.ts +16 -9
  130. package/src/core/renderers/webgl/WebGlRenderer.ts +56 -78
  131. package/src/core/renderers/webgl/WebGlShaderNode.ts +2 -7
  132. package/src/core/renderers/webgl/WebGlShaderProgram.ts +48 -38
  133. package/src/core/shaders/canvas/Border.ts +86 -29
  134. package/src/core/shaders/canvas/HolePunch.ts +2 -1
  135. package/src/core/shaders/canvas/LinearGradient.ts +8 -6
  136. package/src/core/shaders/canvas/RadialGradient.ts +7 -10
  137. package/src/core/shaders/canvas/Rounded.ts +5 -5
  138. package/src/core/shaders/canvas/RoundedWithBorder.ts +68 -18
  139. package/src/core/shaders/canvas/RoundedWithBorderAndShadow.ts +71 -23
  140. package/src/core/shaders/canvas/RoundedWithShadow.ts +6 -5
  141. package/src/core/shaders/canvas/Shadow.ts +7 -5
  142. package/src/core/shaders/canvas/utils/render.ts +45 -36
  143. package/src/core/shaders/templates/BorderTemplate.ts +30 -0
  144. package/src/core/shaders/webgl/Border.ts +72 -15
  145. package/src/core/shaders/webgl/RoundedWithBorder.ts +101 -31
  146. package/src/core/shaders/webgl/RoundedWithBorderAndShadow.ts +102 -38
  147. package/src/core/shaders/webgl/RoundedWithShadow.ts +5 -4
  148. package/src/core/shaders/webgl/Shadow.ts +12 -6
  149. package/src/core/text-rendering/SdfTextRenderer.ts +18 -21
  150. package/src/main-api/Inspector.ts +6 -3
  151. package/src/main-api/Renderer.ts +13 -0
  152. package/src/core/renderers/webgl/WebGlRenderOp.ts +0 -170
@@ -29,6 +29,8 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
29
29
  update(node: CoreNode) {
30
30
  this.uniformRGBA('u_borderColor', this.props!['border-color']);
31
31
  this.uniform4fa('u_borderWidth', this.props!['border-w'] as Vec4);
32
+ this.uniform1f('u_borderGap', this.props!['border-gap'] as number);
33
+ this.uniform1f('u_borderAlign', this.props!['border-align'] as number);
32
34
 
33
35
  this.uniform4fa(
34
36
  'u_radius',
@@ -53,41 +55,93 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
53
55
 
54
56
  uniform vec4 u_radius;
55
57
  uniform vec4 u_borderWidth;
58
+ uniform float u_borderGap;
59
+ uniform float u_borderAlign;
56
60
 
57
61
  varying vec4 v_color;
58
62
  varying vec2 v_textureCoords;
59
63
  varying vec2 v_nodeCoords;
60
64
 
61
- varying vec4 v_innerRadius;
62
65
  varying vec2 v_innerSize;
66
+ varying vec2 v_outerSize;
67
+ varying vec2 v_outerBorderUv;
68
+ varying vec2 v_innerBorderUv;
69
+ varying vec4 v_innerBorderRadius;
70
+ varying vec4 v_outerBorderRadius;
63
71
  varying vec2 v_halfDimensions;
72
+ varying float v_edgeWidth;
64
73
  varying float v_borderZero;
65
74
 
66
75
  void main() {
67
- vec2 normalized = a_position * u_pixelRatio;
76
+ vec2 vertexPos = a_position * u_pixelRatio;
68
77
  vec2 screenSpace = vec2(2.0 / u_resolution.x, -2.0 / u_resolution.y);
69
-
70
- v_color = a_color;
71
- v_nodeCoords = a_nodeCoords;
72
- v_textureCoords = a_textureCoords;
73
-
74
- v_halfDimensions = u_dimensions * 0.5;
78
+ vec2 edge = clamp(a_nodeCoords * 2.0 - vec2(1.0), -1.0, 1.0);
79
+ vec2 edgeOffset = vec2(0.0);
75
80
 
76
81
  v_borderZero = u_borderWidth == vec4(0.0) ? 1.0 : 0.0;
82
+ v_innerSize = vec2(0.0);
83
+ v_outerSize = vec2(0.0);
77
84
 
78
85
  if(v_borderZero == 0.0) {
79
- v_innerRadius = vec4(
80
- max(0.0, u_radius.x - max(u_borderWidth.x, u_borderWidth.w) - 0.5),
81
- max(0.0, u_radius.y - max(u_borderWidth.x, u_borderWidth.y) - 0.5),
82
- max(0.0, u_radius.z - max(u_borderWidth.z, u_borderWidth.y) - 0.5),
83
- max(0.0, u_radius.w - max(u_borderWidth.z, u_borderWidth.w) - 0.5)
86
+ float borderTop = u_borderWidth.x;
87
+ float borderRight = u_borderWidth.y;
88
+ float borderBottom = u_borderWidth.z;
89
+ float borderLeft = u_borderWidth.w;
90
+
91
+ v_outerBorderUv = vec2(0.0);
92
+ v_innerBorderUv = vec2(0.0);
93
+
94
+ vec2 borderSize = vec2(borderRight + borderLeft, borderTop + borderBottom);
95
+ vec2 extraSize = borderSize * u_borderAlign;
96
+ float gapLeft = step(0.001, borderLeft) * u_borderGap;
97
+ float gapRight = step(0.001, borderRight) * u_borderGap;
98
+ float gapTop = step(0.001, borderTop) * u_borderGap;
99
+ float gapBottom = step(0.001, borderBottom) * u_borderGap;
100
+ vec2 gapSize = vec2(gapLeft + gapRight, gapTop + gapBottom);
101
+
102
+ v_outerSize = (u_dimensions + gapSize + extraSize) * 0.5;
103
+ v_innerSize = v_outerSize - borderSize * 0.5;
104
+
105
+ // Use sign() to avoid branching
106
+ vec2 borderDiff = vec2(borderRight - borderLeft, borderBottom - borderTop);
107
+ vec2 signDiff = sign(borderDiff);
108
+ borderDiff = abs(borderDiff);
109
+
110
+ vec2 gapDiff = vec2(gapRight - gapLeft, gapBottom - gapTop);
111
+ vec2 signGapDiff = sign(gapDiff);
112
+ gapDiff = abs(gapDiff);
113
+
114
+ v_outerBorderUv = -signDiff * borderDiff * u_borderAlign * 0.5 - signGapDiff * gapDiff * 0.5;
115
+ v_innerBorderUv = v_outerBorderUv + signDiff * borderDiff * 0.5;
116
+
117
+ v_outerBorderRadius = vec4(
118
+ max(0.0, u_radius.x + max(borderTop * u_borderAlign + u_borderGap, borderLeft * u_borderAlign + u_borderGap)),
119
+ max(0.0, u_radius.y + max(borderTop * u_borderAlign + u_borderGap, borderRight * u_borderAlign + u_borderGap)),
120
+ max(0.0, u_radius.z + max(borderBottom * u_borderAlign + u_borderGap, borderRight * u_borderAlign + u_borderGap)),
121
+ max(0.0, u_radius.w + max(borderBottom * u_borderAlign + u_borderGap, borderLeft * u_borderAlign + u_borderGap))
84
122
  );
85
123
 
86
- v_innerSize = (vec2(u_dimensions.x - (u_borderWidth[3] + u_borderWidth[1]) + 1.0, u_dimensions.y - (u_borderWidth[0] + u_borderWidth[2])) - 2.0) * 0.5;
124
+ v_innerBorderRadius = vec4(
125
+ max(0.0, v_outerBorderRadius.x - max(borderTop, borderLeft)),
126
+ max(0.0, v_outerBorderRadius.y - max(borderTop, borderRight)),
127
+ max(0.0, v_outerBorderRadius.z - max(borderBottom, borderRight)),
128
+ max(0.0, v_outerBorderRadius.w - max(borderBottom, borderLeft))
129
+ );
130
+
131
+ vec2 edgeOffsetExtra = step(u_dimensions * 0.5, v_outerSize) * edge * (extraSize + u_borderGap);
132
+ edgeOffset = edgeOffsetExtra;
133
+
134
+ vertexPos = (a_position + edge + edgeOffset) * u_pixelRatio;
87
135
  }
88
136
 
89
- gl_Position = vec4(normalized.x * screenSpace.x - 1.0, normalized.y * -abs(screenSpace.y) + 1.0, 0.0, 1.0);
90
- gl_Position.y = -sign(screenSpace.y) * gl_Position.y;
137
+ gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0);
138
+
139
+ v_color = a_color;
140
+ v_nodeCoords = a_nodeCoords + (screenSpace + edgeOffset) / (u_dimensions);
141
+ v_textureCoords = a_textureCoords + (screenSpace + edgeOffset) / (u_dimensions);
142
+
143
+ v_halfDimensions = u_dimensions * 0.5;
144
+ v_edgeWidth = 1.0 / u_pixelRatio;
91
145
  }
92
146
  `,
93
147
  fragment: `
@@ -104,17 +158,23 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
104
158
  uniform sampler2D u_texture;
105
159
 
106
160
  uniform vec4 u_radius;
107
-
108
161
  uniform vec4 u_borderWidth;
109
162
  uniform vec4 u_borderColor;
163
+ uniform float u_borderGap;
164
+ uniform float u_borderAlign;
110
165
 
111
166
  varying vec4 v_color;
112
167
  varying vec2 v_textureCoords;
113
168
  varying vec2 v_nodeCoords;
114
169
 
115
- varying vec2 v_halfDimensions;
116
- varying vec4 v_innerRadius;
117
170
  varying vec2 v_innerSize;
171
+ varying vec2 v_outerSize;
172
+ varying vec2 v_outerBorderUv;
173
+ varying vec2 v_innerBorderUv;
174
+ varying vec4 v_innerBorderRadius;
175
+ varying vec4 v_outerBorderRadius;
176
+ varying vec2 v_halfDimensions;
177
+ varying float v_edgeWidth;
118
178
  varying float v_borderZero;
119
179
 
120
180
  float roundedBox(vec2 p, vec2 s, vec4 r) {
@@ -126,27 +186,37 @@ export const RoundedWithBorder: WebGlShaderType<RoundedWithBorderProps> = {
126
186
 
127
187
  void main() {
128
188
  vec4 color = texture2D(u_texture, v_textureCoords) * v_color;
129
-
189
+ vec4 resultColor = vec4(0.0);
130
190
  vec2 boxUv = v_nodeCoords.xy * u_dimensions - v_halfDimensions;
131
- float outerDist = roundedBox(boxUv, v_halfDimensions, u_radius);
132
191
 
133
- float edgeWidth = 1.0 / u_pixelRatio;
134
- float outerAlpha = 1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, outerDist);
192
+ float nodeDist;
193
+ float nodeAlpha;
135
194
 
136
195
  if(v_borderZero == 1.0) {
137
- gl_FragColor = mix(vec4(0.0), color, outerAlpha) * u_alpha;
196
+ nodeDist = roundedBox(boxUv, v_halfDimensions - v_edgeWidth, u_radius);
197
+ nodeAlpha = 1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, nodeDist);
198
+ gl_FragColor = mix(vec4(0.0), color, nodeAlpha) * u_alpha;
138
199
  return;
139
200
  }
140
201
 
141
- boxUv.x += u_borderWidth.y > u_borderWidth.w ? (u_borderWidth.y - u_borderWidth.w) * 0.5 : -(u_borderWidth.w - u_borderWidth.y) * 0.5;
142
- boxUv.y += u_borderWidth.z > u_borderWidth.x ? ((u_borderWidth.z - u_borderWidth.x) * 0.5 + 0.5) : -(u_borderWidth.x - u_borderWidth.z) * 0.5;
202
+ float outerDist = roundedBox(boxUv + v_outerBorderUv, v_outerSize - v_edgeWidth, v_outerBorderRadius);
203
+ float innerDist = roundedBox(boxUv + v_innerBorderUv, v_innerSize - v_edgeWidth, v_innerBorderRadius);
204
+
205
+ if(u_borderGap == 0.0) {
206
+ resultColor = mix(resultColor, u_borderColor, 1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, outerDist));
207
+ resultColor = mix(resultColor, color, 1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, innerDist));
208
+ gl_FragColor = resultColor * u_alpha;
209
+ return;
210
+ }
143
211
 
144
- float innerDist = roundedBox(boxUv, v_innerSize, v_innerRadius);
145
- float innerAlpha = 1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, innerDist);
212
+ nodeDist = roundedBox(boxUv, v_halfDimensions - v_edgeWidth, u_radius);
213
+ nodeAlpha = 1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, nodeDist);
214
+ float borderDist = max(-innerDist, outerDist);
215
+ float borderAlpha = 1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, borderDist);
146
216
 
147
- vec4 resColor = mix(u_borderColor, color, innerAlpha);
148
- resColor = mix(vec4(0.0), resColor, outerAlpha);
149
- gl_FragColor = resColor * u_alpha;
217
+ resultColor = mix(vec4(0.0), color, nodeAlpha);
218
+ resultColor = mix(resultColor, u_borderColor, borderAlpha * u_borderColor.a);
219
+ gl_FragColor = resultColor * u_alpha;
150
220
  }
151
221
  `,
152
222
  };
@@ -31,6 +31,8 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
31
31
  const props = this.props!;
32
32
  this.uniformRGBA('u_borderColor', props['border-color']);
33
33
  this.uniform4fa('u_borderWidth', props['border-w'] as Vec4);
34
+ this.uniform1f('u_borderGap', this.props!['border-gap'] as number);
35
+ this.uniform1f('u_borderAlign', this.props!['border-align'] as number);
34
36
 
35
37
  this.uniformRGBA('u_shadowColor', props['shadow-color']);
36
38
  this.uniform4fa('u_shadow', props['shadow-projection']);
@@ -60,45 +62,94 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
60
62
  uniform vec4 u_shadow;
61
63
  uniform vec4 u_radius;
62
64
  uniform vec4 u_borderWidth;
65
+ uniform float u_borderGap;
66
+ uniform float u_borderAlign;
63
67
 
64
68
  varying vec4 v_color;
65
69
  varying vec2 v_textureCoords;
66
70
  varying vec2 v_nodeCoords;
67
71
 
68
- varying vec4 v_innerRadius;
69
72
  varying vec2 v_innerSize;
73
+ varying vec2 v_outerSize;
74
+ varying vec2 v_outerBorderUv;
75
+ varying vec2 v_innerBorderUv;
76
+ varying vec4 v_innerBorderRadius;
77
+ varying vec4 v_outerBorderRadius;
70
78
  varying vec2 v_halfDimensions;
79
+ varying float v_edgeWidth;
71
80
  varying float v_borderZero;
72
81
 
73
82
  void main() {
74
83
  vec2 screenSpace = vec2(2.0 / u_resolution.x, -2.0 / u_resolution.y);
75
- vec2 outerEdge = clamp(a_nodeCoords * 2.0 - vec2(1.0), -1.0, 1.0);
84
+ vec2 edge = clamp(a_nodeCoords * 2.0 - vec2(1.0), -1.0, 1.0);
76
85
 
77
- vec2 shadowEdge = outerEdge * ((u_shadow.w * 2.0)+ u_shadow.z) + u_shadow.xy;
78
- vec2 normVertexPos = a_position * u_pixelRatio;
79
-
80
- vec2 vertexPos = (a_position + outerEdge + shadowEdge) * u_pixelRatio;
81
- gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0);
82
-
83
- v_halfDimensions = u_dimensions * 0.5;
84
-
85
- v_color = a_color;
86
- v_nodeCoords = a_nodeCoords + (screenSpace + shadowEdge) / (u_dimensions);
87
- v_textureCoords = a_textureCoords + (screenSpace + shadowEdge) / (u_dimensions);
86
+ vec2 edgeOffset = edge * ((u_shadow.w * 2.0)+ u_shadow.z) + u_shadow.xy;
87
+ vec2 vertexPos = (a_position + edge + edgeOffset) * u_pixelRatio;
88
88
 
89
89
  v_borderZero = u_borderWidth == vec4(0.0) ? 1.0 : 0.0;
90
90
 
91
+ v_innerSize = vec2(0.0);
92
+ v_outerSize = vec2(0.0);
91
93
 
92
94
  if(v_borderZero == 0.0) {
93
- v_innerRadius = vec4(
94
- max(0.0, u_radius.x - max(u_borderWidth.x, u_borderWidth.w) - 0.5),
95
- max(0.0, u_radius.y - max(u_borderWidth.x, u_borderWidth.y) - 0.5),
96
- max(0.0, u_radius.z - max(u_borderWidth.z, u_borderWidth.y) - 0.5),
97
- max(0.0, u_radius.w - max(u_borderWidth.z, u_borderWidth.w) - 0.5)
95
+ float borderTop = u_borderWidth.x;
96
+ float borderRight = u_borderWidth.y;
97
+ float borderBottom = u_borderWidth.z;
98
+ float borderLeft = u_borderWidth.w;
99
+
100
+ v_outerBorderUv = vec2(0.0);
101
+ v_innerBorderUv = vec2(0.0);
102
+
103
+ vec2 borderSize = vec2(borderRight + borderLeft, borderTop + borderBottom);
104
+ vec2 extraSize = borderSize * u_borderAlign;
105
+ float gapLeft = step(0.001, borderLeft) * u_borderGap;
106
+ float gapRight = step(0.001, borderRight) * u_borderGap;
107
+ float gapTop = step(0.001, borderTop) * u_borderGap;
108
+ float gapBottom = step(0.001, borderBottom) * u_borderGap;
109
+ vec2 gapSize = vec2(gapLeft + gapRight, gapTop + gapBottom);
110
+
111
+ v_outerSize = (u_dimensions + gapSize + extraSize) * 0.5;
112
+ v_innerSize = v_outerSize - borderSize * 0.5;
113
+
114
+ // Use sign() to avoid branching
115
+ vec2 borderDiff = vec2(borderRight - borderLeft, borderBottom - borderTop);
116
+ vec2 signDiff = sign(borderDiff);
117
+ borderDiff = abs(borderDiff);
118
+
119
+ vec2 gapDiff = vec2(gapRight - gapLeft, gapBottom - gapTop);
120
+ vec2 signGapDiff = sign(gapDiff);
121
+ gapDiff = abs(gapDiff);
122
+
123
+ v_outerBorderUv = -signDiff * borderDiff * u_borderAlign * 0.5 - signGapDiff * gapDiff * 0.5;
124
+ v_innerBorderUv = v_outerBorderUv + signDiff * borderDiff * 0.5;
125
+
126
+ v_outerBorderRadius = vec4(
127
+ max(0.0, u_radius.x + max(borderTop * u_borderAlign + u_borderGap, borderLeft * u_borderAlign + u_borderGap)),
128
+ max(0.0, u_radius.y + max(borderTop * u_borderAlign + u_borderGap, borderRight * u_borderAlign + u_borderGap)),
129
+ max(0.0, u_radius.z + max(borderBottom * u_borderAlign + u_borderGap, borderRight * u_borderAlign + u_borderGap)),
130
+ max(0.0, u_radius.w + max(borderBottom * u_borderAlign + u_borderGap, borderLeft * u_borderAlign + u_borderGap))
98
131
  );
99
132
 
100
- v_innerSize = (vec2(u_dimensions.x - (u_borderWidth[3] + u_borderWidth[1]) - 1.0, u_dimensions.y - (u_borderWidth[0] + u_borderWidth[2])) - 2.0) * 0.5;
133
+ v_innerBorderRadius = vec4(
134
+ max(0.0, v_outerBorderRadius.x - max(borderTop, borderLeft)),
135
+ max(0.0, v_outerBorderRadius.y - max(borderTop, borderRight)),
136
+ max(0.0, v_outerBorderRadius.z - max(borderBottom, borderRight)),
137
+ max(0.0, v_outerBorderRadius.w - max(borderBottom, borderLeft))
138
+ );
139
+
140
+ vec2 edgeOffsetExtra = step(u_dimensions * 0.5, v_outerSize) * edge * (extraSize + u_borderGap);
141
+ edgeOffset += edgeOffsetExtra;
142
+
143
+ vertexPos = (a_position + edge + edgeOffset) * u_pixelRatio;
101
144
  }
145
+
146
+ gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0);
147
+
148
+ v_halfDimensions = u_dimensions * 0.5;
149
+ v_edgeWidth = 1.0 / u_pixelRatio;
150
+ v_color = a_color;
151
+ v_nodeCoords = a_nodeCoords + (screenSpace + edgeOffset) / (u_dimensions);
152
+ v_textureCoords = a_textureCoords + (screenSpace + edgeOffset) / (u_dimensions);
102
153
  }
103
154
  `,
104
155
  fragment: `
@@ -125,9 +176,14 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
125
176
  varying vec2 v_textureCoords;
126
177
  varying vec2 v_nodeCoords;
127
178
 
128
- varying vec2 v_halfDimensions;
129
- varying vec4 v_innerRadius;
130
179
  varying vec2 v_innerSize;
180
+ varying vec2 v_outerSize;
181
+ varying vec2 v_outerBorderUv;
182
+ varying vec2 v_innerBorderUv;
183
+ varying vec4 v_innerBorderRadius;
184
+ varying vec4 v_outerBorderRadius;
185
+ varying vec2 v_halfDimensions;
186
+ varying float v_edgeWidth;
131
187
  varying float v_borderZero;
132
188
 
133
189
  float roundedBox(vec2 p, vec2 s, vec4 r) {
@@ -147,30 +203,38 @@ export const RoundedWithBorderAndShadow: WebGlShaderType<RoundedWithBorderAndSha
147
203
 
148
204
  void main() {
149
205
  vec4 color = texture2D(u_texture, v_textureCoords) * v_color;
150
-
206
+ vec4 resultColor = vec4(0.0);
151
207
  vec2 boxUv = v_nodeCoords.xy * u_dimensions - v_halfDimensions;
152
- float outerDist = roundedBox(boxUv, v_halfDimensions - 1.0, u_radius);
153
-
154
- float edgeWidth = 1.0 / u_pixelRatio;
155
- float outerAlpha = 1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, outerDist);
156
-
157
- float shadowAlpha = shadowBox(boxUv - u_shadow.xy, v_halfDimensions + u_shadow.w, u_radius + u_shadow.z);
158
- vec4 shadow = mix(vec4(0.0), u_shadowColor, shadowAlpha);
208
+ float nodeDist;
209
+ float nodeAlpha;
210
+ float shadowAlpha;
159
211
 
160
212
  if(v_borderZero == 1.0) {
161
- gl_FragColor = mix(shadow, color, outerAlpha) * u_alpha;
213
+ nodeDist = roundedBox(boxUv, v_halfDimensions - v_edgeWidth, u_radius);
214
+ nodeAlpha = 1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, nodeDist);
215
+ shadowAlpha = shadowBox(boxUv - u_shadow.xy, v_halfDimensions + u_shadow.w - v_edgeWidth, u_radius + u_shadow.z);
216
+ resultColor = mix(resultColor, u_shadowColor, shadowAlpha);
217
+ gl_FragColor = mix(resultColor, color, nodeAlpha) * u_alpha;
162
218
  return;
163
219
  }
164
220
 
165
- boxUv.x += u_borderWidth.y > u_borderWidth.w ? (u_borderWidth.y - u_borderWidth.w) * 0.5 : -(u_borderWidth.w - u_borderWidth.y) * 0.5;
166
- boxUv.y += u_borderWidth.z > u_borderWidth.x ? ((u_borderWidth.z - u_borderWidth.x) * 0.5 + 0.5) : -(u_borderWidth.x - u_borderWidth.z) * 0.5;
167
-
168
- float innerDist = roundedBox(boxUv, v_innerSize, v_innerRadius);
169
- float innerAlpha = 1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, innerDist);
221
+ if(v_outerSize.x > v_halfDimensions.x || v_outerSize.y > v_halfDimensions.y) {
222
+ shadowAlpha = shadowBox(boxUv + v_outerBorderUv - u_shadow.xy, v_outerSize + u_shadow.w - v_edgeWidth, v_outerBorderRadius + u_shadow.z);
223
+ }
224
+ else {
225
+ shadowAlpha = shadowBox(boxUv - u_shadow.xy, v_halfDimensions + u_shadow.w - v_edgeWidth, u_radius + u_shadow.z);
226
+ }
170
227
 
171
- vec4 resColor = mix(u_borderColor, color, innerAlpha);
172
- resColor = mix(shadow, resColor, outerAlpha);
173
- gl_FragColor = resColor * u_alpha;
228
+ nodeDist = roundedBox(boxUv, v_halfDimensions - v_edgeWidth, u_radius);
229
+ nodeAlpha = 1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, nodeDist);
230
+ float outerDist = roundedBox(boxUv + v_outerBorderUv, v_outerSize - v_edgeWidth, v_outerBorderRadius);
231
+ float innerDist = roundedBox(boxUv + v_innerBorderUv, v_innerSize - v_edgeWidth, v_innerBorderRadius);
232
+ float borderDist = max(-innerDist, outerDist);
233
+ float borderAlpha = 1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, borderDist);
234
+ resultColor = mix(resultColor, u_shadowColor, shadowAlpha);
235
+ resultColor = mix(resultColor, color, nodeAlpha);
236
+ resultColor = mix(resultColor, u_borderColor, borderAlpha * u_borderColor.a);
237
+ gl_FragColor = resultColor * u_alpha;
174
238
  }
175
239
  `,
176
240
  };
@@ -59,6 +59,8 @@ export const RoundedWithShadow: WebGlShaderType<RoundedWithShadowProps> = {
59
59
  varying vec2 v_textureCoords;
60
60
  varying vec2 v_nodeCoords;
61
61
 
62
+ varying float v_edgeWidth;
63
+
62
64
  float roundedBox(vec2 p, vec2 s, vec4 r) {
63
65
  r.xy = (p.x > 0.0) ? r.yz : r.xw;
64
66
  r.x = (p.y > 0.0) ? r.y : r.x;
@@ -79,12 +81,11 @@ export const RoundedWithShadow: WebGlShaderType<RoundedWithShadowProps> = {
79
81
  vec2 halfDimensions = (u_dimensions * 0.5);
80
82
 
81
83
  vec2 boxUv = v_nodeCoords.xy * u_dimensions - halfDimensions;
82
- float boxDist = roundedBox(boxUv, halfDimensions, u_radius);
84
+ float boxDist = roundedBox(boxUv, halfDimensions - v_edgeWidth, u_radius);
83
85
 
84
- float edgeWidth = 1.0 / u_pixelRatio;
85
- float roundedAlpha = 1.0 - smoothstep(-0.5 * edgeWidth, 0.5 * edgeWidth, boxDist);
86
+ float roundedAlpha = 1.0 - smoothstep(-0.5 * v_edgeWidth, 0.5 * v_edgeWidth, boxDist);
86
87
 
87
- float shadowAlpha = shadowBox(boxUv - u_shadow.xy, halfDimensions + u_shadow.w, u_radius + u_shadow.z);
88
+ float shadowAlpha = shadowBox(boxUv - u_shadow.xy, halfDimensions + u_shadow.w - v_edgeWidth, u_radius + u_shadow.z);
88
89
 
89
90
  vec4 resColor = vec4(0.0);
90
91
  resColor = mix(resColor, u_shadow_color, shadowAlpha);
@@ -50,12 +50,14 @@ export const Shadow: WebGlShaderType<ShadowProps> = {
50
50
  varying vec2 v_textureCoords;
51
51
  varying vec2 v_nodeCoords;
52
52
 
53
+ varying float v_edgeWidth;
54
+ varying vec2 v_halfDimensions;
55
+
53
56
  void main() {
54
57
  vec2 screenSpace = vec2(2.0 / u_resolution.x, -2.0 / u_resolution.y);
55
58
  vec2 outerEdge = clamp(a_nodeCoords * 2.0 - vec2(1.0), -1.0, 1.0);
56
59
 
57
60
  vec2 shadowEdge = outerEdge * ((u_shadow.w * 2.0)+ u_shadow.z) + u_shadow.xy;
58
- vec2 normVertexPos = a_position * u_pixelRatio;
59
61
 
60
62
  vec2 vertexPos = (a_position + outerEdge + shadowEdge) * u_pixelRatio;
61
63
  gl_Position = vec4(vertexPos.x * screenSpace.x - 1.0, -sign(screenSpace.y) * (vertexPos.y * -abs(screenSpace.y)) + 1.0, 0.0, 1.0);
@@ -63,6 +65,9 @@ export const Shadow: WebGlShaderType<ShadowProps> = {
63
65
  v_color = a_color;
64
66
  v_nodeCoords = a_nodeCoords + (screenSpace + shadowEdge) / (u_dimensions);
65
67
  v_textureCoords = a_textureCoords + (screenSpace + shadowEdge) / (u_dimensions);
68
+
69
+ v_halfDimensions = u_dimensions * 0.5;
70
+ v_edgeWidth = 1.0 / u_pixelRatio;
66
71
  }
67
72
  `,
68
73
  fragment: `
@@ -85,6 +90,9 @@ export const Shadow: WebGlShaderType<ShadowProps> = {
85
90
  varying vec2 v_textureCoords;
86
91
  varying vec2 v_nodeCoords;
87
92
 
93
+ varying vec2 v_halfDimensions;
94
+ varying float v_edgeWidth;
95
+
88
96
  float box(vec2 p, vec2 s) {
89
97
  vec2 q = abs(p) - s;
90
98
  return (min(max(q.x, q.y), 0.0) + length(max(q, 0.0))) + 2.0;
@@ -98,13 +106,11 @@ export const Shadow: WebGlShaderType<ShadowProps> = {
98
106
 
99
107
  void main() {
100
108
  vec4 color = texture2D(u_texture, v_textureCoords) * v_color;
101
- vec2 halfDimensions = (u_dimensions * 0.5);
102
-
103
- vec2 boxUv = v_nodeCoords.xy * u_dimensions - halfDimensions;
104
- float boxDist = box(boxUv, halfDimensions);
109
+ vec2 boxUv = v_nodeCoords.xy * u_dimensions - v_halfDimensions;
110
+ float boxDist = box(boxUv, v_halfDimensions - v_edgeWidth);
105
111
 
106
112
  float boxAlpha = 1.0 - smoothstep(0.0, u_pixelRatio, boxDist);
107
- float shadowDist = shadowBox(boxUv - u_shadow.xy, halfDimensions + u_shadow.w, u_shadow.z);
113
+ float shadowDist = shadowBox(boxUv - u_shadow.xy, v_halfDimensions + u_shadow.w - v_edgeWidth, u_shadow.z);
108
114
 
109
115
  vec4 resColor = vec4(0.0);
110
116
  resColor = mix(resColor, u_color, shadowDist);
@@ -29,7 +29,7 @@ import { hasZeroWidthSpace } from './Utils.js';
29
29
  import * as SdfFontHandler from './SdfFontHandler.js';
30
30
  import type { CoreRenderer } from '../renderers/CoreRenderer.js';
31
31
  import { WebGlRenderer } from '../renderers/webgl/WebGlRenderer.js';
32
- import { WebGlRenderOp } from '../renderers/webgl/WebGlRenderOp.js';
32
+ import { SdfRenderOp } from '../renderers/webgl/SdfRenderOp.js';
33
33
  import { Sdf, type SdfShaderProps } from '../shaders/webgl/SdfShader.js';
34
34
  import { BufferCollection } from '../renderers/webgl/internal/BufferCollection.js';
35
35
  import type { WebGlCtxTexture } from '../renderers/webgl/WebGlCtxTexture.js';
@@ -238,28 +238,25 @@ const renderQuads = (
238
238
  glw.arrayBufferData(buffer, vertexBuffer, glw.STATIC_DRAW as number);
239
239
  }
240
240
 
241
- const renderOp = new WebGlRenderOp(
241
+ const renderOp = new SdfRenderOp(
242
242
  renderer as WebGlRenderer,
243
+ sdfShader!, // Ensure sdfShader is not null
243
244
  {
244
- sdfShaderProps: {
245
- transform: globalTransform,
246
- color: mergeColorAlpha(color, worldAlpha),
247
- size: layout.fontScale, // Use proper font scaling in shader
248
- distanceRange: layout.distanceRange,
249
- } satisfies SdfShaderProps,
250
- sdfBuffers: webGlBuffers,
251
- shader: sdfShader,
252
- alpha: worldAlpha,
253
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment
254
- clippingRect: renderProps.clippingRect as any,
255
- height: layout.height,
256
- width: layout.width,
257
- rtt: false,
258
- parentHasRenderTexture: renderProps.parentHasRenderTexture,
259
- // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment
260
- framebufferDimensions: renderProps.framebufferDimensions as any,
261
- },
262
- 0,
245
+ transform: globalTransform,
246
+ color: mergeColorAlpha(color, worldAlpha),
247
+ size: layout.fontScale, // Use proper font scaling in shader
248
+ distanceRange: layout.distanceRange,
249
+ } satisfies SdfShaderProps,
250
+ webGlBuffers,
251
+ worldAlpha,
252
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
253
+ renderProps.clippingRect as any,
254
+ layout.width,
255
+ layout.height,
256
+ false,
257
+ renderProps.parentHasRenderTexture,
258
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
259
+ renderProps.framebufferDimensions as any,
263
260
  );
264
261
 
265
262
  // Add atlas texture and set quad count
@@ -773,10 +773,13 @@ export class Inspector {
773
773
  return this.createProxy(node, div);
774
774
  }
775
775
 
776
- createTextNode(node: CoreNode): CoreTextNode {
777
- const div = this.createDiv(node.id, node.props);
776
+ createTextNode(node: CoreTextNode): CoreTextNode {
777
+ // eslint-disable-next-line
778
+ // @ts-ignore - textProps is a private property and keeping it that way
779
+ // but we need it from the inspector to set the initial properties on the div element
780
+ const div = this.createDiv(node.id, node.textProps);
778
781
  (div as HTMLElement & { node: CoreNode }).node = node;
779
- (node as CoreNode & { div: HTMLElement }).div = div;
782
+ (node as CoreTextNode & { div: HTMLElement }).div = div;
780
783
 
781
784
  return this.createProxy(node, div) as CoreTextNode;
782
785
  }
@@ -238,6 +238,17 @@ export interface RendererRuntimeSettings {
238
238
  */
239
239
  fpsUpdateInterval: number;
240
240
 
241
+ /**
242
+ * Clears the render buffer on reset
243
+ *
244
+ * @remarks
245
+ * If false, the renderer will not clear the buffer before rendering a new frame.
246
+ * This is useful if you want to preserve the previous frame.
247
+ *
248
+ * @defaultValue `true`
249
+ */
250
+ enableClear: boolean;
251
+
241
252
  /**
242
253
  * DOM Inspector
243
254
  *
@@ -525,6 +536,7 @@ export class RendererMain extends EventEmitter {
525
536
  settings.devicePhysicalPixelRatio || window.devicePixelRatio || 1,
526
537
  clearColor: settings.clearColor ?? 0x00000000,
527
538
  fpsUpdateInterval: settings.fpsUpdateInterval || 0,
539
+ enableClear: settings.enableClear ?? true,
528
540
  targetFPS: settings.targetFPS || 0,
529
541
  numImageWorkers:
530
542
  settings.numImageWorkers !== undefined ? settings.numImageWorkers : 2,
@@ -586,6 +598,7 @@ export class RendererMain extends EventEmitter {
586
598
  enableContextSpy: settings.enableContextSpy!,
587
599
  forceWebGL2: settings.forceWebGL2!,
588
600
  fpsUpdateInterval: settings.fpsUpdateInterval!,
601
+ enableClear: settings.enableClear!,
589
602
  numImageWorkers: settings.numImageWorkers!,
590
603
  renderEngine: settings.renderEngine!,
591
604
  textureMemory: resolvedTxSettings,