lunchboxjs 0.1.4013 → 0.1.4016
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 +14 -0
- package/dist/.DS_Store +0 -0
- package/dist/lunchboxjs.js +152 -110
- package/dist/lunchboxjs.min.js +1 -1
- package/dist/lunchboxjs.module.js +152 -111
- package/package.json +10 -5
- package/src/.DS_Store +0 -0
- package/src/components/LunchboxWrapper/LunchboxWrapper.ts +36 -3
- package/src/components/LunchboxWrapper/prepCanvas.ts +2 -2
- package/src/components/catalogue.ts +1 -1
- package/src/core/.DS_Store +0 -0
- package/src/core/createNode.ts +5 -1
- package/src/core/ensure.ts +4 -10
- package/src/core/instantiateThreeObject/processProps.ts +23 -6
- package/src/core/interaction/input.ts +1 -1
- package/src/core/interaction/setupAutoRaycaster.ts +12 -2
- package/src/core/update.ts +29 -3
- package/src/index.ts +12 -40
- package/src/nodeOps/remove.ts +0 -1
- package/src/types.ts +4 -0
package/src/core/ensure.ts
CHANGED
|
@@ -158,18 +158,10 @@ export const ensuredCamera = computed<Lunch.Node<THREE.Camera> | null>({
|
|
|
158
158
|
},
|
|
159
159
|
})
|
|
160
160
|
|
|
161
|
-
// export const ensuredCamera = buildEnsured<THREE.Camera>(
|
|
162
|
-
// ['PerspectiveCamera', 'OrthographicCamera'],
|
|
163
|
-
// fallbackCameraUuid,
|
|
164
|
-
// {
|
|
165
|
-
// args: [45, 0.5625, 1, 1000],
|
|
166
|
-
// }
|
|
167
|
-
// )
|
|
168
|
-
|
|
169
161
|
// ENSURE RENDERER
|
|
170
162
|
// ====================
|
|
171
163
|
export const fallbackRendererUuid = 'FALLBACK_RENDERER'
|
|
172
|
-
export const
|
|
164
|
+
export const ensuredRenderer = buildEnsured(
|
|
173
165
|
// TODO: ensure support for css/svg renderers
|
|
174
166
|
['WebGLRenderer'], //, 'CSS2DRenderer', 'CSS3DRenderer', 'SVGRenderer'],
|
|
175
167
|
fallbackRendererUuid,
|
|
@@ -181,7 +173,9 @@ export const rendererReady = ref(false)
|
|
|
181
173
|
|
|
182
174
|
export const ensureRenderer = computed<Lunch.Node<THREE.WebGLRenderer> | null>({
|
|
183
175
|
get() {
|
|
184
|
-
return (
|
|
176
|
+
return (
|
|
177
|
+
rendererReady.value ? (ensuredRenderer.value as any) : (null as any)
|
|
178
|
+
) as any
|
|
185
179
|
},
|
|
186
180
|
set(val: any) {
|
|
187
181
|
const t = val.type ?? ''
|
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { Lunch } from '../..'
|
|
2
2
|
|
|
3
3
|
/** Process props into either themselves or the $attached value */
|
|
4
|
-
export function processProp<T, U = THREE.Object3D>({
|
|
4
|
+
export function processProp<T, U = THREE.Object3D>({
|
|
5
|
+
node,
|
|
6
|
+
prop,
|
|
7
|
+
}: {
|
|
8
|
+
node: Lunch.StandardMeta<U>
|
|
9
|
+
prop: any
|
|
10
|
+
}) {
|
|
5
11
|
// return $attachedArray value if needed
|
|
6
12
|
if (typeof prop === 'string' && prop.startsWith('$attachedArray')) {
|
|
7
|
-
return node.attachedArray[
|
|
13
|
+
return node.attachedArray[
|
|
14
|
+
prop.replace('$attachedArray.', '')
|
|
15
|
+
] as any as T
|
|
8
16
|
}
|
|
9
17
|
|
|
10
18
|
// return $attached value if needed
|
|
@@ -16,8 +24,17 @@ export function processProp<T, U = THREE.Object3D>({ node, prop }: { node: Lunch
|
|
|
16
24
|
return prop as T
|
|
17
25
|
}
|
|
18
26
|
|
|
19
|
-
export function processPropAsArray<T, U = THREE.Object3D>({
|
|
20
|
-
|
|
27
|
+
export function processPropAsArray<T, U = THREE.Object3D>({
|
|
28
|
+
node,
|
|
29
|
+
prop,
|
|
30
|
+
}: {
|
|
31
|
+
node: Lunch.StandardMeta<U>
|
|
32
|
+
prop: any
|
|
33
|
+
}) {
|
|
34
|
+
const isAttachedArray =
|
|
35
|
+
typeof prop === 'string' && prop.startsWith('$attachedArray')
|
|
21
36
|
const output = processProp<T, U>({ node, prop })
|
|
22
|
-
return Array.isArray(output) && isAttachedArray
|
|
23
|
-
|
|
37
|
+
return Array.isArray(output) && isAttachedArray
|
|
38
|
+
? (output as Array<T>)
|
|
39
|
+
: [output]
|
|
40
|
+
}
|
|
@@ -17,6 +17,8 @@ let mouseUpListener: (event: MouseEvent) => void
|
|
|
17
17
|
export const mousePos = ref({ x: Infinity, y: Infinity })
|
|
18
18
|
let autoRaycasterEventsInitialized = false
|
|
19
19
|
|
|
20
|
+
let frameID: number
|
|
21
|
+
|
|
20
22
|
export const setupAutoRaycaster = (node: Lunch.Node<THREE.Raycaster>) => {
|
|
21
23
|
const instance = node.instance
|
|
22
24
|
|
|
@@ -67,8 +69,16 @@ export const setupAutoRaycaster = (node: Lunch.Node<THREE.Raycaster>) => {
|
|
|
67
69
|
|
|
68
70
|
// TODO: add touch events
|
|
69
71
|
|
|
70
|
-
//
|
|
71
|
-
|
|
72
|
+
// process mouse events asynchronously, whenever the mouse state changes
|
|
73
|
+
watch(
|
|
74
|
+
() => [inputActive.value, mousePos.value.x, mousePos.value.y],
|
|
75
|
+
() => {
|
|
76
|
+
if (frameID) cancelAnimationFrame(frameID)
|
|
77
|
+
frameID = requestAnimationFrame(() => {
|
|
78
|
+
autoRaycasterBeforeRender()
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
)
|
|
72
82
|
|
|
73
83
|
// mark complete
|
|
74
84
|
autoRaycasterEventsInitialized = true
|
package/src/core/update.ts
CHANGED
|
@@ -1,22 +1,44 @@
|
|
|
1
1
|
import { ensureRenderer, ensuredScene, ensuredCamera } from '.'
|
|
2
2
|
import { Lunch } from '..'
|
|
3
|
-
import { toRaw } from 'vue'
|
|
3
|
+
import { toRaw, watch, WatchStopHandle } from 'vue'
|
|
4
4
|
|
|
5
5
|
let frameID: number
|
|
6
|
+
let watchStopHandle: WatchStopHandle
|
|
6
7
|
|
|
7
8
|
export const beforeRender = [] as Lunch.UpdateCallback[]
|
|
8
9
|
export const afterRender = [] as Lunch.UpdateCallback[]
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
const requestUpdate = (opts: Lunch.UpdateCallbackProperties) => {
|
|
12
|
+
cancelUpdate()
|
|
12
13
|
frameID = requestAnimationFrame(() =>
|
|
13
14
|
update({
|
|
14
15
|
app: opts.app,
|
|
15
16
|
renderer: ensureRenderer.value?.instance,
|
|
16
17
|
scene: ensuredScene.value.instance,
|
|
17
18
|
camera: ensuredCamera.value?.instance,
|
|
19
|
+
updateSource: opts.updateSource,
|
|
18
20
|
})
|
|
19
21
|
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const update: Lunch.UpdateCallback = (opts) => {
|
|
25
|
+
if (opts.updateSource) {
|
|
26
|
+
if (!watchStopHandle) {
|
|
27
|
+
// request next frame only when state changes
|
|
28
|
+
watchStopHandle = watch(
|
|
29
|
+
opts.updateSource,
|
|
30
|
+
() => {
|
|
31
|
+
requestUpdate(opts)
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
deep: true,
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
}
|
|
38
|
+
} else {
|
|
39
|
+
// request next frame on a continuous loop
|
|
40
|
+
requestUpdate(opts)
|
|
41
|
+
}
|
|
20
42
|
|
|
21
43
|
// prep options
|
|
22
44
|
const { app, renderer, scene, camera } = opts
|
|
@@ -82,3 +104,7 @@ export const offAfterRender = (cb: Lunch.UpdateCallback | number) => {
|
|
|
82
104
|
export const cancelUpdate = () => {
|
|
83
105
|
if (frameID) cancelAnimationFrame(frameID)
|
|
84
106
|
}
|
|
107
|
+
|
|
108
|
+
export const cancelUpdateSource = () => {
|
|
109
|
+
if (watchStopHandle) watchStopHandle()
|
|
110
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
computed,
|
|
3
|
-
createRenderer,
|
|
4
|
-
Component,
|
|
5
|
-
ref,
|
|
6
|
-
watch,
|
|
7
|
-
WatchStopHandle,
|
|
8
|
-
} from 'vue'
|
|
1
|
+
import { computed, createRenderer, Component, ref, watch } from 'vue'
|
|
9
2
|
import { nodeOps } from './nodeOps'
|
|
10
3
|
import {
|
|
11
4
|
// createdCamera,
|
|
@@ -47,20 +40,13 @@ export const globals = {
|
|
|
47
40
|
export const camera = computed(() => ensuredCamera.value?.instance ?? null)
|
|
48
41
|
/** Run a function using the current camera when it's present. */
|
|
49
42
|
export function useCamera<T extends THREE.Camera = THREE.PerspectiveCamera>(
|
|
50
|
-
callback: (cam: T) => void
|
|
51
|
-
once = true
|
|
43
|
+
callback: (cam: T) => void
|
|
52
44
|
) {
|
|
53
|
-
|
|
54
|
-
destroy = watch(
|
|
45
|
+
return watch(
|
|
55
46
|
camera,
|
|
56
47
|
(newVal) => {
|
|
57
48
|
if (!newVal) return
|
|
58
|
-
|
|
59
|
-
// TODO: better fix than `any`?
|
|
60
|
-
callback(newVal as any)
|
|
61
|
-
if (once) {
|
|
62
|
-
destroy?.()
|
|
63
|
-
}
|
|
49
|
+
callback(newVal as unknown as T)
|
|
64
50
|
},
|
|
65
51
|
{ immediate: true }
|
|
66
52
|
)
|
|
@@ -70,20 +56,13 @@ export function useCamera<T extends THREE.Camera = THREE.PerspectiveCamera>(
|
|
|
70
56
|
export const renderer = computed(() => ensureRenderer.value?.instance ?? null)
|
|
71
57
|
/** Run a function using the current renderer when it's present. */
|
|
72
58
|
export function useRenderer<T extends THREE.Renderer = THREE.WebGLRenderer>(
|
|
73
|
-
callback: (rend: T) => void
|
|
74
|
-
once = true
|
|
59
|
+
callback: (rend: T) => void
|
|
75
60
|
) {
|
|
76
|
-
|
|
77
|
-
destroy = watch(
|
|
61
|
+
return watch(
|
|
78
62
|
renderer,
|
|
79
63
|
(newVal) => {
|
|
80
64
|
if (!newVal) return
|
|
81
|
-
|
|
82
|
-
// TODO: better fix than `any`?
|
|
83
|
-
callback(newVal as any)
|
|
84
|
-
if (once) {
|
|
85
|
-
destroy?.()
|
|
86
|
-
}
|
|
65
|
+
callback(newVal as unknown as T)
|
|
87
66
|
},
|
|
88
67
|
{ immediate: true }
|
|
89
68
|
)
|
|
@@ -92,21 +71,12 @@ export function useRenderer<T extends THREE.Renderer = THREE.WebGLRenderer>(
|
|
|
92
71
|
/** The current scene. Often easier to use `useScene` instead of this. */
|
|
93
72
|
export const scene = computed(() => ensuredScene.value.instance)
|
|
94
73
|
/** Run a function using the current scene when it's present. */
|
|
95
|
-
export function useScene(
|
|
96
|
-
|
|
97
|
-
once = true
|
|
98
|
-
) {
|
|
99
|
-
let destroy: WatchStopHandle
|
|
100
|
-
destroy = watch(
|
|
74
|
+
export function useScene(callback: (newScene: THREE.Scene) => void) {
|
|
75
|
+
return watch(
|
|
101
76
|
scene,
|
|
102
77
|
(newVal) => {
|
|
103
78
|
if (!newVal) return
|
|
104
|
-
|
|
105
|
-
// TODO: better fix than `any`?
|
|
106
79
|
callback(newVal as any)
|
|
107
|
-
if (once) {
|
|
108
|
-
destroy?.()
|
|
109
|
-
}
|
|
110
80
|
},
|
|
111
81
|
{ immediate: true }
|
|
112
82
|
)
|
|
@@ -142,15 +112,17 @@ export const createApp = (root: Component) => {
|
|
|
142
112
|
|
|
143
113
|
// register all components
|
|
144
114
|
Object.keys(components).forEach((key) => {
|
|
145
|
-
app
|
|
115
|
+
app?.component(key, (components as any)[key])
|
|
146
116
|
})
|
|
147
117
|
|
|
148
118
|
// update mount function to match Lunchbox.Node
|
|
149
119
|
const { mount } = app
|
|
150
120
|
app.mount = (root, ...args) => {
|
|
121
|
+
// find DOM element to use as app root
|
|
151
122
|
const domElement = (
|
|
152
123
|
typeof root === 'string' ? document.querySelector(root) : root
|
|
153
124
|
) as HTMLElement
|
|
125
|
+
// create or find root node
|
|
154
126
|
const rootNode = ensureRootNode({
|
|
155
127
|
domElement,
|
|
156
128
|
isLunchboxRootNode: true,
|
package/src/nodeOps/remove.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
type RootNode = import('./core/minidom').MiniDom.RendererRootNode
|
|
2
2
|
type VNodeProps = import('vue').VNodeProps
|
|
3
3
|
type VueApp<T> = import('vue').App<T>
|
|
4
|
+
type WatchSource = import('vue').WatchSource
|
|
4
5
|
type RendererStandardNode<T = THREE.Object3D> =
|
|
5
6
|
import('./core').MiniDom.RendererStandardNode<T>
|
|
6
7
|
|
|
@@ -127,6 +128,7 @@ export declare namespace Lunch {
|
|
|
127
128
|
scene?: THREE.Scene | null
|
|
128
129
|
renderer?: THREE.Renderer | null
|
|
129
130
|
camera?: THREE.Camera | null
|
|
131
|
+
updateSource?: WatchSource | null
|
|
130
132
|
|
|
131
133
|
// sceneNode: Node<THREE.Scene> | null
|
|
132
134
|
// rendererNode: Node<THREE.Renderer> | null
|
|
@@ -145,11 +147,13 @@ export declare namespace Lunch {
|
|
|
145
147
|
dpr?: number
|
|
146
148
|
ortho?: boolean
|
|
147
149
|
orthographic?: boolean
|
|
150
|
+
r3f?: boolean
|
|
148
151
|
// TODO: Why doesn't ConstructorParameters<THREE.WebGLRenderer> work here?
|
|
149
152
|
rendererArguments?: object
|
|
150
153
|
rendererProperties?: Partial<THREE.WebGLRenderer>
|
|
151
154
|
shadow?: ShadowSugar
|
|
152
155
|
transparent?: boolean
|
|
153
156
|
zoom?: number
|
|
157
|
+
updateSource?: WatchSource | null
|
|
154
158
|
}
|
|
155
159
|
}
|