@lightningjs/blits 1.45.0 → 2.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +0 -11
- package/README.md +0 -2
- package/index.d.ts +23 -86
- package/package.json +5 -24
- package/scripts/prepublishOnly.js +1 -4
- package/src/component/base/methods.js +16 -76
- package/src/component/base/utils.js +18 -4
- package/src/component/setup/props.js +37 -28
- package/src/component/setup/state.js +4 -4
- package/src/component.js +25 -16
- package/src/components/Circle.js +49 -7
- package/src/components/FPScounter.js +226 -88
- package/src/components/RouterView.js +50 -5
- package/src/components/Sprite.js +61 -20
- package/src/engines/L3/element.js +109 -86
- package/src/engines/L3/fontLoader.js +26 -31
- package/src/engines/L3/shaderLoader.js +56 -6
- package/src/focus.js +9 -9
- package/src/launch.js +1 -2
- package/src/lib/codegenerator/generator.js +117 -16
- package/src/lib/colors/colors.js +0 -1
- package/src/lib/lifecycle.js +3 -3
- package/src/lib/precompiler/precompiler.js +14 -23
- package/src/lib/reactivityguard/computedprops.js +1 -6
- package/src/lib/shaders/shaders.js +163 -0
- package/src/lib/symbols.js +8 -0
- package/src/lib/templateparser/parser.js +6 -2
- package/src/lib/utils.js +36 -0
- package/src/router/router.js +7 -7
- package/vite/blitsTips.js +57 -0
- package/vite/msdfGenerator.js +52 -6
- package/vite/preCompiler.js +5 -15
- package/vscode/data/template-attributes.json +112 -0
- package/src/plugins/appstate.d.ts +0 -29
- package/src/plugins/index.d.ts +0 -29
- package/src/plugins/language.d.ts +0 -34
- package/src/plugins/storage/storage.d.ts +0 -29
- package/src/plugins/theme.d.ts +0 -35
package/src/components/Sprite.js
CHANGED
|
@@ -25,6 +25,47 @@ export default () =>
|
|
|
25
25
|
code: {
|
|
26
26
|
render: function anonymous(parent, component, context, components, effect, getRaw, Log) {
|
|
27
27
|
const elms = []
|
|
28
|
+
const validAttributes = [
|
|
29
|
+
'parent',
|
|
30
|
+
'rotation',
|
|
31
|
+
'w',
|
|
32
|
+
'width',
|
|
33
|
+
'h',
|
|
34
|
+
'height',
|
|
35
|
+
'x',
|
|
36
|
+
'y',
|
|
37
|
+
'z',
|
|
38
|
+
'zIndex',
|
|
39
|
+
'color',
|
|
40
|
+
'src',
|
|
41
|
+
'texture',
|
|
42
|
+
'fit',
|
|
43
|
+
'rtt',
|
|
44
|
+
'mount',
|
|
45
|
+
'pivot',
|
|
46
|
+
'scale',
|
|
47
|
+
'show',
|
|
48
|
+
'alpha',
|
|
49
|
+
'rounded',
|
|
50
|
+
'border',
|
|
51
|
+
'shadow',
|
|
52
|
+
'shader',
|
|
53
|
+
'clipping',
|
|
54
|
+
'overflow',
|
|
55
|
+
'font',
|
|
56
|
+
'size',
|
|
57
|
+
'maxwidth',
|
|
58
|
+
'maxheight',
|
|
59
|
+
'maxlines',
|
|
60
|
+
'textoverflow',
|
|
61
|
+
'letterspacing',
|
|
62
|
+
'lineheight',
|
|
63
|
+
'contain',
|
|
64
|
+
'align',
|
|
65
|
+
'content',
|
|
66
|
+
'placement',
|
|
67
|
+
'inspector-data',
|
|
68
|
+
]
|
|
28
69
|
const elementConfigs = []
|
|
29
70
|
const forloops = []
|
|
30
71
|
const props = []
|
|
@@ -45,8 +86,8 @@ export default () =>
|
|
|
45
86
|
inSlot === true ? slotComponent : component
|
|
46
87
|
)
|
|
47
88
|
|
|
48
|
-
elementConfigs[0]['w'] = parent.node.
|
|
49
|
-
elementConfigs[0]['h'] = parent.node.
|
|
89
|
+
elementConfigs[0]['w'] = parent.node.w * (100 / 100)
|
|
90
|
+
elementConfigs[0]['h'] = parent.node.h * (100 / 100)
|
|
50
91
|
elementConfigs[0]['texture'] = component.texture
|
|
51
92
|
elementConfigs[0]['color'] = component.color
|
|
52
93
|
elementConfigs[0]['effects'] = component.effects
|
|
@@ -72,20 +113,25 @@ export default () =>
|
|
|
72
113
|
props.length = 0
|
|
73
114
|
skips.length = 0
|
|
74
115
|
},
|
|
116
|
+
skips,
|
|
75
117
|
}
|
|
76
118
|
},
|
|
77
119
|
effects: [
|
|
78
|
-
function anonymous(component, elms, context, components, rootComponent, effect) {
|
|
120
|
+
function anonymous(component, elms, context, components, rootComponent, skips, effect) {
|
|
79
121
|
elms[0].set('texture', component.texture)
|
|
80
122
|
},
|
|
81
|
-
function anonymous(component, elms, context, components, rootComponent, effect) {
|
|
123
|
+
function anonymous(component, elms, context, components, rootComponent, skips, effect) {
|
|
82
124
|
elms[0].set('color', component.color)
|
|
83
125
|
},
|
|
84
126
|
],
|
|
85
127
|
context: {},
|
|
86
128
|
},
|
|
87
|
-
props:
|
|
88
|
-
|
|
129
|
+
props: {
|
|
130
|
+
image: undefined,
|
|
131
|
+
map: undefined,
|
|
132
|
+
frame: undefined,
|
|
133
|
+
color: undefined,
|
|
134
|
+
},
|
|
89
135
|
state() {
|
|
90
136
|
return {
|
|
91
137
|
spriteTexture: null,
|
|
@@ -121,20 +167,15 @@ export default () =>
|
|
|
121
167
|
// Resolve frame data from sprite map
|
|
122
168
|
let options = null
|
|
123
169
|
if (
|
|
124
|
-
this.map !== null &&
|
|
125
170
|
this.map !== undefined &&
|
|
126
|
-
this.
|
|
127
|
-
this.frame !== undefined
|
|
171
|
+
this.map !== null &&
|
|
172
|
+
this.frame !== undefined &&
|
|
173
|
+
this.frame !== null
|
|
128
174
|
) {
|
|
129
|
-
|
|
130
|
-
this.map
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
) {
|
|
134
|
-
options = Object.assign({}, this.map.defaults || {}, this.map.frames[this.frame])
|
|
135
|
-
} else if (this.frame in this.map) {
|
|
136
|
-
options = this.map[this.frame]
|
|
137
|
-
}
|
|
175
|
+
options =
|
|
176
|
+
'frames' in this.map
|
|
177
|
+
? Object.assign({}, this.map.defaults || {}, this.map.frames[this.frame])
|
|
178
|
+
: this.map[this.frame]
|
|
138
179
|
}
|
|
139
180
|
|
|
140
181
|
// If no map but frame is object (manual subtexture)
|
|
@@ -148,8 +189,8 @@ export default () =>
|
|
|
148
189
|
texture: this.spriteTexture,
|
|
149
190
|
x: options.x,
|
|
150
191
|
y: options.y,
|
|
151
|
-
|
|
152
|
-
|
|
192
|
+
w: options.w,
|
|
193
|
+
h: options.h,
|
|
153
194
|
})
|
|
154
195
|
}
|
|
155
196
|
|
|
@@ -16,11 +16,13 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { renderer } from './launch.js'
|
|
19
|
+
import { parseToObject, isObjectString, isArrayString, isTransition } from '../../lib/utils.js'
|
|
19
20
|
import colors from '../../lib/colors/colors.js'
|
|
20
21
|
|
|
21
22
|
import { Log } from '../../lib/log.js'
|
|
22
23
|
import symbols from '../../lib/symbols.js'
|
|
23
24
|
import Settings from '../../settings.js'
|
|
25
|
+
import shaders from '../../lib/shaders/shaders.js'
|
|
24
26
|
|
|
25
27
|
/**
|
|
26
28
|
* Creates a padding object from a value and direction.
|
|
@@ -79,8 +81,8 @@ const layoutFn = function (config) {
|
|
|
79
81
|
const position = config.direction === 'vertical' ? 'y' : 'x'
|
|
80
82
|
const oppositePosition = config.direction === 'vertical' ? 'x' : 'y'
|
|
81
83
|
const oppositeMount = config.direction === 'vertical' ? 'mountX' : 'mountY'
|
|
82
|
-
const dimension = config.direction === 'vertical' ? '
|
|
83
|
-
const oppositeDimension = config.direction === 'vertical' ? '
|
|
84
|
+
const dimension = config.direction === 'vertical' ? 'h' : 'w'
|
|
85
|
+
const oppositeDimension = config.direction === 'vertical' ? 'w' : 'h'
|
|
84
86
|
const padding = createPaddingObject(config.padding, config.direction)
|
|
85
87
|
|
|
86
88
|
let offset = padding.start
|
|
@@ -98,17 +100,10 @@ const layoutFn = function (config) {
|
|
|
98
100
|
node[position] = offset
|
|
99
101
|
node[oppositePosition] = padding.oppositeStart
|
|
100
102
|
// todo: temporary text check, due to 1px width of empty text node
|
|
101
|
-
if (dimension === '
|
|
102
|
-
offset += node.
|
|
103
|
+
if (dimension === 'w') {
|
|
104
|
+
offset += node.w + (node.w !== ('text' in node ? 1 : 0) ? gap : 0)
|
|
103
105
|
} else {
|
|
104
|
-
offset +=
|
|
105
|
-
'text' in node
|
|
106
|
-
? node.width > 1
|
|
107
|
-
? node.height + gap
|
|
108
|
-
: 0
|
|
109
|
-
: node.height !== 0
|
|
110
|
-
? node.height + gap
|
|
111
|
-
: 0
|
|
106
|
+
offset += 'text' in node ? (node.w > 1 ? node.h + gap : 0) : node.h !== 0 ? node.h + gap : 0
|
|
112
107
|
}
|
|
113
108
|
otherDimension = Math.max(
|
|
114
109
|
otherDimension,
|
|
@@ -135,7 +130,7 @@ const layoutFn = function (config) {
|
|
|
135
130
|
|
|
136
131
|
// emit an updated event
|
|
137
132
|
if (config['@updated'] !== undefined) {
|
|
138
|
-
config['@updated']({ w: this.node.
|
|
133
|
+
config['@updated']({ w: this.node.w, h: this.node.h }, this)
|
|
139
134
|
}
|
|
140
135
|
|
|
141
136
|
// trigger layout on parent if parent is a layout
|
|
@@ -144,33 +139,6 @@ const layoutFn = function (config) {
|
|
|
144
139
|
}
|
|
145
140
|
}
|
|
146
141
|
|
|
147
|
-
/**
|
|
148
|
-
* Checks if a value is a transition object.
|
|
149
|
-
* @param {any} value - The value to check.
|
|
150
|
-
* @returns {boolean} True if the value is a transition object, false otherwise.
|
|
151
|
-
*/
|
|
152
|
-
const isTransition = (value) => {
|
|
153
|
-
return value !== null && typeof value === 'object' && 'transition' in value === true
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Checks if a string is an object string (starts and ends with curly braces).
|
|
158
|
-
* @param {string} str - The string to check.
|
|
159
|
-
* @returns {boolean} True if the string is an object string, false otherwise.
|
|
160
|
-
*/
|
|
161
|
-
const isObjectString = (str) => {
|
|
162
|
-
return typeof str === 'string' && str.startsWith('{') && str.endsWith('}')
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
/**
|
|
166
|
-
* Parses a string into an object, converting single quotes to double and adding quotes to keys.
|
|
167
|
-
* @param {string} str - The string to parse.
|
|
168
|
-
* @returns {object} The parsed object.
|
|
169
|
-
*/
|
|
170
|
-
const parseToObject = (str) => {
|
|
171
|
-
return JSON.parse(str.replace(/'/g, '"').replace(/([{,]\s*)([\w-_]+)(\s*:)/g, '$1"$2"$3'))
|
|
172
|
-
}
|
|
173
|
-
|
|
174
142
|
/**
|
|
175
143
|
* Parses a percentage string or returns the value as-is.
|
|
176
144
|
* @param {string|number} v - The value to parse (may be a percentage string).
|
|
@@ -242,22 +210,24 @@ const propsTransformer = {
|
|
|
242
210
|
this.props['rotation'] = v * (Math.PI / 180)
|
|
243
211
|
},
|
|
244
212
|
set w(v) {
|
|
245
|
-
|
|
213
|
+
if (v < 0) v = 0
|
|
214
|
+
this.props['w'] = parsePercentage.call(this, v, 'w')
|
|
246
215
|
},
|
|
247
216
|
set width(v) {
|
|
248
|
-
this.
|
|
217
|
+
this.w = v
|
|
249
218
|
},
|
|
250
219
|
set h(v) {
|
|
251
|
-
|
|
220
|
+
if (v < 0) v = 0
|
|
221
|
+
this.props['h'] = parsePercentage.call(this, v, 'h')
|
|
252
222
|
},
|
|
253
223
|
set height(v) {
|
|
254
|
-
this.
|
|
224
|
+
this.h = v
|
|
255
225
|
},
|
|
256
226
|
set x(v) {
|
|
257
|
-
this.props['x'] = parsePercentage.call(this, v, '
|
|
227
|
+
this.props['x'] = parsePercentage.call(this, v, 'w')
|
|
258
228
|
},
|
|
259
229
|
set y(v) {
|
|
260
|
-
this.props['y'] = parsePercentage.call(this, v, '
|
|
230
|
+
this.props['y'] = parsePercentage.call(this, v, 'h')
|
|
261
231
|
},
|
|
262
232
|
set z(v) {
|
|
263
233
|
this.props['zIndex'] = v
|
|
@@ -287,7 +257,7 @@ const propsTransformer = {
|
|
|
287
257
|
this.props['color'] = this.props['src'] ? 0xffffffff : 0x00000000
|
|
288
258
|
}
|
|
289
259
|
// apply auto sizing when no width or height specified
|
|
290
|
-
if (!('w' in this.raw) && !('
|
|
260
|
+
if (!('w' in this.raw) && !('h' in this.raw)) {
|
|
291
261
|
this.props['autosize'] = true
|
|
292
262
|
}
|
|
293
263
|
},
|
|
@@ -379,37 +349,68 @@ const propsTransformer = {
|
|
|
379
349
|
this.props['alpha'] = v
|
|
380
350
|
}
|
|
381
351
|
},
|
|
352
|
+
set rounded(v) {
|
|
353
|
+
this.props['rounded'] = v
|
|
354
|
+
if (this.element.node !== undefined && this.elementShader === true) {
|
|
355
|
+
if (typeof v === 'object' || (isObjectString(v) === true && (v = parseToObject(v)))) {
|
|
356
|
+
this.element.node.props['shader'].props = v
|
|
357
|
+
} else {
|
|
358
|
+
if (isArrayString(v) === true) {
|
|
359
|
+
v = JSON.parse(v)
|
|
360
|
+
}
|
|
361
|
+
this.element.node.props['shader'].props.radius = v
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
},
|
|
365
|
+
set border(v) {
|
|
366
|
+
this.props['border'] = v
|
|
367
|
+
if (
|
|
368
|
+
this.element.node !== undefined &&
|
|
369
|
+
this.elementShader === true &&
|
|
370
|
+
(typeof v === 'object' || isObjectString(v) === true)
|
|
371
|
+
) {
|
|
372
|
+
v = shaders.parseProps(v)
|
|
373
|
+
for (const key in v) {
|
|
374
|
+
this.element.node.props['shader'].props[`border-${key}`] = v[key]
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
set shadow(v) {
|
|
379
|
+
this.props['shadow'] = v
|
|
380
|
+
if (
|
|
381
|
+
this.element.node !== undefined &&
|
|
382
|
+
this.elementShader === true &&
|
|
383
|
+
(typeof v === 'object' || isObjectString(v) === true)
|
|
384
|
+
) {
|
|
385
|
+
v = shaders.parseProps(v)
|
|
386
|
+
for (const key in v) {
|
|
387
|
+
this.element.node.props['shader'].props[`shadow-${key}`] = v[key]
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
},
|
|
382
391
|
set shader(v) {
|
|
392
|
+
let type = v
|
|
393
|
+
if (typeof v === 'object' || (isObjectString(v) === true && (v = parseToObject(v)))) {
|
|
394
|
+
type = v.type
|
|
395
|
+
v = shaders.parseProps(v)
|
|
396
|
+
}
|
|
383
397
|
const target = this.element.node !== undefined ? this.element.node : this.props
|
|
384
|
-
|
|
385
|
-
if (v ===
|
|
386
|
-
target['shader'] =
|
|
398
|
+
//if v remains a string we can change shader types
|
|
399
|
+
if (typeof v === 'string') {
|
|
400
|
+
target['shader'] = renderer.createShader(type)
|
|
387
401
|
return
|
|
388
402
|
}
|
|
389
403
|
|
|
390
|
-
if
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
}
|
|
404
|
+
//check again if v is an object since it could have been an object string
|
|
405
|
+
if (typeof v === 'object') {
|
|
406
|
+
if (target.shader !== undefined && type === target.shader.shaderKey) {
|
|
407
|
+
target['shader'].props = v
|
|
395
408
|
return
|
|
396
409
|
}
|
|
397
|
-
target['shader'] = renderer.createShader(
|
|
398
|
-
|
|
399
|
-
},
|
|
400
|
-
set effects(v) {
|
|
401
|
-
for (let i = 0; i < v.length; i++) {
|
|
402
|
-
if (v[i].props && v[i].props.color) {
|
|
403
|
-
v[i].props.color = colors.normalize(v[i].props.color)
|
|
404
|
-
}
|
|
405
|
-
}
|
|
406
|
-
if (this.element.node === undefined) {
|
|
407
|
-
this.props['shader'] = renderer.createShader('DynamicShader', {
|
|
408
|
-
effects: v.map((effect) => {
|
|
409
|
-
return renderer.createEffect(effect.type, effect.props)
|
|
410
|
-
}),
|
|
411
|
-
})
|
|
410
|
+
target['shader'] = renderer.createShader(type, v)
|
|
411
|
+
return
|
|
412
412
|
}
|
|
413
|
+
target['shader'] = renderer.createShader('DefaultShader')
|
|
413
414
|
},
|
|
414
415
|
set clipping(v) {
|
|
415
416
|
this.props['clipping'] = v
|
|
@@ -423,21 +424,27 @@ const propsTransformer = {
|
|
|
423
424
|
set size(v) {
|
|
424
425
|
this.props['fontSize'] = v
|
|
425
426
|
},
|
|
426
|
-
set wordwrap(v) {
|
|
427
|
-
Log.warn('The wordwrap attribute is deprecated, use maxwidth instead')
|
|
428
|
-
this.props['width'] = v
|
|
429
|
-
this.props['contain'] = 'width'
|
|
430
|
-
},
|
|
431
427
|
set maxwidth(v) {
|
|
432
|
-
this.props['
|
|
428
|
+
this.props['maxWidth'] = v
|
|
429
|
+
if (this.manualTextContain === true) {
|
|
430
|
+
return
|
|
431
|
+
}
|
|
432
|
+
if (this.props['contain'] === 'height') {
|
|
433
|
+
this.props['contain'] = 'both'
|
|
434
|
+
return
|
|
435
|
+
}
|
|
433
436
|
this.props['contain'] = 'width'
|
|
434
437
|
},
|
|
435
438
|
set maxheight(v) {
|
|
436
|
-
this.props['
|
|
437
|
-
this.
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
this.props['contain']
|
|
439
|
+
this.props['maxHeight'] = v
|
|
440
|
+
if (this.manualTextContain === true) {
|
|
441
|
+
return
|
|
442
|
+
}
|
|
443
|
+
if (this.props['contain'] === 'width') {
|
|
444
|
+
this.props['contain'] = 'both'
|
|
445
|
+
return
|
|
446
|
+
}
|
|
447
|
+
this.props['contain'] = 'height'
|
|
441
448
|
},
|
|
442
449
|
set maxlines(v) {
|
|
443
450
|
this.props['maxLines'] = v
|
|
@@ -451,6 +458,10 @@ const propsTransformer = {
|
|
|
451
458
|
set lineheight(v) {
|
|
452
459
|
this.props['lineHeight'] = v
|
|
453
460
|
},
|
|
461
|
+
set contain(v) {
|
|
462
|
+
this.props['contain'] = v
|
|
463
|
+
this.manualTextContain = true
|
|
464
|
+
},
|
|
454
465
|
set align(v) {
|
|
455
466
|
this.props['textAlign'] = v
|
|
456
467
|
},
|
|
@@ -500,13 +511,14 @@ const propsTransformer = {
|
|
|
500
511
|
},
|
|
501
512
|
}
|
|
502
513
|
|
|
514
|
+
export const elementAttributes = Object.keys(propsTransformer)
|
|
515
|
+
|
|
503
516
|
const Element = {
|
|
504
517
|
/**
|
|
505
518
|
* Populates the element with data
|
|
506
|
-
* @param {import('../../component.js').BlitsElementProps}
|
|
519
|
+
* @param {import('../../component.js').BlitsElementProps} props
|
|
507
520
|
*/
|
|
508
|
-
populate(
|
|
509
|
-
const props = data
|
|
521
|
+
populate(props) {
|
|
510
522
|
props['node'] = this.config.node
|
|
511
523
|
|
|
512
524
|
if (props[symbols.isSlot] === true) {
|
|
@@ -519,11 +531,22 @@ const Element = {
|
|
|
519
531
|
//@ts-ignore This might be a left over from the old code?
|
|
520
532
|
delete props.parent
|
|
521
533
|
|
|
522
|
-
this.props.raw =
|
|
534
|
+
this.props.raw = props
|
|
535
|
+
this.props.elementShader = false
|
|
523
536
|
|
|
524
537
|
const propKeys = Object.keys(props)
|
|
525
538
|
const length = propKeys.length
|
|
526
539
|
|
|
540
|
+
if (
|
|
541
|
+
props['shader'] === undefined &&
|
|
542
|
+
(props['rounded'] !== undefined ||
|
|
543
|
+
props['border'] !== undefined ||
|
|
544
|
+
props['shadow'] !== undefined)
|
|
545
|
+
) {
|
|
546
|
+
this.props.elementShader = true
|
|
547
|
+
this.props.props['shader'] = shaders.createElementShader(props)
|
|
548
|
+
}
|
|
549
|
+
|
|
527
550
|
for (let i = 0; i < length; i++) {
|
|
528
551
|
const key = propKeys[i]
|
|
529
552
|
const value = props[key]
|
|
@@ -543,7 +566,7 @@ const Element = {
|
|
|
543
566
|
|
|
544
567
|
if (props['@loaded'] !== undefined && typeof props['@loaded'] === 'function') {
|
|
545
568
|
this.node.on('loaded', (el, { type, dimensions }) => {
|
|
546
|
-
props['@loaded']({ w: dimensions.
|
|
569
|
+
props['@loaded']({ w: dimensions.w, h: dimensions.h, type }, this)
|
|
547
570
|
})
|
|
548
571
|
}
|
|
549
572
|
|
|
@@ -1,38 +1,33 @@
|
|
|
1
|
-
import { SdfTrFontFace, WebTrFontFace } from '@lightningjs/renderer'
|
|
2
1
|
import Settings from '../../settings.js'
|
|
3
2
|
import { renderer } from './launch.js'
|
|
4
3
|
|
|
4
|
+
const fontTypeMapping = {
|
|
5
|
+
sdf: 'sdf',
|
|
6
|
+
msdf: 'sdf',
|
|
7
|
+
canvas: 'canvas',
|
|
8
|
+
web: 'canvas',
|
|
9
|
+
}
|
|
10
|
+
|
|
5
11
|
export default () => {
|
|
6
12
|
const stage = renderer.stage
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
})
|
|
26
|
-
)
|
|
27
|
-
} else if (font.type === 'web') {
|
|
28
|
-
stage.fontManager.addFontFace(
|
|
29
|
-
new WebTrFontFace({
|
|
30
|
-
fontFamily: font.family,
|
|
31
|
-
fontUrl: font.file,
|
|
32
|
-
descriptors: {},
|
|
33
|
-
metrics: font.metrics,
|
|
34
|
-
})
|
|
35
|
-
)
|
|
13
|
+
|
|
14
|
+
const fonts = Settings.get('fonts', [])
|
|
15
|
+
for (let i = 0; i < fonts.length; i++) {
|
|
16
|
+
const font = fonts[i]
|
|
17
|
+
const type = fontTypeMapping[font.type] || 'sdf'
|
|
18
|
+
|
|
19
|
+
if (type === 'sdf') {
|
|
20
|
+
stage.loadFont('sdf', {
|
|
21
|
+
fontFamily: font.family,
|
|
22
|
+
atlasUrl: font.json || (font.file && font.file.replace(/\.[^.]+$/, `.${font.type}.png`)),
|
|
23
|
+
atlasDataUrl:
|
|
24
|
+
font.json || (font.file && font.file.replace(/\.[^.]+$/, `.${font.type}.json`)),
|
|
25
|
+
})
|
|
26
|
+
} else {
|
|
27
|
+
stage.loadFont('canvas', {
|
|
28
|
+
fontFamily: font.family,
|
|
29
|
+
fontUrl: font.file,
|
|
30
|
+
})
|
|
36
31
|
}
|
|
37
|
-
}
|
|
32
|
+
}
|
|
38
33
|
}
|
|
@@ -1,12 +1,62 @@
|
|
|
1
1
|
import Settings from '../../settings.js'
|
|
2
2
|
import { renderer } from './launch.js'
|
|
3
|
+
import * as webglShaders from '@lightningjs/renderer/webgl/shaders'
|
|
4
|
+
import * as canvasShaders from '@lightningjs/renderer/canvas/shaders'
|
|
5
|
+
|
|
6
|
+
function registerBlitsDefaultShaders(
|
|
7
|
+
shManager,
|
|
8
|
+
Rounded,
|
|
9
|
+
Border,
|
|
10
|
+
Shadow,
|
|
11
|
+
RoundedWithBorder,
|
|
12
|
+
RoundedWithShadow,
|
|
13
|
+
RoundedWithBorderAndShadow,
|
|
14
|
+
HolePunch,
|
|
15
|
+
RadialGradient,
|
|
16
|
+
LinearGradient
|
|
17
|
+
) {
|
|
18
|
+
shManager.registerShaderType('rounded', Rounded)
|
|
19
|
+
shManager.registerShaderType('border', Border)
|
|
20
|
+
shManager.registerShaderType('shadow', Shadow)
|
|
21
|
+
shManager.registerShaderType('roundedWithBorder', RoundedWithBorder)
|
|
22
|
+
shManager.registerShaderType('roundedWithShadow', RoundedWithShadow)
|
|
23
|
+
shManager.registerShaderType('roundedWithBorderAndShadow', RoundedWithBorderAndShadow)
|
|
24
|
+
shManager.registerShaderType('holePunch', HolePunch)
|
|
25
|
+
shManager.registerShaderType('radialGradient', RadialGradient)
|
|
26
|
+
shManager.registerShaderType('linearGradient', LinearGradient)
|
|
27
|
+
}
|
|
3
28
|
|
|
4
29
|
export default () => {
|
|
5
30
|
const stage = renderer.stage
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
31
|
+
|
|
32
|
+
const {
|
|
33
|
+
Rounded,
|
|
34
|
+
Border,
|
|
35
|
+
Shadow,
|
|
36
|
+
RoundedWithBorder,
|
|
37
|
+
RoundedWithShadow,
|
|
38
|
+
RoundedWithBorderAndShadow,
|
|
39
|
+
HolePunch,
|
|
40
|
+
RadialGradient,
|
|
41
|
+
LinearGradient,
|
|
42
|
+
} = Settings.get('renderMode', 'webgl') === 'webgl' ? webglShaders : canvasShaders
|
|
43
|
+
|
|
44
|
+
registerBlitsDefaultShaders(
|
|
45
|
+
stage.shManager,
|
|
46
|
+
Rounded,
|
|
47
|
+
Border,
|
|
48
|
+
Shadow,
|
|
49
|
+
RoundedWithBorder,
|
|
50
|
+
RoundedWithShadow,
|
|
51
|
+
RoundedWithBorderAndShadow,
|
|
52
|
+
HolePunch,
|
|
53
|
+
RadialGradient,
|
|
54
|
+
LinearGradient
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
const shaders = Settings.get('shaders', [])
|
|
58
|
+
const len = shaders.length
|
|
59
|
+
for (let i = 0; i < len; i++) {
|
|
60
|
+
stage.shManager.registerShaderType(shaders[i].name, shaders[i].type)
|
|
61
|
+
}
|
|
12
62
|
}
|
package/src/focus.js
CHANGED
|
@@ -50,7 +50,7 @@ export default {
|
|
|
50
50
|
|
|
51
51
|
// unfocus currently focused components
|
|
52
52
|
if (focusedComponent !== null) {
|
|
53
|
-
if (focusChain[focusChain.length - 1] === component.parent) {
|
|
53
|
+
if (focusChain[focusChain.length - 1] === component[symbols.parent]) {
|
|
54
54
|
focusChain.push(component)
|
|
55
55
|
} else {
|
|
56
56
|
const newFocusChain = getAncestors([component])
|
|
@@ -58,7 +58,7 @@ export default {
|
|
|
58
58
|
while (i--) {
|
|
59
59
|
// don't unfocus when part of the new focus chain
|
|
60
60
|
if (newFocusChain.indexOf(focusChain[i]) > -1) break
|
|
61
|
-
focusChain[i].lifecycle.state = 'unfocus'
|
|
61
|
+
focusChain[i][symbols.lifecycle].state = 'unfocus'
|
|
62
62
|
}
|
|
63
63
|
focusChain = newFocusChain
|
|
64
64
|
}
|
|
@@ -67,7 +67,7 @@ export default {
|
|
|
67
67
|
// ensure that all components in the focus path have focus state
|
|
68
68
|
let i = 0
|
|
69
69
|
while (i < focusChain.length - 1) {
|
|
70
|
-
focusChain[i].lifecycle.state = 'focus'
|
|
70
|
+
focusChain[i][symbols.lifecycle].state = 'focus'
|
|
71
71
|
i++
|
|
72
72
|
}
|
|
73
73
|
|
|
@@ -105,8 +105,8 @@ export default {
|
|
|
105
105
|
* @returns array components
|
|
106
106
|
*/
|
|
107
107
|
const getAncestors = (components) => {
|
|
108
|
-
if (components[0].parent !== undefined) {
|
|
109
|
-
components.unshift(components[0].parent)
|
|
108
|
+
if (components[0][symbols.parent] !== undefined) {
|
|
109
|
+
components.unshift(components[0][symbols.parent])
|
|
110
110
|
return getAncestors(components)
|
|
111
111
|
}
|
|
112
112
|
return components
|
|
@@ -125,8 +125,8 @@ export const getComponentWithInputEvent = (component, key) => {
|
|
|
125
125
|
typeof component[symbols.inputEvents].any === 'function')
|
|
126
126
|
) {
|
|
127
127
|
return component
|
|
128
|
-
} else if (component.parent !== undefined) {
|
|
129
|
-
return getComponentWithInputEvent(component.parent, key)
|
|
128
|
+
} else if (component[symbols.parent] !== undefined) {
|
|
129
|
+
return getComponentWithInputEvent(component[symbols.parent], key)
|
|
130
130
|
} else return null
|
|
131
131
|
}
|
|
132
132
|
|
|
@@ -138,11 +138,11 @@ export const getComponentWithInputEvent = (component, key) => {
|
|
|
138
138
|
const setFocus = (component, event) => {
|
|
139
139
|
Log.info(
|
|
140
140
|
'\nFocus chain:\n',
|
|
141
|
-
focusChain.map((c, index) => '\t'.repeat(index) + '↳ ' + c
|
|
141
|
+
focusChain.map((c, index) => '\t'.repeat(index) + '↳ ' + c.$componentId).join('\n')
|
|
142
142
|
)
|
|
143
143
|
|
|
144
144
|
focusedComponent = component
|
|
145
|
-
component.lifecycle.state = 'focus'
|
|
145
|
+
component[symbols.lifecycle].state = 'focus'
|
|
146
146
|
|
|
147
147
|
if (event instanceof KeyboardEvent) {
|
|
148
148
|
const internalEvent = new KeyboardEvent('keydown', event)
|
package/src/launch.js
CHANGED
|
@@ -41,9 +41,8 @@ import blitsPackageInfo from '../package.json' with { type: 'json' }
|
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* @typedef {import('@lightningjs/renderer').RendererMain} RendererMain
|
|
44
|
-
* @type {RendererMain}
|
|
44
|
+
* @type {RendererMain | {}}
|
|
45
45
|
*/
|
|
46
|
-
// @ts-ignore - We ignore this because it will be replaced by the renderer once the app is launched
|
|
47
46
|
export let renderer = {}
|
|
48
47
|
export const stage = {}
|
|
49
48
|
|