@lightningtv/solid 3.0.0-2 → 3.0.0-21
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/LICENSE +1 -1
- package/README.md +6 -0
- package/dist/src/activeElement.d.ts +1 -1
- package/dist/src/core/animation.d.ts +35 -0
- package/dist/src/core/animation.js +120 -0
- package/dist/src/core/animation.js.map +1 -0
- package/dist/src/core/config.d.ts +47 -0
- package/dist/src/core/config.js +23 -0
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/core/domRenderer.d.ts +117 -0
- package/dist/src/core/domRenderer.js +1160 -0
- package/dist/src/core/domRenderer.js.map +1 -0
- package/dist/src/core/elementNode.d.ts +209 -0
- package/dist/src/core/elementNode.js +829 -0
- package/dist/src/core/elementNode.js.map +1 -0
- package/dist/src/core/flex.d.ts +2 -0
- package/dist/src/core/flex.js +243 -0
- package/dist/src/core/flex.js.map +1 -0
- package/dist/src/core/focusKeyTypes.d.ts +42 -0
- package/dist/src/core/focusKeyTypes.js +2 -0
- package/dist/src/core/focusKeyTypes.js.map +1 -0
- package/dist/src/core/focusManager.d.ts +13 -0
- package/dist/src/core/focusManager.js +269 -0
- package/dist/src/core/focusManager.js.map +1 -0
- package/dist/src/core/index.d.ts +12 -0
- package/dist/src/core/index.js +12 -0
- package/dist/src/core/index.js.map +1 -0
- package/dist/src/core/intrinsicTypes.d.ts +90 -0
- package/dist/src/core/intrinsicTypes.js +2 -0
- package/dist/src/core/intrinsicTypes.js.map +1 -0
- package/dist/src/core/lightningInit.d.ts +89 -0
- package/dist/src/core/lightningInit.js +26 -0
- package/dist/src/core/lightningInit.js.map +1 -0
- package/dist/src/core/nodeTypes.d.ts +6 -0
- package/dist/src/core/nodeTypes.js +6 -0
- package/dist/src/core/nodeTypes.js.map +1 -0
- package/dist/src/core/shaders.d.ts +51 -0
- package/dist/src/core/shaders.js +446 -0
- package/dist/src/core/shaders.js.map +1 -0
- package/dist/src/core/states.d.ts +12 -0
- package/dist/src/core/states.js +84 -0
- package/dist/src/core/states.js.map +1 -0
- package/dist/src/core/timings.d.ts +36 -0
- package/dist/src/core/timings.js +199 -0
- package/dist/src/core/timings.js.map +1 -0
- package/dist/src/core/utils.d.ts +39 -0
- package/dist/src/core/utils.js +164 -0
- package/dist/src/core/utils.js.map +1 -0
- package/dist/src/devtools/index.d.ts +1 -1
- package/dist/src/devtools/index.js +1 -1
- package/dist/src/devtools/index.js.map +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/jsx-runtime.d.ts +1 -3
- package/dist/src/primitives/Column.jsx +9 -10
- package/dist/src/primitives/Column.jsx.map +1 -1
- package/dist/src/primitives/FPSCounter.jsx +14 -1
- package/dist/src/primitives/FPSCounter.jsx.map +1 -1
- package/dist/src/primitives/Grid.d.ts +15 -6
- package/dist/src/primitives/Grid.jsx +35 -22
- package/dist/src/primitives/Grid.jsx.map +1 -1
- package/dist/src/primitives/Image.d.ts +8 -0
- package/dist/src/primitives/Image.jsx +24 -0
- package/dist/src/primitives/Image.jsx.map +1 -0
- package/dist/src/primitives/KeepAlive.d.ts +30 -0
- package/dist/src/primitives/KeepAlive.jsx +77 -0
- package/dist/src/primitives/KeepAlive.jsx.map +1 -0
- package/dist/src/primitives/Lazy.d.ts +8 -7
- package/dist/src/primitives/Lazy.jsx +52 -23
- package/dist/src/primitives/Lazy.jsx.map +1 -1
- package/dist/src/primitives/Marquee.d.ts +64 -0
- package/dist/src/primitives/Marquee.jsx +86 -0
- package/dist/src/primitives/Marquee.jsx.map +1 -0
- package/dist/src/primitives/Preserve.d.ts +4 -0
- package/dist/src/primitives/Preserve.jsx +11 -0
- package/dist/src/primitives/Preserve.jsx.map +1 -0
- package/dist/src/primitives/Row.jsx +9 -10
- package/dist/src/primitives/Row.jsx.map +1 -1
- package/dist/src/primitives/Suspense.d.ts +22 -0
- package/dist/src/primitives/Suspense.jsx +33 -0
- package/dist/src/primitives/Suspense.jsx.map +1 -0
- package/dist/src/primitives/Virtual.d.ts +18 -0
- package/dist/src/primitives/Virtual.jsx +434 -0
- package/dist/src/primitives/Virtual.jsx.map +1 -0
- package/dist/src/primitives/VirtualGrid.d.ts +13 -0
- package/dist/src/primitives/VirtualGrid.jsx +160 -0
- package/dist/src/primitives/VirtualGrid.jsx.map +1 -0
- package/dist/src/primitives/VirtualList.d.ts +11 -0
- package/dist/src/primitives/VirtualList.jsx +96 -0
- package/dist/src/primitives/VirtualList.jsx.map +1 -0
- package/dist/src/primitives/VirtualRow.d.ts +13 -0
- package/dist/src/primitives/VirtualRow.jsx +97 -0
- package/dist/src/primitives/VirtualRow.jsx.map +1 -0
- package/dist/src/primitives/Visible.d.ts +0 -1
- package/dist/src/primitives/Visible.jsx +1 -1
- package/dist/src/primitives/Visible.jsx.map +1 -1
- package/dist/src/primitives/announcer/announcer.d.ts +2 -0
- package/dist/src/primitives/announcer/announcer.js +7 -5
- package/dist/src/primitives/announcer/announcer.js.map +1 -1
- package/dist/src/primitives/announcer/index.d.ts +5 -1
- package/dist/src/primitives/announcer/index.js +8 -2
- package/dist/src/primitives/announcer/index.js.map +1 -1
- package/dist/src/primitives/announcer/speech.d.ts +2 -2
- package/dist/src/primitives/announcer/speech.js +157 -28
- package/dist/src/primitives/announcer/speech.js.map +1 -1
- package/dist/src/primitives/createFocusStack.d.ts +4 -4
- package/dist/src/primitives/createFocusStack.jsx +15 -6
- package/dist/src/primitives/createFocusStack.jsx.map +1 -1
- package/dist/src/primitives/createTag.d.ts +8 -0
- package/dist/src/primitives/createTag.jsx +20 -0
- package/dist/src/primitives/createTag.jsx.map +1 -0
- package/dist/src/primitives/index.d.ts +14 -4
- package/dist/src/primitives/index.js +13 -3
- package/dist/src/primitives/index.js.map +1 -1
- package/dist/src/primitives/types.d.ts +5 -2
- package/dist/src/primitives/useFocusManager.d.ts +2 -2
- package/dist/src/primitives/useFocusManager.js +2 -2
- package/dist/src/primitives/useFocusManager.js.map +1 -1
- package/dist/src/primitives/useHold.d.ts +27 -0
- package/dist/src/primitives/useHold.js +54 -0
- package/dist/src/primitives/useHold.js.map +1 -0
- package/dist/src/primitives/useMouse.d.ts +18 -2
- package/dist/src/primitives/useMouse.js +171 -47
- package/dist/src/primitives/useMouse.js.map +1 -1
- package/dist/src/primitives/utils/chainFunctions.d.ts +30 -4
- package/dist/src/primitives/utils/chainFunctions.js +14 -3
- package/dist/src/primitives/utils/chainFunctions.js.map +1 -1
- package/dist/src/primitives/utils/createBlurredImage.d.ts +56 -0
- package/dist/src/primitives/utils/createBlurredImage.js +223 -0
- package/dist/src/primitives/utils/createBlurredImage.js.map +1 -0
- package/dist/src/primitives/utils/createSpriteMap.d.ts +2 -2
- package/dist/src/primitives/utils/createSpriteMap.js +1 -1
- package/dist/src/primitives/utils/createSpriteMap.js.map +1 -1
- package/dist/src/primitives/utils/handleNavigation.d.ts +79 -5
- package/dist/src/primitives/utils/handleNavigation.js +242 -69
- package/dist/src/primitives/utils/handleNavigation.js.map +1 -1
- package/dist/src/primitives/utils/withScrolling.d.ts +14 -2
- package/dist/src/primitives/utils/withScrolling.js +66 -7
- package/dist/src/primitives/utils/withScrolling.js.map +1 -1
- package/dist/src/render.d.ts +8 -7
- package/dist/src/render.js +5 -1
- package/dist/src/render.js.map +1 -1
- package/dist/src/solidOpts.d.ts +1 -7
- package/dist/src/solidOpts.js +32 -16
- package/dist/src/solidOpts.js.map +1 -1
- package/dist/src/types.d.ts +1 -13
- package/dist/src/universal.d.ts +25 -0
- package/dist/src/universal.js +232 -0
- package/dist/src/universal.js.map +1 -0
- package/dist/src/utils.d.ts +3 -1
- package/dist/src/utils.js +9 -1
- package/dist/src/utils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/jsx-runtime.d.ts +2 -4
- package/package.json +17 -15
- package/src/activeElement.ts +1 -1
- package/src/core/animation.ts +183 -0
- package/src/core/config.ts +77 -0
- package/src/core/domRenderer.ts +1308 -0
- package/src/core/elementNode.ts +1198 -0
- package/src/core/flex.ts +284 -0
- package/src/core/focusKeyTypes.ts +87 -0
- package/src/core/focusManager.ts +359 -0
- package/src/core/index.ts +13 -0
- package/src/core/intrinsicTypes.ts +199 -0
- package/src/core/lightningInit.ts +147 -0
- package/src/core/nodeTypes.ts +6 -0
- package/src/core/shaders.ts +567 -0
- package/src/core/states.ts +91 -0
- package/src/core/timings.ts +261 -0
- package/src/core/utils.ts +222 -0
- package/src/devtools/index.ts +1 -1
- package/src/index.ts +3 -3
- package/src/primitives/Column.tsx +10 -12
- package/src/primitives/FPSCounter.tsx +15 -1
- package/src/primitives/Grid.tsx +57 -33
- package/src/primitives/Image.tsx +36 -0
- package/src/primitives/KeepAlive.tsx +124 -0
- package/src/primitives/Lazy.tsx +66 -37
- package/src/primitives/Marquee.tsx +149 -0
- package/src/primitives/Preserve.tsx +18 -0
- package/src/primitives/Row.tsx +13 -14
- package/src/primitives/Suspense.tsx +39 -0
- package/src/primitives/Virtual.tsx +478 -0
- package/src/primitives/VirtualGrid.tsx +220 -0
- package/src/primitives/Visible.tsx +1 -2
- package/src/primitives/announcer/announcer.ts +16 -10
- package/src/primitives/announcer/index.ts +12 -2
- package/src/primitives/announcer/speech.ts +188 -27
- package/src/primitives/createFocusStack.tsx +18 -7
- package/src/primitives/createTag.tsx +31 -0
- package/src/primitives/index.ts +18 -4
- package/src/primitives/types.ts +12 -2
- package/src/primitives/useFocusManager.ts +3 -3
- package/src/primitives/useHold.ts +69 -0
- package/src/primitives/useMouse.ts +306 -67
- package/src/primitives/utils/chainFunctions.ts +40 -9
- package/src/primitives/utils/createBlurredImage.ts +366 -0
- package/src/primitives/utils/createSpriteMap.ts +6 -4
- package/src/primitives/utils/handleNavigation.ts +300 -84
- package/src/primitives/utils/withScrolling.ts +91 -18
- package/src/render.ts +10 -8
- package/src/solidOpts.ts +31 -24
- package/src/types.ts +1 -15
- package/src/utils.ts +11 -1
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import { Config, isDev } from './config.js';
|
|
2
|
+
export type * from './focusKeyTypes.js';
|
|
3
|
+
import { ElementNode } from './elementNode.js';
|
|
4
|
+
import type {
|
|
5
|
+
KeyNameOrKeyCode,
|
|
6
|
+
KeyHoldOptions,
|
|
7
|
+
KeyMap,
|
|
8
|
+
} from './focusKeyTypes.js';
|
|
9
|
+
import { isFunction } from './utils.js';
|
|
10
|
+
|
|
11
|
+
const keyMapEntries: Record<KeyNameOrKeyCode, string> = {
|
|
12
|
+
ArrowLeft: 'Left',
|
|
13
|
+
ArrowRight: 'Right',
|
|
14
|
+
ArrowUp: 'Up',
|
|
15
|
+
ArrowDown: 'Down',
|
|
16
|
+
Enter: 'Enter',
|
|
17
|
+
l: 'Last',
|
|
18
|
+
' ': 'Space',
|
|
19
|
+
Backspace: 'Back',
|
|
20
|
+
Escape: 'Escape',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const keyHoldMapEntries: Record<KeyNameOrKeyCode, string> = {
|
|
24
|
+
// Enter: 'EnterHold',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const flattenKeyMap = (keyMap: any, targetMap: any): void => {
|
|
28
|
+
for (const [key, value] of Object.entries(keyMap)) {
|
|
29
|
+
if (Array.isArray(value)) {
|
|
30
|
+
value.forEach((v) => {
|
|
31
|
+
targetMap[v] = key;
|
|
32
|
+
});
|
|
33
|
+
} else if (value === null) {
|
|
34
|
+
delete targetMap[key];
|
|
35
|
+
} else {
|
|
36
|
+
targetMap[value as keyof any] = key;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
let needFocusDebugStyles = true;
|
|
42
|
+
const addFocusDebug = (
|
|
43
|
+
prevFocusPath: ElementNode[],
|
|
44
|
+
newFocusPath: ElementNode[],
|
|
45
|
+
) => {
|
|
46
|
+
if (needFocusDebugStyles) {
|
|
47
|
+
const style = document.createElement('style');
|
|
48
|
+
style.type = 'text/css';
|
|
49
|
+
style.innerHTML = `
|
|
50
|
+
[data-focus="3"] {
|
|
51
|
+
border: 2px solid rgba(255, 33, 33, 0.2);
|
|
52
|
+
border-radius: 5px;
|
|
53
|
+
transition: border-color 0.3s ease;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
[data-focus="2"] {
|
|
57
|
+
border: 2px solid rgba(255, 33, 33, 0.4);
|
|
58
|
+
border-radius: 5px;
|
|
59
|
+
transition: border-color 0.3s ease;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
[data-focus="1"] {
|
|
63
|
+
border: 4px solid rgba(255, 33, 33, 0.9);
|
|
64
|
+
border-radius: 5px;
|
|
65
|
+
transition: border-color 0.5s ease;
|
|
66
|
+
}
|
|
67
|
+
`;
|
|
68
|
+
document.head.appendChild(style);
|
|
69
|
+
needFocusDebugStyles = false;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
prevFocusPath.forEach((elm) => {
|
|
73
|
+
elm.data = {
|
|
74
|
+
...elm.data,
|
|
75
|
+
focus: undefined,
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
newFocusPath.forEach((elm, i) => {
|
|
80
|
+
elm.data = {
|
|
81
|
+
...elm.data,
|
|
82
|
+
focus: i + 1,
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
let activeElement: ElementNode | undefined;
|
|
88
|
+
export const setActiveElement = (elm: ElementNode) => {
|
|
89
|
+
updateFocusPath(elm, activeElement);
|
|
90
|
+
activeElement = elm;
|
|
91
|
+
// Callback for libraries to use signals / refs
|
|
92
|
+
Config.setActiveElement(elm);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
let focusPath: ElementNode[] = [];
|
|
96
|
+
const updateFocusPath = (
|
|
97
|
+
currentFocusedElm: ElementNode,
|
|
98
|
+
prevFocusedElm: ElementNode | undefined,
|
|
99
|
+
) => {
|
|
100
|
+
let current = currentFocusedElm;
|
|
101
|
+
const fp: ElementNode[] = [];
|
|
102
|
+
while (current) {
|
|
103
|
+
if (
|
|
104
|
+
!current.states.has(Config.focusStateKey) ||
|
|
105
|
+
current === currentFocusedElm
|
|
106
|
+
) {
|
|
107
|
+
current.states.add(Config.focusStateKey);
|
|
108
|
+
current.onFocus?.call(current, currentFocusedElm, prevFocusedElm);
|
|
109
|
+
current.onFocusChanged?.call(
|
|
110
|
+
current,
|
|
111
|
+
true,
|
|
112
|
+
currentFocusedElm,
|
|
113
|
+
prevFocusedElm,
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
fp.push(current);
|
|
117
|
+
current = current.parent!;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
focusPath.forEach((elm) => {
|
|
121
|
+
if (!fp.includes(elm)) {
|
|
122
|
+
elm.states.remove(Config.focusStateKey);
|
|
123
|
+
elm.onBlur?.call(elm, currentFocusedElm, prevFocusedElm!);
|
|
124
|
+
elm.onFocusChanged?.call(elm, false, currentFocusedElm, prevFocusedElm);
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
if (Config.focusDebug) {
|
|
129
|
+
addFocusDebug(focusPath, fp);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
focusPath = fp;
|
|
133
|
+
return fp;
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
let lastGlobalKeyPressTime = 0;
|
|
137
|
+
|
|
138
|
+
const propagateKeyPress = (
|
|
139
|
+
e: KeyboardEvent,
|
|
140
|
+
mappedEvent?: string,
|
|
141
|
+
isHold: boolean = false,
|
|
142
|
+
isUp: boolean = false,
|
|
143
|
+
): boolean => {
|
|
144
|
+
const currentTime = performance.now();
|
|
145
|
+
if (!isUp && Config.throttleInput) {
|
|
146
|
+
if (currentTime - lastGlobalKeyPressTime < Config.throttleInput) {
|
|
147
|
+
if (isDev && Config.keyDebug) {
|
|
148
|
+
console.log(
|
|
149
|
+
`Keypress throttled by global Config.throttleInput: ${Config.throttleInput}ms`,
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
lastGlobalKeyPressTime = currentTime;
|
|
155
|
+
}
|
|
156
|
+
let finalFocusElm: ElementNode | undefined;
|
|
157
|
+
let handlerAvailable: ElementNode | undefined;
|
|
158
|
+
const numItems = focusPath.length;
|
|
159
|
+
const captureEvent =
|
|
160
|
+
`onCapture${mappedEvent || e.key}` + isUp ? 'Release' : '';
|
|
161
|
+
const captureKey = isUp ? 'onCaptureKeyRelease' : 'onCaptureKey';
|
|
162
|
+
|
|
163
|
+
for (let i = numItems - 1; i >= 0; i--) {
|
|
164
|
+
const elm = focusPath[i]!;
|
|
165
|
+
|
|
166
|
+
// Check throttle for capture phase
|
|
167
|
+
if (elm.throttleInput) {
|
|
168
|
+
if (
|
|
169
|
+
elm._lastAnyKeyPressTime !== undefined &&
|
|
170
|
+
currentTime - elm._lastAnyKeyPressTime < elm.throttleInput
|
|
171
|
+
) {
|
|
172
|
+
return true;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const captureHandler = elm[captureEvent] || elm[captureKey];
|
|
177
|
+
if (
|
|
178
|
+
isFunction(captureHandler) &&
|
|
179
|
+
captureHandler.call(elm, e, elm, finalFocusElm, mappedEvent) === true
|
|
180
|
+
) {
|
|
181
|
+
elm._lastAnyKeyPressTime = currentTime;
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
let eventHandlerKey: string | undefined;
|
|
187
|
+
let releaseEventHandlerKey: string | undefined;
|
|
188
|
+
let fallbackHandlerKey: 'onKeyHold' | 'onKeyPress' | undefined;
|
|
189
|
+
|
|
190
|
+
if (mappedEvent) {
|
|
191
|
+
eventHandlerKey = `on${mappedEvent}`;
|
|
192
|
+
releaseEventHandlerKey = `on${mappedEvent}Release`;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (!isUp) {
|
|
196
|
+
fallbackHandlerKey = isHold ? 'onKeyHold' : 'onKeyPress';
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
for (let i = 0; i < numItems; i++) {
|
|
200
|
+
const elm = focusPath[i]!;
|
|
201
|
+
if (!finalFocusElm) {
|
|
202
|
+
finalFocusElm = elm;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Check throttle for bubbling phase
|
|
206
|
+
if (elm.throttleInput) {
|
|
207
|
+
if (
|
|
208
|
+
elm._lastAnyKeyPressTime !== undefined &&
|
|
209
|
+
currentTime - elm._lastAnyKeyPressTime < elm.throttleInput
|
|
210
|
+
) {
|
|
211
|
+
return true;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
let handled = false;
|
|
216
|
+
|
|
217
|
+
// Check for the release event handler if isUp is true and the key is defined
|
|
218
|
+
if (isUp && releaseEventHandlerKey) {
|
|
219
|
+
const eventHandler = elm[releaseEventHandlerKey];
|
|
220
|
+
if (isFunction(eventHandler)) {
|
|
221
|
+
handlerAvailable = elm;
|
|
222
|
+
if (eventHandler.call(elm, e, elm, finalFocusElm) === true)
|
|
223
|
+
handled = true;
|
|
224
|
+
}
|
|
225
|
+
} else if (!isUp && eventHandlerKey) {
|
|
226
|
+
// Check for the regular event handler if isUp is false and the key is defined
|
|
227
|
+
const eventHandler = elm[eventHandlerKey];
|
|
228
|
+
if (isFunction(eventHandler)) {
|
|
229
|
+
handlerAvailable = elm;
|
|
230
|
+
if (eventHandler.call(elm, e, elm, finalFocusElm) === true)
|
|
231
|
+
handled = true;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Check for the fallback handler if its key is defined and not already handled by specific key handler
|
|
236
|
+
if (!handled && fallbackHandlerKey) {
|
|
237
|
+
const fallbackHandler = elm[fallbackHandlerKey];
|
|
238
|
+
if (isFunction(fallbackHandler)) {
|
|
239
|
+
handlerAvailable = elm;
|
|
240
|
+
if (
|
|
241
|
+
fallbackHandler.call(elm, e, mappedEvent, elm, finalFocusElm) === true
|
|
242
|
+
)
|
|
243
|
+
handled = true;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
if (handled) {
|
|
248
|
+
elm._lastAnyKeyPressTime = currentTime;
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (isDev && Config.keyDebug && !isUp) {
|
|
254
|
+
if (handlerAvailable) {
|
|
255
|
+
console.log(
|
|
256
|
+
`Keypress bubbled, key="${e.key}", mappedEvent=${mappedEvent}, isHold=${isHold}, isUp=${isUp}`,
|
|
257
|
+
handlerAvailable,
|
|
258
|
+
);
|
|
259
|
+
} else {
|
|
260
|
+
console.log(
|
|
261
|
+
`No event handler available for keypress: key="${e.key}", mappedEvent=${mappedEvent}, isHold=${isHold}, isUp=${isUp}`,
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return false;
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
const DEFAULT_KEY_HOLD_THRESHOLD = 500; // ms
|
|
270
|
+
const keyHoldTimeouts: { [key: KeyNameOrKeyCode]: number | true } = {};
|
|
271
|
+
|
|
272
|
+
const handleKeyEvents = (
|
|
273
|
+
delay: number,
|
|
274
|
+
keydown?: KeyboardEvent,
|
|
275
|
+
keyup?: KeyboardEvent,
|
|
276
|
+
) => {
|
|
277
|
+
if (keydown) {
|
|
278
|
+
const key: KeyNameOrKeyCode = keydown.key || keydown.keyCode;
|
|
279
|
+
const mappedKeyHoldEvent =
|
|
280
|
+
keyHoldMapEntries[keydown.key] || keyHoldMapEntries[keydown.keyCode];
|
|
281
|
+
const mappedKeyEvent =
|
|
282
|
+
keyMapEntries[keydown.key] || keyMapEntries[keydown.keyCode];
|
|
283
|
+
if (mappedKeyHoldEvent) {
|
|
284
|
+
if (!keyHoldTimeouts[key]) {
|
|
285
|
+
keyHoldTimeouts[key] = window.setTimeout(() => {
|
|
286
|
+
keyHoldTimeouts[key] = true;
|
|
287
|
+
propagateKeyPress(keydown, mappedKeyHoldEvent, true);
|
|
288
|
+
}, delay);
|
|
289
|
+
}
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
propagateKeyPress(keydown, mappedKeyEvent, false);
|
|
294
|
+
} else if (keyup) {
|
|
295
|
+
const key: KeyNameOrKeyCode = keyup.key || keyup.keyCode;
|
|
296
|
+
const mappedKeyEvent =
|
|
297
|
+
keyMapEntries[keyup.key] || keyMapEntries[keyup.keyCode];
|
|
298
|
+
if (keyHoldTimeouts[key] === true) {
|
|
299
|
+
delete keyHoldTimeouts[key];
|
|
300
|
+
} else if (keyHoldTimeouts[key]) {
|
|
301
|
+
clearTimeout(keyHoldTimeouts[key]);
|
|
302
|
+
delete keyHoldTimeouts[key];
|
|
303
|
+
// trigger key down event when hold didn't finish
|
|
304
|
+
propagateKeyPress(keyup, mappedKeyEvent, false);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
propagateKeyPress(keyup, mappedKeyEvent, false, true);
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
interface FocusManagerOptions {
|
|
312
|
+
userKeyMap?: Partial<KeyMap>;
|
|
313
|
+
keyHoldOptions?: KeyHoldOptions;
|
|
314
|
+
ownerContext?: (cb: () => void) => void;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
export const useFocusManager = ({
|
|
318
|
+
userKeyMap,
|
|
319
|
+
keyHoldOptions,
|
|
320
|
+
ownerContext = (cb) => {
|
|
321
|
+
cb();
|
|
322
|
+
},
|
|
323
|
+
}: FocusManagerOptions = {}) => {
|
|
324
|
+
if (userKeyMap) {
|
|
325
|
+
flattenKeyMap(userKeyMap, keyMapEntries);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (keyHoldOptions?.userKeyHoldMap) {
|
|
329
|
+
flattenKeyMap(keyHoldOptions.userKeyHoldMap, keyHoldMapEntries);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const delay = keyHoldOptions?.holdThreshold || DEFAULT_KEY_HOLD_THRESHOLD;
|
|
333
|
+
const runKeyEvent = handleKeyEvents.bind(null, delay);
|
|
334
|
+
|
|
335
|
+
// Owner context is for frameworks that need effects
|
|
336
|
+
const keyPressHandler = (event: KeyboardEvent) =>
|
|
337
|
+
ownerContext(() => {
|
|
338
|
+
runKeyEvent(event, undefined);
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
const keyUpHandler = (event: KeyboardEvent) =>
|
|
342
|
+
ownerContext(() => {
|
|
343
|
+
runKeyEvent(undefined, event);
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
document.addEventListener('keyup', keyUpHandler);
|
|
347
|
+
document.addEventListener('keydown', keyPressHandler);
|
|
348
|
+
|
|
349
|
+
return {
|
|
350
|
+
cleanup: () => {
|
|
351
|
+
document.removeEventListener('keydown', keyPressHandler);
|
|
352
|
+
document.removeEventListener('keyup', keyUpHandler);
|
|
353
|
+
for (const [_, timeout] of Object.entries(keyHoldTimeouts)) {
|
|
354
|
+
if (timeout && timeout !== true) clearTimeout(timeout);
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
focusPath: () => focusPath,
|
|
358
|
+
};
|
|
359
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export * from './elementNode.js';
|
|
2
|
+
export * from './lightningInit.js';
|
|
3
|
+
export * from './nodeTypes.js';
|
|
4
|
+
export * from './utils.js';
|
|
5
|
+
export * from './intrinsicTypes.js';
|
|
6
|
+
export * from './focusKeyTypes.js';
|
|
7
|
+
export * from './config.js';
|
|
8
|
+
export * from './shaders.js';
|
|
9
|
+
export type * from '@lightningjs/renderer';
|
|
10
|
+
export { type AnimationSettings } from './intrinsicTypes.js';
|
|
11
|
+
// hopefully fix up webpack error
|
|
12
|
+
import { assertTruthy, deg2Rad } from '@lightningjs/renderer/utils';
|
|
13
|
+
export { assertTruthy, deg2Rad };
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import * as lngr from '@lightningjs/renderer';
|
|
2
|
+
import { ElementNode, type RendererNode } from './elementNode.js';
|
|
3
|
+
import { NodeStates } from './states.js';
|
|
4
|
+
import {
|
|
5
|
+
ShaderBorderProps,
|
|
6
|
+
ShaderHolePunchProps,
|
|
7
|
+
ShaderLinearGradientProps,
|
|
8
|
+
ShaderRadialGradientProps,
|
|
9
|
+
ShaderRoundedProps,
|
|
10
|
+
ShaderShadowProps,
|
|
11
|
+
} from './shaders.js';
|
|
12
|
+
import {
|
|
13
|
+
EventHandlers,
|
|
14
|
+
DefaultKeyMap,
|
|
15
|
+
KeyHoldMap,
|
|
16
|
+
FocusNode,
|
|
17
|
+
} from './focusKeyTypes.js';
|
|
18
|
+
import type { JSXElement } from 'solid-js';
|
|
19
|
+
|
|
20
|
+
export type AnimationSettings = Partial<lngr.AnimationSettings>;
|
|
21
|
+
|
|
22
|
+
export type AddColorString<T> = {
|
|
23
|
+
[K in keyof T]: K extends `color${string}` ? string | number : T[K];
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export interface BorderStyleObject {
|
|
27
|
+
width: number;
|
|
28
|
+
color: number | string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type DollarString = `$${string}`;
|
|
32
|
+
export type BorderStyle = BorderStyleObject;
|
|
33
|
+
export type BorderRadius = number | number[];
|
|
34
|
+
|
|
35
|
+
export interface Effects {
|
|
36
|
+
linearGradient?: Partial<ShaderLinearGradientProps>;
|
|
37
|
+
radialGradient?: Partial<ShaderRadialGradientProps>;
|
|
38
|
+
holePunch?: Partial<ShaderHolePunchProps>;
|
|
39
|
+
shadow?: Partial<ShaderShadowProps>;
|
|
40
|
+
rounded?: Partial<ShaderRoundedProps>;
|
|
41
|
+
borderRadius?: Partial<BorderRadius>;
|
|
42
|
+
border?: Partial<ShaderBorderProps>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export type StyleEffects = Effects;
|
|
46
|
+
|
|
47
|
+
export type NewOmit<T, K extends PropertyKey> = {
|
|
48
|
+
[P in keyof T as Exclude<P, K>]: T[P];
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export type RemoveUnderscoreProps<T> = {
|
|
52
|
+
[K in keyof T as K extends `_${string}` ? never : K]: T[K];
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
type RendererText = AddColorString<
|
|
56
|
+
Partial<Omit<lngr.ITextNodeProps, 'debug' | 'shader' | 'parent'>>
|
|
57
|
+
>;
|
|
58
|
+
|
|
59
|
+
type CleanElementNode = NewOmit<
|
|
60
|
+
RemoveUnderscoreProps<ElementNode>,
|
|
61
|
+
| 'parent'
|
|
62
|
+
| 'insertChild'
|
|
63
|
+
| 'removeChild'
|
|
64
|
+
| 'selectedNode'
|
|
65
|
+
| 'shader'
|
|
66
|
+
| 'animate'
|
|
67
|
+
| 'chain'
|
|
68
|
+
| 'start'
|
|
69
|
+
| 'isTextNode'
|
|
70
|
+
| 'getText'
|
|
71
|
+
| 'destroy'
|
|
72
|
+
| 'hasChildren'
|
|
73
|
+
| 'getChildById'
|
|
74
|
+
| 'searchChildrenById'
|
|
75
|
+
| 'states'
|
|
76
|
+
| 'requiresLayout'
|
|
77
|
+
| 'updateLayout'
|
|
78
|
+
| 'render'
|
|
79
|
+
| 'style'
|
|
80
|
+
>;
|
|
81
|
+
/** Node text, children of a ElementNode of type TextNode */
|
|
82
|
+
export interface ElementText
|
|
83
|
+
extends NewOmit<
|
|
84
|
+
ElementNode,
|
|
85
|
+
'_type' | 'parent' | 'children' | 'src' | 'scale'
|
|
86
|
+
>,
|
|
87
|
+
NewOmit<RendererText, 'x' | 'y' | 'w' | 'h'> {
|
|
88
|
+
_type: 'textNode';
|
|
89
|
+
parent?: ElementNode;
|
|
90
|
+
children: TextNode[];
|
|
91
|
+
text: string;
|
|
92
|
+
style: TextStyles;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export interface TextNode {
|
|
96
|
+
_type: 'text';
|
|
97
|
+
parent?: ElementText;
|
|
98
|
+
text: string;
|
|
99
|
+
[key: string]: any;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export interface NodeProps
|
|
103
|
+
extends RendererNode,
|
|
104
|
+
EventHandlers<DefaultKeyMap>,
|
|
105
|
+
EventHandlers<KeyHoldMap>,
|
|
106
|
+
FocusNode,
|
|
107
|
+
Partial<
|
|
108
|
+
NewOmit<
|
|
109
|
+
CleanElementNode,
|
|
110
|
+
| 'children'
|
|
111
|
+
| 'text'
|
|
112
|
+
| 'lng'
|
|
113
|
+
| 'rendered'
|
|
114
|
+
| 'renderer'
|
|
115
|
+
| 'emit'
|
|
116
|
+
| 'preFlexwidth'
|
|
117
|
+
| 'preFlexHeight'
|
|
118
|
+
>
|
|
119
|
+
> {
|
|
120
|
+
states?: NodeStates;
|
|
121
|
+
style?: NodeStyles;
|
|
122
|
+
children?: JSXElement | undefined;
|
|
123
|
+
}
|
|
124
|
+
export interface NodeStyles extends NewOmit<NodeProps, 'style'> {
|
|
125
|
+
[key: `$${string}`]: NodeProps;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export interface TextProps
|
|
129
|
+
extends RendererText,
|
|
130
|
+
Partial<
|
|
131
|
+
NewOmit<
|
|
132
|
+
CleanElementNode,
|
|
133
|
+
| 'lng'
|
|
134
|
+
| 'rendered'
|
|
135
|
+
| 'renderer'
|
|
136
|
+
| 'alignItems'
|
|
137
|
+
| 'autosize'
|
|
138
|
+
| 'children'
|
|
139
|
+
| 'data'
|
|
140
|
+
| 'direction'
|
|
141
|
+
| 'display'
|
|
142
|
+
| 'flexBoundary'
|
|
143
|
+
| 'flexDirection'
|
|
144
|
+
| 'gap'
|
|
145
|
+
| 'justifyContent'
|
|
146
|
+
| 'forwardFocus'
|
|
147
|
+
| 'forwardStates'
|
|
148
|
+
| 'linearGradient'
|
|
149
|
+
| 'src'
|
|
150
|
+
| 'scale'
|
|
151
|
+
| 'texture'
|
|
152
|
+
| 'textureOptions'
|
|
153
|
+
>
|
|
154
|
+
> {
|
|
155
|
+
states?: NodeStates;
|
|
156
|
+
fontWeight?: number | string;
|
|
157
|
+
style?: TextStyles;
|
|
158
|
+
children?: string | string[] | undefined;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export interface TextStyles extends NewOmit<TextProps, 'style'> {
|
|
162
|
+
[key: `$${string}`]: TextProps;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
export type Styles = NodeStyles | TextStyles;
|
|
166
|
+
|
|
167
|
+
// TODO: deprecated
|
|
168
|
+
export interface IntrinsicNodeProps extends NodeProps {}
|
|
169
|
+
export interface IntrinsicNodeStyleProps extends NodeStyles {}
|
|
170
|
+
export interface IntrinsicTextNodeStyleProps extends TextStyles {}
|
|
171
|
+
|
|
172
|
+
export type AnimationEvents = 'animating' | 'tick' | 'stopped';
|
|
173
|
+
export type AnimationEventHandler = (
|
|
174
|
+
controller: lngr.IAnimationController,
|
|
175
|
+
name: string,
|
|
176
|
+
endValue: number,
|
|
177
|
+
props?: any,
|
|
178
|
+
) => void;
|
|
179
|
+
|
|
180
|
+
type EventPayloadMap = {
|
|
181
|
+
loaded: lngr.NodeLoadedPayload;
|
|
182
|
+
failed: lngr.NodeFailedPayload;
|
|
183
|
+
freed: Event;
|
|
184
|
+
inBounds: Event;
|
|
185
|
+
outOfBounds: Event;
|
|
186
|
+
inViewport: Event;
|
|
187
|
+
outOfViewport: Event;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
type NodeEvents = keyof EventPayloadMap;
|
|
191
|
+
|
|
192
|
+
type EventHandler<E extends NodeEvents> = (
|
|
193
|
+
target: ElementNode,
|
|
194
|
+
event?: EventPayloadMap[E],
|
|
195
|
+
) => void;
|
|
196
|
+
|
|
197
|
+
export type OnEvent = Partial<{
|
|
198
|
+
[K in NodeEvents]: EventHandler<K>;
|
|
199
|
+
}>;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import * as lng from '@lightningjs/renderer';
|
|
2
|
+
import { DOMRendererMain } from './domRenderer.js';
|
|
3
|
+
import { DOM_RENDERING } from './config.js';
|
|
4
|
+
import {
|
|
5
|
+
ShaderBorderPrefixedProps,
|
|
6
|
+
ShaderHolePunchProps,
|
|
7
|
+
ShaderLinearGradientProps,
|
|
8
|
+
ShaderRadialGradientProps,
|
|
9
|
+
ShaderRoundedProps,
|
|
10
|
+
ShaderShadowPrefixedProps,
|
|
11
|
+
} from './shaders.js';
|
|
12
|
+
|
|
13
|
+
export type SdfFontType = 'ssdf' | 'msdf';
|
|
14
|
+
|
|
15
|
+
/** Based on {@link lng.CoreRenderer} */
|
|
16
|
+
export interface IRendererCoreRenderer {
|
|
17
|
+
mode: 'canvas' | 'webgl' | undefined;
|
|
18
|
+
}
|
|
19
|
+
/** Based on {@link lng.TrFontManager} */
|
|
20
|
+
export interface IRendererFontManager {
|
|
21
|
+
addFontFace: (...a: any[]) => void;
|
|
22
|
+
}
|
|
23
|
+
/** Based on {@link lng.Stage} */
|
|
24
|
+
export interface IRendererStage {
|
|
25
|
+
root: IRendererNode;
|
|
26
|
+
renderer: IRendererCoreRenderer;
|
|
27
|
+
shManager: IRendererShaderManager;
|
|
28
|
+
animationManager: {
|
|
29
|
+
registerAnimation: (anim: any) => void;
|
|
30
|
+
unregisterAnimation: (anim: any) => void;
|
|
31
|
+
};
|
|
32
|
+
loadFont(kind: string, props: any): Promise<void>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** Based on {@link lng.CoreShaderManager} */
|
|
36
|
+
export interface IRendererShaderManager {
|
|
37
|
+
registerShaderType: (name: string, shader: any) => void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Based on {@link lng.CoreShaderNode} */
|
|
41
|
+
export interface IRendererShader {
|
|
42
|
+
shaderType: IRendererShaderType;
|
|
43
|
+
props?: IRendererShaderProps;
|
|
44
|
+
program?: {};
|
|
45
|
+
}
|
|
46
|
+
/** Based on {@link lng.CoreShaderType} */
|
|
47
|
+
export interface IRendererShaderType {}
|
|
48
|
+
export type IRendererShaderProps = Partial<ShaderBorderPrefixedProps> &
|
|
49
|
+
Partial<ShaderShadowPrefixedProps> &
|
|
50
|
+
Partial<ShaderRoundedProps> &
|
|
51
|
+
Partial<ShaderHolePunchProps> &
|
|
52
|
+
Partial<ShaderRadialGradientProps> &
|
|
53
|
+
Partial<ShaderLinearGradientProps>;
|
|
54
|
+
|
|
55
|
+
/** Based on {@link lng.Texture} */
|
|
56
|
+
export interface IRendererTexture {
|
|
57
|
+
props: IRendererTextureProps;
|
|
58
|
+
type: lng.TextureType;
|
|
59
|
+
}
|
|
60
|
+
export interface IRendererTextureProps {}
|
|
61
|
+
|
|
62
|
+
export interface IEventEmitter {
|
|
63
|
+
on: (e: string, cb: (...a: any[]) => void) => void;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface IRendererNodeShaded extends IEventEmitter {
|
|
67
|
+
stage: IRendererStage;
|
|
68
|
+
id: number;
|
|
69
|
+
animate: (
|
|
70
|
+
props: Partial<lng.INodeAnimateProps<any>>,
|
|
71
|
+
settings: Partial<lng.AnimationSettings>,
|
|
72
|
+
) => lng.IAnimationController;
|
|
73
|
+
get absX(): number;
|
|
74
|
+
get absY(): number;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Based on {@link lng.INodeProps} */
|
|
78
|
+
export interface IRendererNodeProps
|
|
79
|
+
extends Omit<lng.INodeProps<lng.CoreShaderNode>, 'shader' | 'parent'> {
|
|
80
|
+
shader: IRendererShader | null;
|
|
81
|
+
parent: IRendererNode | null;
|
|
82
|
+
}
|
|
83
|
+
/** Based on {@link lng.INode} */
|
|
84
|
+
export interface IRendererNode extends IRendererNodeShaded, IRendererNodeProps {
|
|
85
|
+
div?: HTMLElement;
|
|
86
|
+
props: IRendererNodeProps;
|
|
87
|
+
renderState: lng.CoreNodeRenderState;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Based on {@link lng.ITextNodeProps} */
|
|
91
|
+
export interface IRendererTextNodeProps
|
|
92
|
+
extends Omit<lng.ITextNodeProps, 'shader' | 'parent'> {
|
|
93
|
+
shader: IRendererShader | null;
|
|
94
|
+
parent: IRendererNode | null;
|
|
95
|
+
fontWeight?: string;
|
|
96
|
+
}
|
|
97
|
+
/** Based on {@link lng.ITextNode} */
|
|
98
|
+
export interface IRendererTextNode
|
|
99
|
+
extends IRendererNodeShaded,
|
|
100
|
+
IRendererTextNodeProps {
|
|
101
|
+
div?: HTMLElement;
|
|
102
|
+
props: IRendererTextNodeProps;
|
|
103
|
+
renderState: lng.CoreNodeRenderState;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** Based on {@link lng.RendererMain} */
|
|
107
|
+
export interface IRendererMain extends IEventEmitter {
|
|
108
|
+
stage: IRendererStage;
|
|
109
|
+
root: IRendererNode;
|
|
110
|
+
createTextNode(props: Partial<IRendererTextNodeProps>): IRendererTextNode;
|
|
111
|
+
createNode(props: Partial<IRendererNodeProps>): IRendererNode;
|
|
112
|
+
createShader(kind: string, props: IRendererShaderProps): IRendererShader;
|
|
113
|
+
createTexture(
|
|
114
|
+
kind: keyof lng.TextureMap,
|
|
115
|
+
props: IRendererTextureProps,
|
|
116
|
+
): IRendererTexture;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export let renderer: IRendererMain;
|
|
120
|
+
|
|
121
|
+
export const getRenderer = () => renderer;
|
|
122
|
+
|
|
123
|
+
export function startLightningRenderer(
|
|
124
|
+
options: lng.RendererMainSettings,
|
|
125
|
+
rootId: string | HTMLElement = 'app',
|
|
126
|
+
) {
|
|
127
|
+
renderer = DOM_RENDERING
|
|
128
|
+
? new DOMRendererMain(options, rootId)
|
|
129
|
+
: (new lng.RendererMain(options, rootId) as any as IRendererMain);
|
|
130
|
+
return renderer;
|
|
131
|
+
}
|
|
132
|
+
export function loadFonts(fonts: any[]) {
|
|
133
|
+
for (const font of fonts) {
|
|
134
|
+
// WebGL — SDF
|
|
135
|
+
if (
|
|
136
|
+
renderer.stage.renderer.mode === 'webgl' &&
|
|
137
|
+
'type' in font &&
|
|
138
|
+
(font.type === 'msdf' || font.type === 'ssdf')
|
|
139
|
+
) {
|
|
140
|
+
renderer.stage.loadFont('sdf', font);
|
|
141
|
+
}
|
|
142
|
+
// Canvas — Web
|
|
143
|
+
else if ('fontUrl' in font && renderer.stage.renderer.mode !== 'webgl') {
|
|
144
|
+
renderer.stage.loadFont('canvas', font);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|