lunchboxjs 0.1.4018 → 0.2.1001-beta.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/lunchboxjs.js +1739 -1670
- package/dist/lunchboxjs.min.js +1 -1
- package/dist/lunchboxjs.module.js +1694 -1667
- package/extras/OrbitControlsWrapper.vue +5 -7
- package/package.json +15 -4
- package/src/components/LunchboxEventHandlers.tsx +237 -0
- package/src/components/LunchboxWrapper/LunchboxScene.tsx +8 -0
- package/src/components/LunchboxWrapper/LunchboxWrapper.tsx +341 -0
- package/src/components/LunchboxWrapper/prepCanvas.ts +27 -21
- package/src/components/LunchboxWrapper/resizeCanvas.ts +13 -12
- package/src/components/autoGeneratedComponents.ts +1 -1
- package/src/components/index.ts +2 -4
- package/src/core/createNode.ts +2 -18
- package/src/core/extend.ts +1 -1
- package/src/core/index.ts +0 -3
- package/src/core/instantiateThreeObject/index.ts +7 -2
- package/src/core/instantiateThreeObject/processProps.ts +1 -1
- package/src/core/interaction.ts +55 -0
- package/src/core/minidom.ts +5 -9
- package/src/core/update.ts +92 -53
- package/src/core/updateObjectProp.ts +5 -14
- package/src/index.ts +270 -76
- package/src/keys.ts +25 -0
- package/src/nodeOps/createElement.ts +2 -5
- package/src/nodeOps/index.ts +70 -57
- package/src/nodeOps/insert.ts +11 -32
- package/src/nodeOps/remove.ts +1 -17
- package/src/types.ts +34 -10
- package/src/utils/index.ts +11 -4
- package/dist/.DS_Store +0 -0
- package/src/.DS_Store +0 -0
- package/src/components/LunchboxWrapper/LunchboxWrapper.ts +0 -312
- package/src/components/catalogue.ts +0 -3
- package/src/core/.DS_Store +0 -0
- package/src/core/allNodes.ts +0 -4
- package/src/core/ensure.ts +0 -203
- package/src/core/interaction/index.ts +0 -102
- package/src/core/interaction/input.ts +0 -4
- package/src/core/interaction/interactables.ts +0 -14
- package/src/core/interaction/setupAutoRaycaster.ts +0 -224
- package/src/core/start.ts +0 -11
package/src/index.ts
CHANGED
|
@@ -1,82 +1,79 @@
|
|
|
1
|
-
import { computed, createRenderer, Component, ref, watch } from 'vue'
|
|
2
|
-
import { nodeOps } from './nodeOps'
|
|
3
1
|
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
} from './core'
|
|
2
|
+
computed,
|
|
3
|
+
createRenderer,
|
|
4
|
+
Component,
|
|
5
|
+
ComputedRef,
|
|
6
|
+
inject,
|
|
7
|
+
watch,
|
|
8
|
+
reactive,
|
|
9
|
+
Ref,
|
|
10
|
+
} from 'vue'
|
|
11
|
+
import { createNodeOps } from './nodeOps'
|
|
12
|
+
import { extend, MiniDom } from './core'
|
|
16
13
|
import { components } from './components'
|
|
17
14
|
import { Lunch } from './types'
|
|
18
15
|
|
|
19
|
-
export
|
|
20
|
-
export {
|
|
21
|
-
offAfterRender,
|
|
22
|
-
offBeforeRender,
|
|
23
|
-
onAfterRender,
|
|
24
|
-
onBeforeRender,
|
|
25
|
-
onStart,
|
|
26
|
-
} from './core'
|
|
16
|
+
export * from './core'
|
|
27
17
|
export * from './types'
|
|
28
18
|
|
|
19
|
+
import * as Keys from './keys'
|
|
20
|
+
export * from './keys'
|
|
21
|
+
|
|
29
22
|
// Utilities
|
|
30
23
|
export * from './utils/find'
|
|
31
24
|
|
|
32
|
-
/**
|
|
33
|
-
export const
|
|
34
|
-
|
|
35
|
-
inputActive,
|
|
36
|
-
mousePos,
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/** The current camera. Often easier to use `useCamera` instead of this. */
|
|
40
|
-
export const camera = computed(() => ensuredCamera.value?.instance ?? null)
|
|
25
|
+
/** The current camera as a computed value. */
|
|
26
|
+
export const useCamera = <T extends THREE.Camera = THREE.Camera>() =>
|
|
27
|
+
inject<ComputedRef<T>>(Keys.appCameraKey)!
|
|
41
28
|
/** Run a function using the current camera when it's present. */
|
|
42
|
-
export
|
|
43
|
-
|
|
44
|
-
) {
|
|
45
|
-
|
|
46
|
-
|
|
29
|
+
export const onCameraReady = <T extends THREE.Camera = THREE.Camera>(
|
|
30
|
+
cb: (camera?: T) => void
|
|
31
|
+
) => {
|
|
32
|
+
const stopWatch = watch(
|
|
33
|
+
useCamera<T>(),
|
|
47
34
|
(newVal) => {
|
|
48
|
-
if (
|
|
49
|
-
|
|
35
|
+
if (newVal) {
|
|
36
|
+
cb(newVal)
|
|
37
|
+
stopWatch()
|
|
38
|
+
}
|
|
50
39
|
},
|
|
51
40
|
{ immediate: true }
|
|
52
41
|
)
|
|
53
42
|
}
|
|
54
43
|
|
|
55
|
-
/** The current renderer
|
|
56
|
-
export const
|
|
44
|
+
/** The current renderer as a computed value. */
|
|
45
|
+
export const useRenderer = <T extends THREE.Renderer = THREE.WebGLRenderer>() =>
|
|
46
|
+
inject<ComputedRef<T>>(Keys.appRenderersKey)!
|
|
57
47
|
/** Run a function using the current renderer when it's present. */
|
|
58
|
-
export
|
|
59
|
-
|
|
60
|
-
) {
|
|
61
|
-
|
|
62
|
-
|
|
48
|
+
export const onRendererReady = <T extends THREE.Renderer = THREE.Renderer>(
|
|
49
|
+
cb: (renderer?: T) => void
|
|
50
|
+
) => {
|
|
51
|
+
const stopWatch = watch(
|
|
52
|
+
useRenderer<T>(),
|
|
63
53
|
(newVal) => {
|
|
64
|
-
if (
|
|
65
|
-
|
|
54
|
+
if (newVal) {
|
|
55
|
+
cb(newVal)
|
|
56
|
+
stopWatch()
|
|
57
|
+
}
|
|
66
58
|
},
|
|
67
59
|
{ immediate: true }
|
|
68
60
|
)
|
|
69
61
|
}
|
|
70
62
|
|
|
71
|
-
/** The current scene
|
|
72
|
-
export const
|
|
63
|
+
/** The current scene as a computed value. */
|
|
64
|
+
export const useScene = <T extends THREE.Scene = THREE.Scene>() =>
|
|
65
|
+
inject<ComputedRef<T>>(Keys.appSceneKey)!
|
|
73
66
|
/** Run a function using the current scene when it's present. */
|
|
74
|
-
export
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
export const onSceneReady = <T extends THREE.Scene = THREE.Scene>(
|
|
68
|
+
cb: (scene?: T) => void
|
|
69
|
+
) => {
|
|
70
|
+
const stopWatch = watch(
|
|
71
|
+
useScene<T>(),
|
|
77
72
|
(newVal) => {
|
|
78
|
-
if (
|
|
79
|
-
|
|
73
|
+
if (newVal) {
|
|
74
|
+
cb(newVal)
|
|
75
|
+
stopWatch()
|
|
76
|
+
}
|
|
80
77
|
},
|
|
81
78
|
{ immediate: true }
|
|
82
79
|
)
|
|
@@ -84,38 +81,213 @@ export function useScene(callback: (newScene: THREE.Scene) => void) {
|
|
|
84
81
|
|
|
85
82
|
// CUSTOM RENDER SUPPORT
|
|
86
83
|
// ====================
|
|
87
|
-
let app: Lunch.App | null = null
|
|
88
|
-
let queuedCustomRenderFunction:
|
|
89
|
-
| ((opts: Lunch.UpdateCallbackProperties) => void)
|
|
90
|
-
| null = null
|
|
91
|
-
|
|
92
84
|
/** Set a custom render function, overriding the Lunchbox app's default render function.
|
|
93
85
|
* Changing this requires the user to manually render their scene.
|
|
86
|
+
*
|
|
87
|
+
* Invokes immediately - use `useCustomRender().setCustomRender`
|
|
88
|
+
* if you need to call somewhere outside of `setup`.
|
|
94
89
|
*/
|
|
95
90
|
export const setCustomRender = (
|
|
96
91
|
render: (opts: Lunch.UpdateCallbackProperties) => void
|
|
97
92
|
) => {
|
|
98
|
-
|
|
99
|
-
else queuedCustomRenderFunction = render
|
|
93
|
+
useCustomRender()?.setCustomRender?.(render)
|
|
100
94
|
}
|
|
101
95
|
|
|
102
|
-
/** Clear the active app's custom render function.
|
|
96
|
+
/** Clear the active app's custom render function.
|
|
97
|
+
*
|
|
98
|
+
* Invokes immediately - use `useCustomRender().clearCustomRender`
|
|
99
|
+
* if you need to call somewhere outside of `setup`.
|
|
100
|
+
*/
|
|
103
101
|
export const clearCustomRender = () => {
|
|
104
|
-
|
|
105
|
-
|
|
102
|
+
useCustomRender()?.clearCustomRender?.()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** Provides `setCustomRender` and `clearCustomRender` functions to be called in a non-`setup` context. */
|
|
106
|
+
export const useCustomRender = () => {
|
|
107
|
+
return {
|
|
108
|
+
/** Set a custom render function, overriding the Lunchbox app's default render function.
|
|
109
|
+
* Changing this requires the user to manually render their scene. */
|
|
110
|
+
setCustomRender: inject<Lunch.CustomRenderFunctionSetter>(
|
|
111
|
+
Keys.setCustomRenderKey
|
|
112
|
+
),
|
|
113
|
+
/** Clear the active app's custom render function. */
|
|
114
|
+
clearCustomRender: inject<() => void>(Keys.clearCustomRenderKey),
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Use app-level globals. */
|
|
119
|
+
export const useGlobals = () =>
|
|
120
|
+
inject<Lunch.AppGlobals>(Keys.globalsInjectionKey)!
|
|
121
|
+
|
|
122
|
+
/** Construct a function to update your app-level globals.
|
|
123
|
+
*
|
|
124
|
+
* ```js
|
|
125
|
+
* // in setup():
|
|
126
|
+
* const updateGlobals = useUpdateGlobals()
|
|
127
|
+
*
|
|
128
|
+
* // ...later, to update the device pixel resolution...
|
|
129
|
+
* updateGlobals({ dpr: 2 })
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
export const useUpdateGlobals = () =>
|
|
133
|
+
inject<Lunch.AppGlobalsUpdate>(Keys.updateGlobalsInjectionKey)
|
|
134
|
+
|
|
135
|
+
/** Update app-level globals.
|
|
136
|
+
*
|
|
137
|
+
* Invokes immediately - use `useUpdateGlobals`
|
|
138
|
+
* if you need to call somewhere outside of `setup`.
|
|
139
|
+
*/
|
|
140
|
+
export const updateGlobals = (newValue: Partial<Lunch.AppGlobals>) => {
|
|
141
|
+
useUpdateGlobals()?.(newValue)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Use the current Lunchbox app. Usually used internally by Lunchbox. */
|
|
145
|
+
export const useApp = () => inject<Lunch.App>(Keys.appKey)
|
|
146
|
+
|
|
147
|
+
/** Obtain a list of the start callback functions. Usually used internally by Lunchbox. */
|
|
148
|
+
export const useStartCallbacks = () =>
|
|
149
|
+
inject<Lunch.UpdateCallback[]>(Keys.startCallbackKey)
|
|
150
|
+
|
|
151
|
+
/** Run a given callback once when the Lunchbox app starts. Include an index to
|
|
152
|
+
* splice the callback at that index in the callback queue. */
|
|
153
|
+
export const onStart = (cb: Lunch.UpdateCallback, index = Infinity) => {
|
|
154
|
+
const callbacks = useStartCallbacks()
|
|
155
|
+
if (index === Infinity) {
|
|
156
|
+
callbacks?.push(cb)
|
|
157
|
+
} else {
|
|
158
|
+
callbacks?.splice(index, 0, cb)
|
|
159
|
+
}
|
|
106
160
|
}
|
|
107
161
|
|
|
162
|
+
/** Obtain a list of interactable objects (registered via onClick, onHover, etc events). Usually used internally by Lunchbox. */
|
|
163
|
+
export const useLunchboxInteractables = () =>
|
|
164
|
+
inject<Ref<Lunch.Node[]>>(Keys.lunchboxInteractables)
|
|
165
|
+
|
|
108
166
|
// CREATE APP
|
|
109
167
|
// ====================
|
|
110
168
|
export const createApp = (root: Component) => {
|
|
111
|
-
|
|
169
|
+
const { nodeOps, interactables } = createNodeOps()
|
|
170
|
+
const app = createRenderer(nodeOps).createApp(root) as Lunch.App
|
|
171
|
+
|
|
172
|
+
// provide Lunchbox interaction handlers flag (modified when user references events via
|
|
173
|
+
// @click, etc)
|
|
174
|
+
app.provide(Keys.lunchboxInteractables, interactables)
|
|
112
175
|
|
|
113
176
|
// register all components
|
|
177
|
+
// ====================
|
|
114
178
|
Object.keys(components).forEach((key) => {
|
|
115
179
|
app?.component(key, (components as any)[key])
|
|
116
180
|
})
|
|
117
181
|
|
|
182
|
+
// provide custom renderer functions
|
|
183
|
+
// ====================
|
|
184
|
+
app.provide(
|
|
185
|
+
Keys.setCustomRenderKey,
|
|
186
|
+
(render: (opts: Lunch.UpdateCallbackProperties) => void) => {
|
|
187
|
+
app.setCustomRender(render)
|
|
188
|
+
}
|
|
189
|
+
)
|
|
190
|
+
app.provide(Keys.clearCustomRenderKey, () => {
|
|
191
|
+
app.clearCustomRender()
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
// before render
|
|
195
|
+
// ====================
|
|
196
|
+
const beforeRender = [] as Lunch.UpdateCallback[]
|
|
197
|
+
app.provide(Keys.beforeRenderKey, beforeRender)
|
|
198
|
+
app.provide(
|
|
199
|
+
Keys.onBeforeRenderKey,
|
|
200
|
+
(cb: Lunch.UpdateCallback, index = Infinity) => {
|
|
201
|
+
if (index === Infinity) {
|
|
202
|
+
beforeRender.push(cb)
|
|
203
|
+
} else {
|
|
204
|
+
beforeRender.splice(index, 0, cb)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
)
|
|
208
|
+
app.provide(
|
|
209
|
+
Keys.offBeforeRenderKey,
|
|
210
|
+
(cb: Lunch.UpdateCallback | number) => {
|
|
211
|
+
if (isFinite(cb as number)) {
|
|
212
|
+
beforeRender.splice(cb as number, 1)
|
|
213
|
+
} else {
|
|
214
|
+
const idx = beforeRender.findIndex((v) => v == cb)
|
|
215
|
+
if (idx !== -1) {
|
|
216
|
+
beforeRender.splice(idx, 1)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
// after render
|
|
223
|
+
// ====================
|
|
224
|
+
const afterRender = [] as Lunch.UpdateCallback[]
|
|
225
|
+
app.provide(Keys.afterRenderKey, afterRender)
|
|
226
|
+
app.provide(
|
|
227
|
+
Keys.onAfterRenderKey,
|
|
228
|
+
(cb: Lunch.UpdateCallback, index = Infinity) => {
|
|
229
|
+
if (index === Infinity) {
|
|
230
|
+
afterRender.push(cb)
|
|
231
|
+
} else {
|
|
232
|
+
afterRender.splice(index, 0, cb)
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
)
|
|
236
|
+
app.provide(Keys.offAfterRenderKey, (cb: Lunch.UpdateCallback | number) => {
|
|
237
|
+
if (isFinite(cb as number)) {
|
|
238
|
+
afterRender.splice(cb as number, 1)
|
|
239
|
+
} else {
|
|
240
|
+
const idx = afterRender.findIndex((v) => v == cb)
|
|
241
|
+
if (idx !== -1) {
|
|
242
|
+
afterRender.splice(idx, 1)
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
// save app-level components
|
|
248
|
+
// ====================
|
|
249
|
+
app.config.globalProperties.lunchbox = reactive({
|
|
250
|
+
afterRender,
|
|
251
|
+
beforeRender,
|
|
252
|
+
camera: null,
|
|
253
|
+
dpr: 1,
|
|
254
|
+
frameId: -1,
|
|
255
|
+
renderer: null,
|
|
256
|
+
scene: null,
|
|
257
|
+
watchStopHandle: null,
|
|
258
|
+
|
|
259
|
+
// TODO: inputActive, mousePos
|
|
260
|
+
})
|
|
261
|
+
|
|
262
|
+
// provide app-level globals & globals update method
|
|
263
|
+
// ====================
|
|
264
|
+
app.provide(Keys.globalsInjectionKey, app.config.globalProperties.lunchbox)
|
|
265
|
+
app.provide<Lunch.AppGlobalsUpdate>(
|
|
266
|
+
Keys.updateGlobalsInjectionKey,
|
|
267
|
+
(newGlobals: Partial<Lunch.AppGlobals>) => {
|
|
268
|
+
Object.keys(newGlobals).forEach((key) => {
|
|
269
|
+
const typedKey = key as keyof Lunch.AppGlobals
|
|
270
|
+
// TODO: fix
|
|
271
|
+
app.config.globalProperties.lunchbox[typedKey] = newGlobals[
|
|
272
|
+
typedKey
|
|
273
|
+
] as any
|
|
274
|
+
})
|
|
275
|
+
}
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
// frame ID (used for update functions)
|
|
279
|
+
// ====================
|
|
280
|
+
app.provide(Keys.frameIdKey, app.config.globalProperties.lunchbox.frameId)
|
|
281
|
+
|
|
282
|
+
// watch stop handler (used for conditional update loop)
|
|
283
|
+
// ====================
|
|
284
|
+
app.provide(
|
|
285
|
+
Keys.watchStopHandleKey,
|
|
286
|
+
app.config.globalProperties.lunchbox.watchStopHandle
|
|
287
|
+
)
|
|
288
|
+
|
|
118
289
|
// update mount function to match Lunchbox.Node
|
|
290
|
+
// ====================
|
|
119
291
|
const { mount } = app
|
|
120
292
|
app.mount = (root, ...args) => {
|
|
121
293
|
// find DOM element to use as app root
|
|
@@ -123,43 +295,65 @@ export const createApp = (root: Component) => {
|
|
|
123
295
|
typeof root === 'string' ? document.querySelector(root) : root
|
|
124
296
|
) as HTMLElement
|
|
125
297
|
// create or find root node
|
|
126
|
-
const rootNode =
|
|
298
|
+
const rootNode = new MiniDom.RendererRootNode({
|
|
127
299
|
domElement,
|
|
128
300
|
isLunchboxRootNode: true,
|
|
129
301
|
name: 'root',
|
|
130
302
|
metaType: 'rootMeta',
|
|
131
303
|
type: 'root',
|
|
132
|
-
uuid:
|
|
304
|
+
uuid: 'LUNCHBOX_ROOT',
|
|
133
305
|
})
|
|
134
|
-
app
|
|
306
|
+
app.rootNode = rootNode
|
|
307
|
+
app.provide(Keys.appRootNodeKey, rootNode)
|
|
135
308
|
const mounted = mount(rootNode, ...args)
|
|
136
309
|
return mounted
|
|
137
310
|
}
|
|
138
311
|
|
|
139
312
|
// embed .extend function
|
|
313
|
+
// ====================
|
|
140
314
|
app.extend = (targets: Record<string, any>) => {
|
|
141
315
|
extend({ app: app!, ...targets })
|
|
142
316
|
return app!
|
|
143
317
|
}
|
|
144
318
|
|
|
319
|
+
// start callback functions
|
|
320
|
+
// ====================
|
|
321
|
+
const startCallbacks: Lunch.UpdateCallback[] = []
|
|
322
|
+
app.provide(Keys.startCallbackKey, startCallbacks)
|
|
323
|
+
|
|
145
324
|
// prep for custom render support
|
|
325
|
+
// ====================
|
|
146
326
|
app.setCustomRender = (
|
|
147
327
|
newRender: (opts: Lunch.UpdateCallbackProperties) => void
|
|
148
328
|
) => {
|
|
149
|
-
app
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
// add queued custom render if we have one
|
|
153
|
-
if (queuedCustomRenderFunction) {
|
|
154
|
-
app.setCustomRender(queuedCustomRenderFunction)
|
|
155
|
-
queuedCustomRenderFunction = null
|
|
329
|
+
if (app) {
|
|
330
|
+
app.customRender = newRender
|
|
331
|
+
}
|
|
156
332
|
}
|
|
157
333
|
|
|
158
334
|
// add custom render removal
|
|
159
335
|
app.clearCustomRender = () => {
|
|
160
|
-
app
|
|
336
|
+
if (app) {
|
|
337
|
+
app.customRender = null
|
|
338
|
+
}
|
|
161
339
|
}
|
|
162
340
|
|
|
341
|
+
// provide app
|
|
342
|
+
// ====================
|
|
343
|
+
app.provide(Keys.appKey, app)
|
|
344
|
+
app.provide(
|
|
345
|
+
Keys.appRenderersKey,
|
|
346
|
+
computed(() => app.config.globalProperties.lunchbox.renderer)
|
|
347
|
+
)
|
|
348
|
+
app.provide(
|
|
349
|
+
Keys.appSceneKey,
|
|
350
|
+
computed(() => app.config.globalProperties.lunchbox.scene)
|
|
351
|
+
)
|
|
352
|
+
app.provide(
|
|
353
|
+
Keys.appCameraKey,
|
|
354
|
+
computed(() => app.config.globalProperties.lunchbox.camera)
|
|
355
|
+
)
|
|
356
|
+
|
|
163
357
|
// done
|
|
164
358
|
return app
|
|
165
359
|
}
|
package/src/keys.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export const globalsInjectionKey = Symbol()
|
|
2
|
+
export const updateGlobalsInjectionKey = Symbol()
|
|
3
|
+
|
|
4
|
+
export const setCustomRenderKey = Symbol()
|
|
5
|
+
export const clearCustomRenderKey = Symbol()
|
|
6
|
+
|
|
7
|
+
export const beforeRenderKey = Symbol()
|
|
8
|
+
export const onBeforeRenderKey = Symbol()
|
|
9
|
+
export const offBeforeRenderKey = Symbol()
|
|
10
|
+
|
|
11
|
+
export const afterRenderKey = Symbol()
|
|
12
|
+
export const onAfterRenderKey = Symbol()
|
|
13
|
+
export const offAfterRenderKey = Symbol()
|
|
14
|
+
|
|
15
|
+
export const frameIdKey = Symbol()
|
|
16
|
+
export const watchStopHandleKey = Symbol()
|
|
17
|
+
|
|
18
|
+
export const appRootNodeKey = Symbol()
|
|
19
|
+
export const appKey = Symbol()
|
|
20
|
+
export const appRenderersKey = Symbol()
|
|
21
|
+
export const appSceneKey = Symbol()
|
|
22
|
+
export const appCameraKey = Symbol()
|
|
23
|
+
export const lunchboxInteractables = Symbol()
|
|
24
|
+
|
|
25
|
+
export const startCallbackKey = Symbol()
|
|
@@ -10,13 +10,10 @@ export const createElement = (
|
|
|
10
10
|
isCustomizedBuiltin?: string,
|
|
11
11
|
vnodeProps?: Lunch.LunchboxMetaProps
|
|
12
12
|
) => {
|
|
13
|
-
const options = { type
|
|
14
|
-
if (vnodeProps) {
|
|
15
|
-
options.props = vnodeProps
|
|
16
|
-
}
|
|
13
|
+
const options: Partial<Lunch.MetaBase> = { type, props: vnodeProps }
|
|
17
14
|
|
|
18
15
|
// handle dom node
|
|
19
|
-
const isDomNode = isLunchboxDomComponent(
|
|
16
|
+
const isDomNode = isLunchboxDomComponent(options)
|
|
20
17
|
if (isDomNode) {
|
|
21
18
|
const node = createDomNode(options)
|
|
22
19
|
return node
|
package/src/nodeOps/index.ts
CHANGED
|
@@ -1,70 +1,83 @@
|
|
|
1
|
-
import { RendererOptions } from 'vue'
|
|
1
|
+
import { RendererOptions, ref } from 'vue'
|
|
2
2
|
import { createElement } from './createElement'
|
|
3
3
|
import { insert } from './insert'
|
|
4
4
|
import { remove } from './remove'
|
|
5
5
|
import { isLunchboxDomComponent, isLunchboxRootNode } from '../utils'
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
MiniDom,
|
|
10
|
-
updateObjectProp,
|
|
11
|
-
} from '../core'
|
|
12
|
-
import { Lunch } from '..'
|
|
6
|
+
import { createCommentNode, createTextNode, updateObjectProp } from '../core'
|
|
7
|
+
import type { MiniDom } from '../core'
|
|
8
|
+
import type { Lunch } from '..'
|
|
13
9
|
|
|
14
10
|
/*
|
|
15
11
|
Elements are `create`d from the outside in, then `insert`ed from the inside out.
|
|
16
12
|
*/
|
|
17
13
|
|
|
18
|
-
export const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
14
|
+
export const createNodeOps = () => {
|
|
15
|
+
// APP-LEVEL GLOBALS
|
|
16
|
+
// ====================
|
|
17
|
+
// These need to exist at the app level in a place where the node ops can access them.
|
|
18
|
+
// It'd be better to set these via `app.provide` at app creation, but the node ops need access
|
|
19
|
+
// to these values before the app is instantiated, so this is the next-best place for them to exist.
|
|
20
|
+
const interactables = ref([] as Lunch.Node[])
|
|
21
|
+
|
|
22
|
+
// NODE OPS
|
|
23
|
+
// ====================
|
|
24
|
+
const nodeOps: RendererOptions<
|
|
25
|
+
MiniDom.RendererBaseNode,
|
|
26
|
+
MiniDom.RendererBaseNode
|
|
27
|
+
> = {
|
|
28
|
+
createElement,
|
|
29
|
+
createText(text) {
|
|
30
|
+
return createTextNode({ text })
|
|
31
|
+
},
|
|
32
|
+
createComment(text) {
|
|
33
|
+
return createCommentNode({ text })
|
|
34
|
+
},
|
|
35
|
+
insert,
|
|
36
|
+
nextSibling(node) {
|
|
37
|
+
const result = node.nextSibling
|
|
38
|
+
if (!result) return null
|
|
39
|
+
return result as MiniDom.RendererBaseNode
|
|
40
|
+
},
|
|
41
|
+
parentNode(node) {
|
|
42
|
+
const result = node.parentNode
|
|
43
|
+
if (!result) return null
|
|
44
|
+
return result as MiniDom.RendererBaseNode
|
|
45
|
+
},
|
|
46
|
+
patchProp(node, key, prevValue, nextValue) {
|
|
47
|
+
if (isLunchboxDomComponent(node)) {
|
|
48
|
+
// handle DOM node
|
|
49
|
+
if (key === 'style') {
|
|
50
|
+
// special handling for style
|
|
51
|
+
Object.keys(nextValue).forEach((k) => {
|
|
52
|
+
;(node.domElement.style as any)[k] = nextValue[k]
|
|
53
|
+
})
|
|
54
|
+
} else {
|
|
55
|
+
node.domElement.setAttribute(key, nextValue)
|
|
56
|
+
}
|
|
57
|
+
return
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// ignore if root node, or Lunchbox internal prop
|
|
61
|
+
if (isLunchboxRootNode(node) || key.startsWith('$')) {
|
|
62
|
+
return
|
|
51
63
|
}
|
|
52
|
-
return
|
|
53
|
-
}
|
|
54
64
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
65
|
+
// otherwise, update prop
|
|
66
|
+
updateObjectProp({
|
|
67
|
+
node: node as Lunch.Node,
|
|
68
|
+
key,
|
|
69
|
+
interactables,
|
|
70
|
+
value: nextValue,
|
|
71
|
+
})
|
|
72
|
+
},
|
|
73
|
+
remove,
|
|
74
|
+
setElementText() {
|
|
75
|
+
// noop
|
|
76
|
+
},
|
|
77
|
+
setText() {
|
|
78
|
+
// noop
|
|
79
|
+
},
|
|
80
|
+
}
|
|
59
81
|
|
|
60
|
-
|
|
61
|
-
updateObjectProp({ node: node as Lunch.Node, key, value: nextValue })
|
|
62
|
-
},
|
|
63
|
-
remove,
|
|
64
|
-
setElementText() {
|
|
65
|
-
// noop
|
|
66
|
-
},
|
|
67
|
-
setText() {
|
|
68
|
-
// noop
|
|
69
|
-
},
|
|
82
|
+
return { nodeOps, interactables }
|
|
70
83
|
}
|