lunchboxjs 0.2.1001-beta.0 → 0.2.1001-beta.301
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/README.md +0 -47
- package/dist/lunchboxjs.js +438 -420
- package/dist/lunchboxjs.min.js +1 -1
- package/dist/lunchboxjs.module.js +435 -408
- package/extras/OrbitControlsWrapper.vue +2 -12
- package/package.json +6 -2
- package/src/components/LunchboxEventHandlers.tsx +237 -0
- package/src/components/LunchboxWrapper/LunchboxWrapper.tsx +49 -7
- package/src/components/autoGeneratedComponents.ts +1 -1
- package/src/components/index.ts +2 -2
- package/src/core/createNode.ts +1 -1
- package/src/core/extend.ts +1 -1
- package/src/core/index.ts +0 -1
- package/src/core/instantiateThreeObject/index.ts +1 -1
- package/src/core/instantiateThreeObject/processProps.ts +1 -1
- package/src/core/interaction.ts +55 -0
- package/src/core/minidom.ts +1 -1
- package/src/core/update.ts +32 -44
- package/src/core/updateObjectProp.ts +21 -16
- package/src/index.ts +65 -34
- package/src/keys.ts +1 -0
- package/src/nodeOps/index.ts +70 -57
- package/src/types.ts +0 -8
- package/src/utils/index.ts +10 -0
- package/src/components/catalogue.ts +0 -3
- package/src/core/ensure.ts +0 -16
- 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 -232
package/src/core/update.ts
CHANGED
|
@@ -1,18 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// ensuredScene,
|
|
4
|
-
// ensuredCamera,
|
|
5
|
-
// } from '.'
|
|
6
|
-
import { Lunch } from '..'
|
|
7
|
-
import { inject, toRaw, watch, WatchStopHandle } from 'vue'
|
|
1
|
+
import type { Lunch } from '..'
|
|
2
|
+
import { inject, toRaw, watch } from 'vue'
|
|
8
3
|
import * as Keys from '../keys'
|
|
9
4
|
|
|
10
|
-
// let frameID: number
|
|
11
|
-
// let watchStopHandle: WatchStopHandle
|
|
12
|
-
|
|
13
|
-
// export const beforeRender = [] as Lunch.UpdateCallback[]
|
|
14
|
-
// export const afterRender = [] as Lunch.UpdateCallback[]
|
|
15
|
-
|
|
16
5
|
const requestUpdate = (opts: Lunch.UpdateCallbackProperties) => {
|
|
17
6
|
if (typeof opts.app.config.globalProperties.lunchbox.frameId === 'number') {
|
|
18
7
|
cancelAnimationFrame(opts.app.config.globalProperties.lunchbox.frameId)
|
|
@@ -49,7 +38,7 @@ export const update: Lunch.UpdateCallback = (opts) => {
|
|
|
49
38
|
}
|
|
50
39
|
|
|
51
40
|
// prep options
|
|
52
|
-
const { app, renderer, scene
|
|
41
|
+
const { app, renderer, scene } = opts
|
|
53
42
|
|
|
54
43
|
// BEFORE RENDER
|
|
55
44
|
app.config.globalProperties.lunchbox.beforeRender.forEach((cb) => {
|
|
@@ -57,14 +46,14 @@ export const update: Lunch.UpdateCallback = (opts) => {
|
|
|
57
46
|
})
|
|
58
47
|
|
|
59
48
|
// RENDER
|
|
60
|
-
if (renderer && scene && camera) {
|
|
49
|
+
if (renderer && scene && opts.app.config.globalProperties.lunchbox.camera) {
|
|
61
50
|
if (app.customRender) {
|
|
62
51
|
app.customRender(opts)
|
|
63
52
|
} else {
|
|
64
53
|
renderer.render(
|
|
65
54
|
toRaw(scene),
|
|
66
|
-
|
|
67
|
-
toRaw(camera)
|
|
55
|
+
opts.app.config.globalProperties.lunchbox.camera
|
|
56
|
+
// toRaw(camera)
|
|
68
57
|
)
|
|
69
58
|
}
|
|
70
59
|
}
|
|
@@ -77,7 +66,7 @@ export const update: Lunch.UpdateCallback = (opts) => {
|
|
|
77
66
|
|
|
78
67
|
// before render
|
|
79
68
|
// ====================
|
|
80
|
-
|
|
69
|
+
/** Obtain callback methods for `onBeforeRender` and `offBeforeRender`. Usually used internally by Lunchbox. */
|
|
81
70
|
export const useBeforeRender = () => {
|
|
82
71
|
return {
|
|
83
72
|
onBeforeRender: inject<typeof onBeforeRender>(Keys.onBeforeRenderKey),
|
|
@@ -87,19 +76,25 @@ export const useBeforeRender = () => {
|
|
|
87
76
|
}
|
|
88
77
|
}
|
|
89
78
|
|
|
90
|
-
|
|
79
|
+
/** Run a function before every render.
|
|
80
|
+
*
|
|
81
|
+
* Note that if `updateSource` is set in the Lunchbox wrapper component, this will **only** run
|
|
82
|
+
* before a render triggered by that `updateSource`. Normally, the function should run every frame.
|
|
83
|
+
*/
|
|
91
84
|
export const onBeforeRender = (cb: Lunch.UpdateCallback, index = Infinity) => {
|
|
92
85
|
useBeforeRender().onBeforeRender?.(cb, index)
|
|
93
86
|
}
|
|
94
87
|
|
|
95
|
-
|
|
88
|
+
/** Remove a function from the `beforeRender` callback list. Useful for tearing down functions added
|
|
89
|
+
* by `onBeforeRender`.
|
|
90
|
+
*/
|
|
96
91
|
export const offBeforeRender = (cb: Lunch.UpdateCallback | number) => {
|
|
97
92
|
useBeforeRender().offBeforeRender?.(cb)
|
|
98
93
|
}
|
|
99
94
|
|
|
100
95
|
// after render
|
|
101
96
|
// ====================
|
|
102
|
-
|
|
97
|
+
/** Obtain callback methods for `onAfterRender` and `offAfterRender`. Usually used internally by Lunchbox. */
|
|
103
98
|
export const useAfterRender = () => {
|
|
104
99
|
return {
|
|
105
100
|
onAfterRender: inject<typeof onAfterRender>(Keys.onBeforeRenderKey),
|
|
@@ -107,34 +102,25 @@ export const useAfterRender = () => {
|
|
|
107
102
|
}
|
|
108
103
|
}
|
|
109
104
|
|
|
110
|
-
|
|
105
|
+
/** Run a function after every render.
|
|
106
|
+
*
|
|
107
|
+
* Note that if `updateSource` is set in the Lunchbox wrapper component, this will **only** run
|
|
108
|
+
* after a render triggered by that `updateSource`. Normally, the function should run every frame.
|
|
109
|
+
*/
|
|
111
110
|
export const onAfterRender = (cb: Lunch.UpdateCallback, index = Infinity) => {
|
|
112
111
|
useBeforeRender().onBeforeRender?.(cb, index)
|
|
113
112
|
}
|
|
114
113
|
|
|
115
|
-
|
|
114
|
+
/** Remove a function from the `afterRender` callback list. Useful for tearing down functions added
|
|
115
|
+
* by `onAfterRender`.
|
|
116
|
+
*/
|
|
116
117
|
export const offAfterRender = (cb: Lunch.UpdateCallback | number) => {
|
|
117
118
|
useBeforeRender().offBeforeRender?.(cb)
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
// } else {
|
|
124
|
-
// afterRender.splice(index, 0, cb)
|
|
125
|
-
// }
|
|
126
|
-
// }
|
|
127
|
-
|
|
128
|
-
// export const offAfterRender = (cb: Lunch.UpdateCallback | number) => {
|
|
129
|
-
// if (isFinite(cb as number)) {
|
|
130
|
-
// afterRender.splice(cb as number, 1)
|
|
131
|
-
// } else {
|
|
132
|
-
// const idx = afterRender.findIndex((v) => v == cb)
|
|
133
|
-
// afterRender.splice(idx, 1)
|
|
134
|
-
// }
|
|
135
|
-
// }
|
|
136
|
-
|
|
137
|
-
// TODO: document
|
|
121
|
+
/** Obtain a function used to cancel the current update frame. Use `cancelUpdate` if you wish
|
|
122
|
+
* to immediately invoke the cancellation function. Usually used internally by Lunchbox.
|
|
123
|
+
*/
|
|
138
124
|
export const useCancelUpdate = () => {
|
|
139
125
|
const frameId = inject<number>(Keys.frameIdKey)
|
|
140
126
|
return () => {
|
|
@@ -142,12 +128,14 @@ export const useCancelUpdate = () => {
|
|
|
142
128
|
}
|
|
143
129
|
}
|
|
144
130
|
|
|
145
|
-
|
|
131
|
+
/** Cancel the current update frame. Usually used internally by Lunchbox. */
|
|
146
132
|
export const cancelUpdate = () => {
|
|
147
133
|
useCancelUpdate()?.()
|
|
148
134
|
}
|
|
149
135
|
|
|
150
|
-
|
|
136
|
+
/** Obtain a function used to cancel an update source. Use `cancelUpdateSource` if you wish to
|
|
137
|
+
* immediately invoke the cancellation function. Usually used internally by Lunchbox.
|
|
138
|
+
*/
|
|
151
139
|
export const useCancelUpdateSource = () => {
|
|
152
140
|
const cancel = inject<
|
|
153
141
|
Lunch.App['config']['globalProperties']['watchStopHandle']
|
|
@@ -155,7 +143,7 @@ export const useCancelUpdateSource = () => {
|
|
|
155
143
|
return () => cancel?.()
|
|
156
144
|
}
|
|
157
145
|
|
|
158
|
-
|
|
146
|
+
/** Cancel an update source. Usually used internally by Lunchbox. */
|
|
159
147
|
export const cancelUpdateSource = () => {
|
|
160
148
|
useCancelUpdateSource()?.()
|
|
161
149
|
}
|
|
@@ -1,34 +1,25 @@
|
|
|
1
1
|
import { isEventKey, isLunchboxStandardNode } from '../utils'
|
|
2
2
|
import { addEventListener } from './interaction'
|
|
3
3
|
import { get, isNumber, set } from 'lodash'
|
|
4
|
-
import { Lunch } from '..'
|
|
5
|
-
|
|
6
|
-
/** Update the given node so all of its props are current. */
|
|
7
|
-
export function updateAllObjectProps({ node }: { node: Lunch.Node }) {
|
|
8
|
-
// set props
|
|
9
|
-
const props = node.props || {}
|
|
10
|
-
let output = node
|
|
11
|
-
Object.keys(props).forEach((key) => {
|
|
12
|
-
output = updateObjectProp({ node, key, value: props[key] })
|
|
13
|
-
})
|
|
14
|
-
|
|
15
|
-
return output
|
|
16
|
-
}
|
|
4
|
+
import type { Lunch } from '..'
|
|
5
|
+
import type { Ref } from 'vue'
|
|
17
6
|
|
|
18
7
|
/** Update a single prop on a given node. */
|
|
19
8
|
export function updateObjectProp({
|
|
20
9
|
node,
|
|
21
10
|
key,
|
|
11
|
+
interactables,
|
|
22
12
|
value,
|
|
23
13
|
}: {
|
|
24
14
|
node: Lunch.Node
|
|
25
15
|
key: string
|
|
16
|
+
interactables: Ref<Lunch.Node[]>
|
|
26
17
|
value: any
|
|
27
18
|
}) {
|
|
28
19
|
// handle and return early if prop is an event
|
|
29
20
|
// (event list from react-three-fiber)
|
|
30
21
|
if (isEventKey(key)) {
|
|
31
|
-
return addEventListener({ node, key, value })
|
|
22
|
+
return addEventListener({ node, key, interactables, value })
|
|
32
23
|
}
|
|
33
24
|
|
|
34
25
|
// update THREE property
|
|
@@ -67,6 +58,7 @@ export function updateObjectProp({
|
|
|
67
58
|
}
|
|
68
59
|
|
|
69
60
|
// change property
|
|
61
|
+
// first, save as array in case we need to spread it
|
|
70
62
|
if (liveProperty && isNumber(value) && liveProperty.setScalar) {
|
|
71
63
|
// if value is a number and the property has a `setScalar` method, use that
|
|
72
64
|
liveProperty.setScalar(value)
|
|
@@ -75,8 +67,21 @@ export function updateObjectProp({
|
|
|
75
67
|
const nextValueAsArray = Array.isArray(value) ? value : [value]
|
|
76
68
|
;(target as any)[finalKey].set(...nextValueAsArray)
|
|
77
69
|
} else if (typeof liveProperty === 'function') {
|
|
78
|
-
//
|
|
79
|
-
|
|
70
|
+
// some function properties are set rather than called, so let's handle them
|
|
71
|
+
if (
|
|
72
|
+
finalKey.toLowerCase() === 'onbeforerender' ||
|
|
73
|
+
finalKey.toLowerCase() === 'onafterrender'
|
|
74
|
+
) {
|
|
75
|
+
;(target as any)[finalKey] = value
|
|
76
|
+
} else {
|
|
77
|
+
if (!Array.isArray(value)) {
|
|
78
|
+
throw new Error(
|
|
79
|
+
'Arguments on a declarative method must be wrapped in an array.\nWorks:\n<example :methodCall="[256]" />\nDoesn\'t work:\n<example :methodCall="256" />'
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
// if property is a function, let's try calling it
|
|
83
|
+
liveProperty.bind(node.instance)(...value)
|
|
84
|
+
}
|
|
80
85
|
|
|
81
86
|
// pass the result to the parent
|
|
82
87
|
// const parent = node.parentNode
|
package/src/index.ts
CHANGED
|
@@ -2,22 +2,17 @@ import {
|
|
|
2
2
|
computed,
|
|
3
3
|
createRenderer,
|
|
4
4
|
Component,
|
|
5
|
+
ComputedRef,
|
|
5
6
|
inject,
|
|
6
7
|
watch,
|
|
7
8
|
reactive,
|
|
9
|
+
Ref,
|
|
8
10
|
} from 'vue'
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
ensuredCamera,
|
|
12
|
-
ensureRenderer,
|
|
13
|
-
ensuredScene,
|
|
14
|
-
extend,
|
|
15
|
-
MiniDom,
|
|
16
|
-
} from './core'
|
|
11
|
+
import { createNodeOps } from './nodeOps'
|
|
12
|
+
import { extend, MiniDom } from './core'
|
|
17
13
|
import { components } from './components'
|
|
18
14
|
import { Lunch } from './types'
|
|
19
15
|
|
|
20
|
-
// export { lunchboxRootNode as lunchboxTree } from './core'
|
|
21
16
|
export * from './core'
|
|
22
17
|
export * from './types'
|
|
23
18
|
|
|
@@ -27,28 +22,58 @@ export * from './keys'
|
|
|
27
22
|
// Utilities
|
|
28
23
|
export * from './utils/find'
|
|
29
24
|
|
|
30
|
-
/** The current camera
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
export const
|
|
25
|
+
/** The current camera as a computed value. */
|
|
26
|
+
export const useCamera = <T extends THREE.Camera = THREE.Camera>() =>
|
|
27
|
+
inject<ComputedRef<T>>(Keys.appCameraKey)!
|
|
28
|
+
/** Run a function using the current camera when it's present. */
|
|
29
|
+
export const onCameraReady = <T extends THREE.Camera = THREE.Camera>(
|
|
30
|
+
cb: (camera?: T) => void
|
|
31
|
+
) => {
|
|
32
|
+
const stopWatch = watch(
|
|
33
|
+
useCamera<T>(),
|
|
34
|
+
(newVal) => {
|
|
35
|
+
if (newVal) {
|
|
36
|
+
cb(newVal)
|
|
37
|
+
stopWatch()
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
{ immediate: true }
|
|
41
|
+
)
|
|
42
|
+
}
|
|
35
43
|
|
|
36
|
-
/** The current renderer as a computed value.
|
|
37
|
-
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)!
|
|
38
47
|
/** Run a function using the current renderer when it's present. */
|
|
39
|
-
export const
|
|
48
|
+
export const onRendererReady = <T extends THREE.Renderer = THREE.Renderer>(
|
|
49
|
+
cb: (renderer?: T) => void
|
|
50
|
+
) => {
|
|
51
|
+
const stopWatch = watch(
|
|
52
|
+
useRenderer<T>(),
|
|
53
|
+
(newVal) => {
|
|
54
|
+
if (newVal) {
|
|
55
|
+
cb(newVal)
|
|
56
|
+
stopWatch()
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
{ immediate: true }
|
|
60
|
+
)
|
|
61
|
+
}
|
|
40
62
|
|
|
41
|
-
/** The current scene
|
|
42
|
-
|
|
43
|
-
|
|
63
|
+
/** The current scene as a computed value. */
|
|
64
|
+
export const useScene = <T extends THREE.Scene = THREE.Scene>() =>
|
|
65
|
+
inject<ComputedRef<T>>(Keys.appSceneKey)!
|
|
44
66
|
/** Run a function using the current scene when it's present. */
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
67
|
+
export const onSceneReady = <T extends THREE.Scene = THREE.Scene>(
|
|
68
|
+
cb: (scene?: T) => void
|
|
69
|
+
) => {
|
|
70
|
+
const stopWatch = watch(
|
|
71
|
+
useScene<T>(),
|
|
49
72
|
(newVal) => {
|
|
50
|
-
if (
|
|
51
|
-
|
|
73
|
+
if (newVal) {
|
|
74
|
+
cb(newVal)
|
|
75
|
+
stopWatch()
|
|
76
|
+
}
|
|
52
77
|
},
|
|
53
78
|
{ immediate: true }
|
|
54
79
|
)
|
|
@@ -116,18 +141,15 @@ export const updateGlobals = (newValue: Partial<Lunch.AppGlobals>) => {
|
|
|
116
141
|
useUpdateGlobals()?.(newValue)
|
|
117
142
|
}
|
|
118
143
|
|
|
119
|
-
|
|
120
|
-
export const useRootNode = () =>
|
|
121
|
-
inject<MiniDom.RendererRootNode>(Keys.appRootNodeKey)
|
|
122
|
-
|
|
123
|
-
// TODO: document
|
|
144
|
+
/** Use the current Lunchbox app. Usually used internally by Lunchbox. */
|
|
124
145
|
export const useApp = () => inject<Lunch.App>(Keys.appKey)
|
|
125
146
|
|
|
126
|
-
|
|
147
|
+
/** Obtain a list of the start callback functions. Usually used internally by Lunchbox. */
|
|
127
148
|
export const useStartCallbacks = () =>
|
|
128
|
-
inject<Lunch.UpdateCallback[]>(Keys.startCallbackKey)
|
|
149
|
+
inject<Lunch.UpdateCallback[]>(Keys.startCallbackKey)
|
|
129
150
|
|
|
130
|
-
|
|
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. */
|
|
131
153
|
export const onStart = (cb: Lunch.UpdateCallback, index = Infinity) => {
|
|
132
154
|
const callbacks = useStartCallbacks()
|
|
133
155
|
if (index === Infinity) {
|
|
@@ -137,11 +159,20 @@ export const onStart = (cb: Lunch.UpdateCallback, index = Infinity) => {
|
|
|
137
159
|
}
|
|
138
160
|
}
|
|
139
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
|
+
|
|
140
166
|
// CREATE APP
|
|
141
167
|
// ====================
|
|
142
168
|
export const createApp = (root: Component) => {
|
|
169
|
+
const { nodeOps, interactables } = createNodeOps()
|
|
143
170
|
const app = createRenderer(nodeOps).createApp(root) as Lunch.App
|
|
144
171
|
|
|
172
|
+
// provide Lunchbox interaction handlers flag (modified when user references events via
|
|
173
|
+
// @click, etc)
|
|
174
|
+
app.provide(Keys.lunchboxInteractables, interactables)
|
|
175
|
+
|
|
145
176
|
// register all components
|
|
146
177
|
// ====================
|
|
147
178
|
Object.keys(components).forEach((key) => {
|
package/src/keys.ts
CHANGED
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
|
}
|
package/src/types.ts
CHANGED
|
@@ -36,10 +36,6 @@ export declare namespace Lunch {
|
|
|
36
36
|
update: UpdateCallback
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
// type AppGlobals = {
|
|
40
|
-
// /** Device pixel resolution */
|
|
41
|
-
// dpr: number
|
|
42
|
-
// }
|
|
43
39
|
type AppGlobals = App['config']['globalProperties']['lunchbox']
|
|
44
40
|
|
|
45
41
|
type AppGlobalsUpdate = (newValue: Partial<AppGlobals>) => void
|
|
@@ -159,10 +155,6 @@ export declare namespace Lunch {
|
|
|
159
155
|
renderer?: THREE.Renderer | null
|
|
160
156
|
camera?: THREE.Camera | null
|
|
161
157
|
updateSource?: WatchSource | null
|
|
162
|
-
|
|
163
|
-
// sceneNode: Node<THREE.Scene> | null
|
|
164
|
-
// rendererNode: Node<THREE.Renderer> | null
|
|
165
|
-
// cameraNode: Node<THREE.Camera> | null
|
|
166
158
|
}
|
|
167
159
|
|
|
168
160
|
/** Universally unique identifier. */
|
package/src/utils/index.ts
CHANGED
|
@@ -43,3 +43,13 @@ export const isLunchboxStandardNode = (
|
|
|
43
43
|
export const isLunchboxRootNode = (node: any): node is Lunch.RootMeta => {
|
|
44
44
|
return node.isLunchboxRootNode
|
|
45
45
|
}
|
|
46
|
+
|
|
47
|
+
export const waitFor = async (get: () => any) => {
|
|
48
|
+
let output = get()
|
|
49
|
+
while (!output) {
|
|
50
|
+
await new Promise((resolve) => requestAnimationFrame(resolve))
|
|
51
|
+
output = get()
|
|
52
|
+
console.log(output)
|
|
53
|
+
}
|
|
54
|
+
return output
|
|
55
|
+
}
|
package/src/core/ensure.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { ComputedRef, inject } from 'vue'
|
|
2
|
-
import * as Keys from '../keys'
|
|
3
|
-
|
|
4
|
-
export const ensuredCamera = <T extends THREE.Camera = THREE.Camera>() =>
|
|
5
|
-
inject<ComputedRef<T>>(Keys.appCameraKey)!
|
|
6
|
-
|
|
7
|
-
// ENSURE RENDERER
|
|
8
|
-
// ====================
|
|
9
|
-
export const ensureRenderer = <
|
|
10
|
-
T extends THREE.Renderer = THREE.WebGLRenderer
|
|
11
|
-
>() => inject<ComputedRef<T>>(Keys.appRenderersKey)
|
|
12
|
-
|
|
13
|
-
// ENSURE SCENE
|
|
14
|
-
// ====================
|
|
15
|
-
export const ensuredScene = <T extends THREE.Scene = THREE.Scene>() =>
|
|
16
|
-
inject<ComputedRef<T>>(Keys.appSceneKey)
|