@lightningjs/renderer 0.8.0 → 0.8.2
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.
- package/dist/src/core/CoreNode.d.ts +7 -2
- package/dist/src/core/CoreNode.js +43 -13
- package/dist/src/core/CoreNode.js.map +1 -1
- package/dist/src/core/CoreShaderManager.d.ts +2 -0
- package/dist/src/core/CoreShaderManager.js +2 -0
- package/dist/src/core/CoreShaderManager.js.map +1 -1
- package/dist/src/core/Stage.js +1 -0
- package/dist/src/core/Stage.js.map +1 -1
- package/dist/src/core/lib/ImageWorker.js +1 -1
- package/dist/src/core/renderers/webgl/shaders/DynamicShader.d.ts +1 -0
- package/dist/src/core/renderers/webgl/shaders/DynamicShader.js +23 -0
- package/dist/src/core/renderers/webgl/shaders/DynamicShader.js.map +1 -1
- package/dist/src/core/renderers/webgl/shaders/effects/HolePunchEffect.d.ts +58 -0
- package/dist/src/core/renderers/webgl/shaders/effects/HolePunchEffect.js +112 -0
- package/dist/src/core/renderers/webgl/shaders/effects/HolePunchEffect.js.map +1 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js +3 -0
- package/dist/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.js.map +1 -1
- package/dist/src/main-api/INode.d.ts +13 -0
- package/dist/src/main-api/Inspector.js +4 -0
- package/dist/src/main-api/Inspector.js.map +1 -1
- package/dist/src/main-api/RendererMain.js +1 -0
- package/dist/src/main-api/RendererMain.js.map +1 -1
- package/dist/src/render-drivers/main/MainOnlyNode.d.ts +2 -0
- package/dist/src/render-drivers/main/MainOnlyNode.js +7 -0
- package/dist/src/render-drivers/main/MainOnlyNode.js.map +1 -1
- package/dist/src/render-drivers/main/MainOnlyTextNode.js +1 -0
- package/dist/src/render-drivers/main/MainOnlyTextNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/NodeStruct.d.ts +3 -0
- package/dist/src/render-drivers/threadx/NodeStruct.js +9 -0
- package/dist/src/render-drivers/threadx/NodeStruct.js.map +1 -1
- package/dist/src/render-drivers/threadx/SharedNode.d.ts +1 -0
- package/dist/src/render-drivers/threadx/SharedNode.js +1 -0
- package/dist/src/render-drivers/threadx/SharedNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js +2 -0
- package/dist/src/render-drivers/threadx/ThreadXCoreDriver.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js +1 -0
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js +1 -0
- package/dist/src/render-drivers/threadx/worker/ThreadXRendererTextNode.js.map +1 -1
- package/dist/src/render-drivers/threadx/worker/renderer.js +1 -0
- package/dist/src/render-drivers/threadx/worker/renderer.js.map +1 -1
- package/dist/src/utils.d.ts +8 -0
- package/dist/src/utils.js +10 -0
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.dist.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/core/CoreNode.ts +63 -19
- package/src/core/CoreShaderManager.ts +3 -0
- package/src/core/Stage.ts +1 -0
- package/src/core/lib/ImageWorker.ts +1 -1
- package/src/core/renderers/webgl/shaders/DynamicShader.ts +31 -0
- package/src/core/renderers/webgl/shaders/effects/HolePunchEffect.ts +166 -0
- package/src/core/text-rendering/renderers/SdfTextRenderer/internal/layoutText.ts +3 -0
- package/src/main-api/INode.ts +13 -0
- package/src/main-api/Inspector.ts +5 -0
- package/src/main-api/RendererMain.ts +1 -0
- package/src/render-drivers/main/MainOnlyNode.ts +9 -0
- package/src/render-drivers/main/MainOnlyTextNode.ts +1 -0
- package/src/render-drivers/threadx/NodeStruct.ts +10 -0
- package/src/render-drivers/threadx/SharedNode.ts +2 -0
- package/src/render-drivers/threadx/ThreadXCoreDriver.ts +2 -0
- package/src/render-drivers/threadx/worker/ThreadXRendererNode.ts +1 -0
- package/src/render-drivers/threadx/worker/ThreadXRendererTextNode.ts +1 -0
- package/src/render-drivers/threadx/worker/renderer.ts +1 -0
- package/src/utils.ts +11 -0
|
@@ -170,6 +170,37 @@ export class DynamicShader extends WebGlCoreShader {
|
|
|
170
170
|
});
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
+
override canBatchShaderProps(
|
|
174
|
+
propsA: Required<DynamicShaderProps>,
|
|
175
|
+
propsB: Required<DynamicShaderProps>,
|
|
176
|
+
): boolean {
|
|
177
|
+
if (
|
|
178
|
+
propsA.$dimensions.width !== propsB.$dimensions.width ||
|
|
179
|
+
propsA.$dimensions.height !== propsB.$dimensions.height ||
|
|
180
|
+
propsA.effects.length !== propsB.effects.length
|
|
181
|
+
) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
const propsEffectsLen = propsA.effects.length;
|
|
185
|
+
let i = 0;
|
|
186
|
+
for (; i < propsEffectsLen; i++) {
|
|
187
|
+
const effectA = propsA.effects[i]!;
|
|
188
|
+
const effectB = propsB.effects[i]!;
|
|
189
|
+
if (effectA.type !== effectB.type) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
for (const key in effectA.props) {
|
|
193
|
+
if (
|
|
194
|
+
(effectB.props && !effectB.props[key]) ||
|
|
195
|
+
effectA.props[key] !== effectB.props![key]
|
|
196
|
+
) {
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return true;
|
|
202
|
+
}
|
|
203
|
+
|
|
173
204
|
static createShader(
|
|
174
205
|
props: DynamicShaderProps,
|
|
175
206
|
effectContructors: Partial<EffectMap>,
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* If not stated otherwise in this file or this component's LICENSE file the
|
|
3
|
+
* following copyright and licenses apply:
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2023 Comcast Cable Communications Management, LLC.
|
|
6
|
+
*
|
|
7
|
+
* Licensed under the Apache License, Version 2.0 (the License);
|
|
8
|
+
* you may not use this file except in compliance with the License.
|
|
9
|
+
* You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
14
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
15
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
16
|
+
* See the License for the specific language governing permissions and
|
|
17
|
+
* limitations under the License.
|
|
18
|
+
*/
|
|
19
|
+
import {
|
|
20
|
+
ShaderEffect,
|
|
21
|
+
type DefaultEffectProps,
|
|
22
|
+
type ShaderEffectUniforms,
|
|
23
|
+
} from './ShaderEffect.js';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Properties of the {@link RadiusEffect} shader
|
|
27
|
+
*/
|
|
28
|
+
export interface HolePunchEffectProps extends DefaultEffectProps {
|
|
29
|
+
/**
|
|
30
|
+
* X position where the hole punch starts
|
|
31
|
+
*/
|
|
32
|
+
x?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Y position where the hole punch starts
|
|
35
|
+
*/
|
|
36
|
+
y?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Width of the hole punch
|
|
39
|
+
*/
|
|
40
|
+
width?: number;
|
|
41
|
+
/**
|
|
42
|
+
* height of the hole punch
|
|
43
|
+
*
|
|
44
|
+
* @remarks if not defined uses the width value
|
|
45
|
+
*/
|
|
46
|
+
height?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Corner radius in pixels, to cut out of the corners of the hole punch
|
|
49
|
+
*
|
|
50
|
+
* @remarks
|
|
51
|
+
* You can input an array with a length of up to four or a number.
|
|
52
|
+
*
|
|
53
|
+
* array length 4:
|
|
54
|
+
* [topLeft, topRight, bottomRight, bottomLeft]
|
|
55
|
+
*
|
|
56
|
+
* array length 2:
|
|
57
|
+
* [20, 40] -> [20(topLeft), 40(topRight), 20(bottomRight), 40(bottomLeft)]
|
|
58
|
+
*
|
|
59
|
+
* array length 3:
|
|
60
|
+
* [20, 40, 60] -> [20(topLeft), 40(topRight), 60(bottomRight), 20(bottomLeft)]
|
|
61
|
+
*
|
|
62
|
+
* number:
|
|
63
|
+
* 30 -> [30, 30, 30, 30]
|
|
64
|
+
*
|
|
65
|
+
* @default 0
|
|
66
|
+
*/
|
|
67
|
+
radius?: number | number[];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Masks the current maskcolor a holepunch effect with rounded corners similar to {@link RoundedRectangle}
|
|
72
|
+
*/
|
|
73
|
+
export class HolePunchEffect extends ShaderEffect {
|
|
74
|
+
static z$__type__Props: HolePunchEffectProps;
|
|
75
|
+
override readonly name = 'holePunch';
|
|
76
|
+
|
|
77
|
+
static override getEffectKey(): string {
|
|
78
|
+
return `holePunch`;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
static override uniforms: ShaderEffectUniforms = {
|
|
82
|
+
x: {
|
|
83
|
+
value: 0,
|
|
84
|
+
method: 'uniform1f',
|
|
85
|
+
type: 'float',
|
|
86
|
+
},
|
|
87
|
+
y: {
|
|
88
|
+
value: 0,
|
|
89
|
+
method: 'uniform1f',
|
|
90
|
+
type: 'float',
|
|
91
|
+
},
|
|
92
|
+
width: {
|
|
93
|
+
value: 0,
|
|
94
|
+
method: 'uniform1f',
|
|
95
|
+
type: 'float',
|
|
96
|
+
},
|
|
97
|
+
height: {
|
|
98
|
+
value: 0,
|
|
99
|
+
method: 'uniform1f',
|
|
100
|
+
type: 'float',
|
|
101
|
+
},
|
|
102
|
+
radius: {
|
|
103
|
+
value: 0,
|
|
104
|
+
method: 'uniform4fv',
|
|
105
|
+
type: 'vec4',
|
|
106
|
+
validator: (value: number | number[]) => {
|
|
107
|
+
let r = value;
|
|
108
|
+
if (Array.isArray(r)) {
|
|
109
|
+
if (r.length === 2) {
|
|
110
|
+
r = [r[0], r[1], r[0], r[1]] as number[];
|
|
111
|
+
} else if (r.length === 3) {
|
|
112
|
+
r = [r[0], r[1], r[2], r[0]] as number[];
|
|
113
|
+
} else if (r.length !== 4) {
|
|
114
|
+
r = [r[0], r[0], r[0], r[0]] as number[];
|
|
115
|
+
}
|
|
116
|
+
} else if (typeof r === 'number') {
|
|
117
|
+
r = [r, r, r, r];
|
|
118
|
+
}
|
|
119
|
+
return r;
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
static override resolveDefaults(
|
|
125
|
+
props: HolePunchEffectProps,
|
|
126
|
+
): Required<HolePunchEffectProps> {
|
|
127
|
+
return {
|
|
128
|
+
x: props.x || 0,
|
|
129
|
+
y: props.y || 0,
|
|
130
|
+
width: props.width || 50,
|
|
131
|
+
height: props.height || 50,
|
|
132
|
+
radius: props.radius ?? 0,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
static override methods: Record<string, string> = {
|
|
137
|
+
fillMask: `
|
|
138
|
+
float function(float dist) {
|
|
139
|
+
return clamp(-dist, 0.0, 1.0);
|
|
140
|
+
}
|
|
141
|
+
`,
|
|
142
|
+
boxDist: `
|
|
143
|
+
float function(vec2 p, vec2 size, float radius) {
|
|
144
|
+
size -= vec2(radius);
|
|
145
|
+
vec2 d = abs(p) - size;
|
|
146
|
+
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0)) - radius;
|
|
147
|
+
}
|
|
148
|
+
`,
|
|
149
|
+
};
|
|
150
|
+
|
|
151
|
+
static override onShaderMask = `
|
|
152
|
+
vec2 halfDimensions = u_dimensions * 0.5;
|
|
153
|
+
vec2 size = vec2(width, height) * 0.5;
|
|
154
|
+
vec2 basePos = v_textureCoordinate.xy * u_dimensions.xy - vec2(x, y);
|
|
155
|
+
vec2 pos = basePos - size;
|
|
156
|
+
float r = radius[0] * step(pos.x, 0.5) * step(pos.y, 0.5);
|
|
157
|
+
r = r + radius[1] * step(0.5, pos.x) * step(pos.y, 0.5);
|
|
158
|
+
r = r + radius[2] * step(0.5, pos.x) * step(0.5, pos.y);
|
|
159
|
+
r = r + radius[3] * step(pos.x, 0.5) * step(0.5, pos.y);
|
|
160
|
+
return $boxDist(pos, size, r);
|
|
161
|
+
`;
|
|
162
|
+
|
|
163
|
+
static override onEffectMask = `
|
|
164
|
+
return mix(maskColor, vec4(0.0), $fillMask(shaderMask));
|
|
165
|
+
`;
|
|
166
|
+
}
|
|
@@ -235,6 +235,9 @@ export function layoutText(
|
|
|
235
235
|
);
|
|
236
236
|
curX = lastWord.xStart;
|
|
237
237
|
bufferOffset = lastWord.bufferOffset;
|
|
238
|
+
// HACK: For the rest of the line when inserting the overflow suffix,
|
|
239
|
+
// set contain = 'none' to prevent an infinite loop.
|
|
240
|
+
contain = 'none';
|
|
238
241
|
}
|
|
239
242
|
} else {
|
|
240
243
|
// This glyph fits, so we can add it to the buffer
|
package/src/main-api/INode.ts
CHANGED
|
@@ -72,6 +72,19 @@ export interface INodeWritableProps {
|
|
|
72
72
|
* @default `1`
|
|
73
73
|
*/
|
|
74
74
|
alpha: number;
|
|
75
|
+
/**
|
|
76
|
+
* Autosize mode
|
|
77
|
+
*
|
|
78
|
+
* @remarks
|
|
79
|
+
* When enabled, when a texture is loaded into the Node, the Node will
|
|
80
|
+
* automatically resize to the dimensions of the texture.
|
|
81
|
+
*
|
|
82
|
+
* Text Nodes are always autosized based on their text content regardless
|
|
83
|
+
* of this mode setting.
|
|
84
|
+
*
|
|
85
|
+
* @default `false`
|
|
86
|
+
*/
|
|
87
|
+
autosize: boolean;
|
|
75
88
|
/**
|
|
76
89
|
* Clipping Mode
|
|
77
90
|
*
|
|
@@ -260,6 +260,11 @@ export class Inspector {
|
|
|
260
260
|
): ITextNode {
|
|
261
261
|
const node = driver.createTextNode(properties);
|
|
262
262
|
const div = this.createDiv(node, properties);
|
|
263
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
264
|
+
(div as any).node = node;
|
|
265
|
+
|
|
266
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
|
|
267
|
+
(node as any).div = div;
|
|
263
268
|
return this.createProxy(node, div) as ITextNode;
|
|
264
269
|
}
|
|
265
270
|
|
|
@@ -534,6 +534,7 @@ export class RendererMain extends EventEmitter {
|
|
|
534
534
|
width: props.width ?? 0,
|
|
535
535
|
height: props.height ?? 0,
|
|
536
536
|
alpha: props.alpha ?? 1,
|
|
537
|
+
autosize: props.autosize ?? false,
|
|
537
538
|
clipping: props.clipping ?? false,
|
|
538
539
|
color,
|
|
539
540
|
colorTop: props.colorTop ?? color,
|
|
@@ -78,6 +78,7 @@ export class MainOnlyNode extends EventEmitter implements INode {
|
|
|
78
78
|
width: props.width,
|
|
79
79
|
height: props.height,
|
|
80
80
|
alpha: props.alpha,
|
|
81
|
+
autosize: props.autosize,
|
|
81
82
|
clipping: props.clipping,
|
|
82
83
|
color: props.color,
|
|
83
84
|
colorTop: props.colorTop,
|
|
@@ -163,6 +164,14 @@ export class MainOnlyNode extends EventEmitter implements INode {
|
|
|
163
164
|
this.coreNode.alpha = value;
|
|
164
165
|
}
|
|
165
166
|
|
|
167
|
+
get autosize(): boolean {
|
|
168
|
+
return this.coreNode.autosize;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
set autosize(value: boolean) {
|
|
172
|
+
this.coreNode.autosize = value;
|
|
173
|
+
}
|
|
174
|
+
|
|
166
175
|
get clipping(): boolean {
|
|
167
176
|
return this.coreNode.clipping;
|
|
168
177
|
}
|
|
@@ -25,6 +25,7 @@ export interface NodeStructWritableProps {
|
|
|
25
25
|
width: number;
|
|
26
26
|
height: number;
|
|
27
27
|
alpha: number;
|
|
28
|
+
autosize: boolean;
|
|
28
29
|
clipping: boolean;
|
|
29
30
|
color: number;
|
|
30
31
|
colorTop: number;
|
|
@@ -100,6 +101,15 @@ export class NodeStruct
|
|
|
100
101
|
// Decorator will handle this
|
|
101
102
|
}
|
|
102
103
|
|
|
104
|
+
@structProp('boolean')
|
|
105
|
+
get autosize(): boolean {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
set autosize(value: boolean) {
|
|
110
|
+
// Decorator will handle this
|
|
111
|
+
}
|
|
112
|
+
|
|
103
113
|
@structProp('boolean')
|
|
104
114
|
get clipping(): boolean {
|
|
105
115
|
return false;
|
|
@@ -40,6 +40,7 @@ export class SharedNode extends SharedObject {
|
|
|
40
40
|
width: sharedNodeStruct.width,
|
|
41
41
|
height: sharedNodeStruct.height,
|
|
42
42
|
alpha: sharedNodeStruct.alpha,
|
|
43
|
+
autosize: sharedNodeStruct.autosize,
|
|
43
44
|
clipping: sharedNodeStruct.clipping,
|
|
44
45
|
color: sharedNodeStruct.color,
|
|
45
46
|
colorTop: sharedNodeStruct.colorTop,
|
|
@@ -72,6 +73,7 @@ export class SharedNode extends SharedObject {
|
|
|
72
73
|
declare width: number;
|
|
73
74
|
declare height: number;
|
|
74
75
|
declare alpha: number;
|
|
76
|
+
declare autosize: boolean;
|
|
75
77
|
declare clipping: boolean;
|
|
76
78
|
declare color: number;
|
|
77
79
|
declare colorTop: number;
|
|
@@ -151,6 +151,7 @@ export class ThreadXCoreDriver implements ICoreDriver {
|
|
|
151
151
|
width: props.width,
|
|
152
152
|
height: props.height,
|
|
153
153
|
parentId: props.parent ? props.parent.id : 0,
|
|
154
|
+
autosize: props.autosize,
|
|
154
155
|
clipping: props.clipping,
|
|
155
156
|
color: props.color,
|
|
156
157
|
colorTop: props.colorTop,
|
|
@@ -208,6 +209,7 @@ export class ThreadXCoreDriver implements ICoreDriver {
|
|
|
208
209
|
colorBl: props.colorBl,
|
|
209
210
|
colorBr: props.colorBr,
|
|
210
211
|
alpha: props.alpha,
|
|
212
|
+
autosize: props.autosize,
|
|
211
213
|
zIndex: props.zIndex,
|
|
212
214
|
zIndexLocked: props.zIndexLocked,
|
|
213
215
|
scaleX: props.scaleX,
|
|
@@ -209,6 +209,7 @@ export class ThreadXRendererNode extends SharedNode {
|
|
|
209
209
|
width: sharedNodeStruct.width,
|
|
210
210
|
height: sharedNodeStruct.height,
|
|
211
211
|
alpha: sharedNodeStruct.alpha,
|
|
212
|
+
autosize: sharedNodeStruct.autosize,
|
|
212
213
|
clipping: sharedNodeStruct.clipping,
|
|
213
214
|
color: sharedNodeStruct.color,
|
|
214
215
|
colorTop: sharedNodeStruct.colorTop,
|
|
@@ -46,6 +46,7 @@ export class ThreadXRendererTextNode extends ThreadXRendererNode {
|
|
|
46
46
|
width: sharedNodeStruct.width,
|
|
47
47
|
height: sharedNodeStruct.height,
|
|
48
48
|
alpha: sharedNodeStruct.alpha,
|
|
49
|
+
autosize: sharedNodeStruct.autosize,
|
|
49
50
|
clipping: sharedNodeStruct.clipping,
|
|
50
51
|
color: sharedNodeStruct.color,
|
|
51
52
|
colorTop: sharedNodeStruct.colorTop,
|
package/src/utils.ts
CHANGED
|
@@ -206,6 +206,17 @@ export function deg2Rad(degrees: number): number {
|
|
|
206
206
|
return (degrees * Math.PI) / 180;
|
|
207
207
|
}
|
|
208
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Returns image aspect ratio
|
|
211
|
+
*
|
|
212
|
+
* @param width
|
|
213
|
+
* @param height
|
|
214
|
+
* @returns
|
|
215
|
+
*/
|
|
216
|
+
export function getImageAspectRatio(width: number, height: number): number {
|
|
217
|
+
return width / height;
|
|
218
|
+
}
|
|
219
|
+
|
|
209
220
|
/**
|
|
210
221
|
* Checks import.meta if env is production
|
|
211
222
|
*
|