lunchboxjs 0.1.4004 → 0.1.4010
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 +3 -0
- package/dist/lunchboxjs.js +129 -37
- package/dist/lunchboxjs.min.js +1 -1
- package/dist/lunchboxjs.module.js +124 -38
- package/package.json +3 -1
- package/src/components/LunchboxWrapper/LunchboxWrapper.ts +31 -9
- package/src/components/autoGeneratedComponents.ts +175 -0
- package/src/components/index.ts +5 -188
- package/src/core/index.ts +2 -1
- package/src/core/start.ts +11 -0
- package/src/core/update.ts +18 -0
- package/src/index.ts +80 -2
- package/src/types.ts +4 -0
package/README.md
CHANGED
package/dist/lunchboxjs.js
CHANGED
|
@@ -105,10 +105,13 @@
|
|
|
105
105
|
// These should match the Lunchbox.WrapperProps interface
|
|
106
106
|
background: String,
|
|
107
107
|
cameraArgs: Array,
|
|
108
|
+
cameraLook: Array,
|
|
109
|
+
cameraLookAt: Array,
|
|
108
110
|
cameraPosition: Array,
|
|
109
111
|
dpr: Number,
|
|
110
112
|
ortho: Boolean,
|
|
111
113
|
orthographic: Boolean,
|
|
114
|
+
rendererArguments: Object,
|
|
112
115
|
rendererProperties: Object,
|
|
113
116
|
shadow: [Boolean, Object],
|
|
114
117
|
transparent: Boolean,
|
|
@@ -138,12 +141,11 @@
|
|
|
138
141
|
if (!renderer) {
|
|
139
142
|
// build renderer args
|
|
140
143
|
const rendererArgs = {
|
|
144
|
+
alpha: props.transparent,
|
|
141
145
|
antialias: true,
|
|
142
146
|
canvas: canvas.value.domElement,
|
|
147
|
+
...(props.rendererArguments ?? {}),
|
|
143
148
|
};
|
|
144
|
-
if (props.transparent) {
|
|
145
|
-
rendererArgs.alpha = true;
|
|
146
|
-
}
|
|
147
149
|
// create new renderer
|
|
148
150
|
ensureRenderer.value = createNode({
|
|
149
151
|
type: 'WebGLRenderer',
|
|
@@ -181,7 +183,6 @@
|
|
|
181
183
|
// the user has initialized the renderer, so anything depending
|
|
182
184
|
// on the renderer can execute
|
|
183
185
|
rendererReady.value = true;
|
|
184
|
-
return;
|
|
185
186
|
}
|
|
186
187
|
// CAMERA
|
|
187
188
|
// ====================
|
|
@@ -194,7 +195,6 @@
|
|
|
194
195
|
if (!camera) {
|
|
195
196
|
// create ortho camera
|
|
196
197
|
if (props.ortho || props.orthographic) {
|
|
197
|
-
// const size: Vector2 = new Vector2()
|
|
198
198
|
ensuredCamera.value = createNode({
|
|
199
199
|
props: { args: props.cameraArgs ?? [] },
|
|
200
200
|
type: 'OrthographicCamera',
|
|
@@ -216,9 +216,17 @@
|
|
|
216
216
|
else {
|
|
217
217
|
cameraReady.value = true;
|
|
218
218
|
}
|
|
219
|
+
if (!camera.instance) {
|
|
220
|
+
throw new Error('Error creating camera.');
|
|
221
|
+
}
|
|
219
222
|
// move camera if needed
|
|
220
223
|
if (camera && props.cameraPosition) {
|
|
221
|
-
camera.instance
|
|
224
|
+
camera.instance.position.set(...props.cameraPosition);
|
|
225
|
+
}
|
|
226
|
+
// angle camera if needed
|
|
227
|
+
if (camera && (props.cameraLookAt || props.cameraLook)) {
|
|
228
|
+
const source = (props.cameraLookAt || props.cameraLook);
|
|
229
|
+
camera.instance.lookAt(...source);
|
|
222
230
|
}
|
|
223
231
|
// SCENE
|
|
224
232
|
// ====================
|
|
@@ -241,11 +249,23 @@
|
|
|
241
249
|
else {
|
|
242
250
|
throw new Error('missing renderer');
|
|
243
251
|
}
|
|
252
|
+
// CALLBACK PREP
|
|
253
|
+
// ====================
|
|
254
|
+
const app = vue.getCurrentInstance().appContext.app;
|
|
255
|
+
// START
|
|
256
|
+
// ====================
|
|
257
|
+
for (let startCallback of startCallbacks) {
|
|
258
|
+
startCallback({
|
|
259
|
+
app,
|
|
260
|
+
camera: camera.instance,
|
|
261
|
+
renderer: renderer.instance,
|
|
262
|
+
scene: scene.instance,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
244
265
|
// KICK UPDATE
|
|
245
266
|
// ====================
|
|
246
|
-
// console.log(scene)
|
|
247
267
|
update({
|
|
248
|
-
app
|
|
268
|
+
app,
|
|
249
269
|
camera: camera.instance,
|
|
250
270
|
renderer: renderer.instance,
|
|
251
271
|
scene: scene.instance,
|
|
@@ -276,21 +296,6 @@
|
|
|
276
296
|
},
|
|
277
297
|
};
|
|
278
298
|
|
|
279
|
-
const catalogue = {};
|
|
280
|
-
|
|
281
|
-
const lunchboxDomComponentNames = [
|
|
282
|
-
'canvas',
|
|
283
|
-
'div',
|
|
284
|
-
'LunchboxWrapper',
|
|
285
|
-
];
|
|
286
|
-
// component creation utility
|
|
287
|
-
const createComponent$1 = (tag) => vue.defineComponent({
|
|
288
|
-
inheritAttrs: false,
|
|
289
|
-
name: tag,
|
|
290
|
-
setup(props, context) {
|
|
291
|
-
return () => vue.h(tag, context.attrs, context.slots?.default?.() || []);
|
|
292
|
-
},
|
|
293
|
-
});
|
|
294
299
|
// list of all components to register out of the box
|
|
295
300
|
const autoGeneratedComponents = [
|
|
296
301
|
// ThreeJS basics
|
|
@@ -403,21 +408,11 @@
|
|
|
403
408
|
'arrayCamera',
|
|
404
409
|
// renderers
|
|
405
410
|
'webGLRenderer',
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
});
|
|
410
|
-
const components = {
|
|
411
|
-
...autoGeneratedComponents,
|
|
412
|
-
'Lunchbox': LunchboxWrapper,
|
|
413
|
-
// Gltf,
|
|
414
|
-
};
|
|
415
|
-
// console.log(components, Gltf)
|
|
416
|
-
/*
|
|
417
|
-
// List copied from r3f
|
|
418
|
-
// https://github.com/pmndrs/react-three-fiber/blob/master/packages/fiber/src/three-types.ts
|
|
411
|
+
/*
|
|
412
|
+
// List copied from r3f:
|
|
413
|
+
// https://github.com/pmndrs/react-three-fiber/blob/master/packages/fiber/src/three-types.ts
|
|
419
414
|
|
|
420
|
-
|
|
415
|
+
// NOT IMPLEMENTED (can be added via Extend - docs.lunchboxjs.com/components/extend/):
|
|
421
416
|
audioListener: AudioListenerProps
|
|
422
417
|
positionalAudio: PositionalAudioProps
|
|
423
418
|
|
|
@@ -465,6 +460,27 @@
|
|
|
465
460
|
fogExp2: FogExp2Props
|
|
466
461
|
shape: ShapeProps
|
|
467
462
|
*/
|
|
463
|
+
];
|
|
464
|
+
|
|
465
|
+
const catalogue = {};
|
|
466
|
+
|
|
467
|
+
const lunchboxDomComponentNames = ['canvas', 'div', 'LunchboxWrapper'];
|
|
468
|
+
// component creation utility
|
|
469
|
+
const createComponent$1 = (tag) => vue.defineComponent({
|
|
470
|
+
inheritAttrs: false,
|
|
471
|
+
name: tag,
|
|
472
|
+
setup(props, context) {
|
|
473
|
+
return () => vue.h(tag, context.attrs, context.slots?.default?.() || []);
|
|
474
|
+
},
|
|
475
|
+
});
|
|
476
|
+
autoGeneratedComponents.map(createComponent$1).reduce((acc, curr) => {
|
|
477
|
+
acc[curr.name] = curr;
|
|
478
|
+
return acc;
|
|
479
|
+
});
|
|
480
|
+
const components = {
|
|
481
|
+
...autoGeneratedComponents,
|
|
482
|
+
Lunchbox: LunchboxWrapper,
|
|
483
|
+
};
|
|
468
484
|
|
|
469
485
|
function find(target) {
|
|
470
486
|
target = vue.isRef(target) ? target.value : target;
|
|
@@ -1258,6 +1274,16 @@
|
|
|
1258
1274
|
const rootNode = new MiniDom.RendererRootNode();
|
|
1259
1275
|
rootNode.minidomType = 'RootNode';
|
|
1260
1276
|
|
|
1277
|
+
const startCallbacks = [];
|
|
1278
|
+
const onStart = (cb, index = Infinity) => {
|
|
1279
|
+
if (index === Infinity) {
|
|
1280
|
+
startCallbacks.push(cb);
|
|
1281
|
+
}
|
|
1282
|
+
else {
|
|
1283
|
+
startCallbacks.splice(index, 0, cb);
|
|
1284
|
+
}
|
|
1285
|
+
};
|
|
1286
|
+
|
|
1261
1287
|
let frameID;
|
|
1262
1288
|
const beforeRender = [];
|
|
1263
1289
|
const afterRender = [];
|
|
@@ -1301,6 +1327,15 @@
|
|
|
1301
1327
|
beforeRender.splice(index, 0, cb);
|
|
1302
1328
|
}
|
|
1303
1329
|
};
|
|
1330
|
+
const offBeforeRender = (cb) => {
|
|
1331
|
+
if (isFinite(cb)) {
|
|
1332
|
+
beforeRender.splice(cb, 1);
|
|
1333
|
+
}
|
|
1334
|
+
else {
|
|
1335
|
+
const idx = beforeRender.findIndex((v) => v == cb);
|
|
1336
|
+
beforeRender.splice(idx, 1);
|
|
1337
|
+
}
|
|
1338
|
+
};
|
|
1304
1339
|
const onAfterRender = (cb, index = Infinity) => {
|
|
1305
1340
|
if (index === Infinity) {
|
|
1306
1341
|
afterRender.push(cb);
|
|
@@ -1309,6 +1344,15 @@
|
|
|
1309
1344
|
afterRender.splice(index, 0, cb);
|
|
1310
1345
|
}
|
|
1311
1346
|
};
|
|
1347
|
+
const offAfterRender = (cb) => {
|
|
1348
|
+
if (isFinite(cb)) {
|
|
1349
|
+
afterRender.splice(cb, 1);
|
|
1350
|
+
}
|
|
1351
|
+
else {
|
|
1352
|
+
const idx = afterRender.findIndex((v) => v == cb);
|
|
1353
|
+
afterRender.splice(idx, 1);
|
|
1354
|
+
}
|
|
1355
|
+
};
|
|
1312
1356
|
const cancelUpdate = () => {
|
|
1313
1357
|
if (frameID)
|
|
1314
1358
|
cancelAnimationFrame(frameID);
|
|
@@ -1662,9 +1706,51 @@
|
|
|
1662
1706
|
inputActive,
|
|
1663
1707
|
mousePos,
|
|
1664
1708
|
};
|
|
1709
|
+
/** The current camera. Often easier to use `useCamera` instead of this. */
|
|
1665
1710
|
const camera = vue.computed(() => ensuredCamera.value?.instance ?? null);
|
|
1711
|
+
/** Run a function using the current camera when it's present. */
|
|
1712
|
+
function useCamera(callback, once = true) {
|
|
1713
|
+
let destroy;
|
|
1714
|
+
destroy = vue.watch(camera, (newVal) => {
|
|
1715
|
+
if (!newVal)
|
|
1716
|
+
return;
|
|
1717
|
+
// TODO: better fix than `any`?
|
|
1718
|
+
callback(newVal);
|
|
1719
|
+
if (once) {
|
|
1720
|
+
destroy?.();
|
|
1721
|
+
}
|
|
1722
|
+
}, { immediate: true });
|
|
1723
|
+
}
|
|
1724
|
+
/** The current renderer. Often easier to use `useRenderer` instead of this. */
|
|
1666
1725
|
const renderer = vue.computed(() => ensureRenderer.value?.instance ?? null);
|
|
1726
|
+
/** Run a function using the current renderer when it's present. */
|
|
1727
|
+
function useRenderer(callback, once = true) {
|
|
1728
|
+
let destroy;
|
|
1729
|
+
destroy = vue.watch(renderer, (newVal) => {
|
|
1730
|
+
if (!newVal)
|
|
1731
|
+
return;
|
|
1732
|
+
// TODO: better fix than `any`?
|
|
1733
|
+
callback(newVal);
|
|
1734
|
+
if (once) {
|
|
1735
|
+
destroy?.();
|
|
1736
|
+
}
|
|
1737
|
+
}, { immediate: true });
|
|
1738
|
+
}
|
|
1739
|
+
/** The current scene. Often easier to use `useScene` instead of this. */
|
|
1667
1740
|
const scene = vue.computed(() => ensuredScene.value.instance);
|
|
1741
|
+
/** Run a function using the current scene when it's present. */
|
|
1742
|
+
function useScene(callback, once = true) {
|
|
1743
|
+
let destroy;
|
|
1744
|
+
destroy = vue.watch(scene, (newVal) => {
|
|
1745
|
+
if (!newVal)
|
|
1746
|
+
return;
|
|
1747
|
+
// TODO: better fix than `any`?
|
|
1748
|
+
callback(newVal);
|
|
1749
|
+
if (once) {
|
|
1750
|
+
destroy?.();
|
|
1751
|
+
}
|
|
1752
|
+
}, { immediate: true });
|
|
1753
|
+
}
|
|
1668
1754
|
// CUSTOM RENDER SUPPORT
|
|
1669
1755
|
// ====================
|
|
1670
1756
|
let app = null;
|
|
@@ -1736,11 +1822,17 @@
|
|
|
1736
1822
|
exports.createApp = createApp;
|
|
1737
1823
|
exports.find = find;
|
|
1738
1824
|
exports.globals = globals;
|
|
1825
|
+
exports.offAfterRender = offAfterRender;
|
|
1826
|
+
exports.offBeforeRender = offBeforeRender;
|
|
1739
1827
|
exports.onAfterRender = onAfterRender;
|
|
1740
1828
|
exports.onBeforeRender = onBeforeRender;
|
|
1829
|
+
exports.onStart = onStart;
|
|
1741
1830
|
exports.renderer = renderer;
|
|
1742
1831
|
exports.scene = scene;
|
|
1743
1832
|
exports.setCustomRender = setCustomRender;
|
|
1833
|
+
exports.useCamera = useCamera;
|
|
1834
|
+
exports.useRenderer = useRenderer;
|
|
1835
|
+
exports.useScene = useScene;
|
|
1744
1836
|
|
|
1745
1837
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
1746
1838
|
|
package/dist/lunchboxjs.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("vue"),require("three"),require("lodash")):"function"==typeof define&&define.amd?define(["exports","vue","three","lodash"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).LunchboxRenderer={},e.vue,e.three,e.lodash)}(this,(function(e,t,n,r){"use strict";function o(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,Object.freeze(t)}var a=o(n);const s=[],i=(e,n)=>{const r=I.value?.instance,o=K.value.instance,a=F.value;if(!r?.domElement||!o||!a)return;const s=(e=e??window.innerWidth)/(n=n??window.innerHeight);if("perspectivecamera"===a.type?.toLowerCase()){const e=a.instance;e.aspect=s,e.updateProjectionMatrix()}else if("orthographiccamera"===a.type?.toLowerCase()){const t=a.instance,r=n/e;t.top=10*r,t.bottom=10*-r,t.right=10,t.left=-10,t.updateProjectionMatrix()}else console.log("TODO: non-ortho or perspective camera");r.setSize(e,n),o&&a.instance&&r.render(t.toRaw(o),t.toRaw(a.instance))},c=e=>({position:e,top:0,right:0,bottom:0,left:0,width:"100%",height:"100%"}),d={name:"Lunchbox",props:{background:String,cameraArgs:Array,cameraPosition:Array,dpr:Number,ortho:Boolean,orthographic:Boolean,rendererProperties:Object,shadow:[Boolean,Object],transparent:Boolean},setup(e,o){const a=t.ref(),s=t.ref(!0),d=t.ref(e.dpr??-1),u=t.ref();let l,p,m;return t.onMounted((()=>{if(!a.value)throw new Error("missing canvas");if(l=N(["WebGLRenderer"]),l)return s.value=!1,void(W.value=!0);{const t={antialias:!0,canvas:a.value.domElement};e.transparent&&(t.alpha=!0),I.value=v({type:"WebGLRenderer",uuid:$,props:{args:[t]}}),W.value=!0;const n=I,o={shadow:e.shadow};n.value.instance&&o?.shadow&&(n.value.instance.shadowMap.enabled=!0,"object"==typeof o.shadow&&(n.value.instance.shadowMap.type=o.shadow.type)),e.rendererProperties&&Object.keys(e.rendererProperties).forEach((t=>{r.set(n.value,t,e.rendererProperties[t])})),l=n.value}if(p=N(["PerspectiveCamera","OrthographicCamera"]),p?D.value=!0:(e.ortho||e.orthographic?F.value=v({props:{args:e.cameraArgs??[]},type:"OrthographicCamera",uuid:k}):F.value=v({props:{args:e.cameraArgs??[45,.5625,1,1e3]},type:"PerspectiveCamera",uuid:k}),D.value=!0,p=F.value),p&&e.cameraPosition&&p.instance?.position.set(...e.cameraPosition),m=K.value,m&&m.instance&&e.background&&(m.instance.background=new n.Color(e.background)),-1===d.value&&(d.value=window.devicePixelRatio),!l?.instance)throw new Error("missing renderer");l.instance.setPixelRatio(d.value),me.dpr.value=d.value,((e,t,n)=>{const r=e.value?.domElement;if(!r)throw new Error("missing container");i();const o=new ResizeObserver((([e])=>{i()}));r&&o.observe(r),n((()=>{t&&o.unobserve(t)}))})(u,l.instance.domElement,t.onBeforeUnmount),oe({app:t.getCurrentInstance().appContext.app,camera:p.instance,renderer:l.instance,scene:m.instance})})),t.onBeforeUnmount((()=>{se()})),()=>[o.slots.default?.()??null,t.h("div",{style:c("absolute"),ref:u},[s.value?t.h("canvas",{style:c("fixed"),class:"lunchbox-canvas",ref:a}):null])]}},u={},l=["canvas","div","LunchboxWrapper"],p={...["mesh","instancedMesh","scene","sprite","object3D","instancedBufferGeometry","bufferGeometry","boxBufferGeometry","circleBufferGeometry","coneBufferGeometry","cylinderBufferGeometry","dodecahedronBufferGeometry","extrudeBufferGeometry","icosahedronBufferGeometry","latheBufferGeometry","octahedronBufferGeometry","parametricBufferGeometry","planeBufferGeometry","polyhedronBufferGeometry","ringBufferGeometry","shapeBufferGeometry","sphereBufferGeometry","tetrahedronBufferGeometry","textBufferGeometry","torusBufferGeometry","torusKnotBufferGeometry","tubeBufferGeometry","wireframeGeometry","parametricGeometry","tetrahedronGeometry","octahedronGeometry","icosahedronGeometry","dodecahedronGeometry","polyhedronGeometry","tubeGeometry","torusKnotGeometry","torusGeometry","sphereGeometry","ringGeometry","planeGeometry","latheGeometry","shapeGeometry","extrudeGeometry","edgesGeometry","coneGeometry","cylinderGeometry","circleGeometry","boxGeometry","material","shadowMaterial","spriteMaterial","rawShaderMaterial","shaderMaterial","pointsMaterial","meshPhysicalMaterial","meshStandardMaterial","meshPhongMaterial","meshToonMaterial","meshNormalMaterial","meshLambertMaterial","meshDepthMaterial","meshDistanceMaterial","meshBasicMaterial","meshMatcapMaterial","lineDashedMaterial","lineBasicMaterial","light","spotLightShadow","spotLight","pointLight","rectAreaLight","hemisphereLight","directionalLightShadow","directionalLight","ambientLight","lightShadow","ambientLightProbe","hemisphereLightProbe","lightProbe","texture","videoTexture","dataTexture","dataTexture3D","compressedTexture","cubeTexture","canvasTexture","depthTexture","textureLoader","group","catmullRomCurve3","points","cameraHelper","camera","perspectiveCamera","orthographicCamera","cubeCamera","arrayCamera","webGLRenderer"].map((e=>t.defineComponent({inheritAttrs:!1,name:e,setup:(n,r)=>()=>t.h(e,r.attrs,r.slots?.default?.()||[])}))).reduce(((e,t)=>(e[t.name]=t,e))),Lunchbox:d};const m=e=>e?.$el&&e?.$el?.hasOwnProperty?.("instance"),h=e=>{if("domMeta"===e?.metaType)return!0;const t="string"==typeof e?e:e?.type;return l.includes(t??"")},f=e=>"standardMeta"===e?.metaType,y=e=>e.isLunchboxRootNode;function v(e={},t={}){const n={attached:e.attached??[],attachedArray:e.attachedArray??{},instance:e.instance??null},r=new J.RendererStandardNode({...e,...n,metaType:"standardMeta"});return!r.type||y(r)||r.instance||(r.instance=function(e){if(!e.type)return null;const t=e.type[0].toUpperCase()+e.type.slice(1),n=u[e.type]||a[t];if(!n)throw`${t} is not part of the THREE namespace! Did you forget to extend? import {extend} from 'lunchbox'; extend({app, YourComponent, ...})`;const r=(e.props.args??[]).map((t=>function({node:e,prop:t}){const n="string"==typeof t&&t.startsWith("$attachedArray"),r=function({node:e,prop:t}){if("string"==typeof t&&t.startsWith("$attachedArray"))return e.attachedArray[t.replace("$attachedArray.","")];if("string"==typeof t&&t.startsWith("$attached"))return e.attached[t.replace("$attached.","")];return t}({node:e,prop:t});return Array.isArray(r)&&n?r:[r]}({node:e,prop:t})));let o=[];r.forEach((e=>{o=o.concat(e)}));return new n(...o)}({...r,props:{...r.props,...t}})),"scene"===r.type&&(K.value=r),r}const g=[],b=t.ref(!1);function x({node:e,key:n,value:r}){var o;if(e.eventListeners[n]||(e.eventListeners[n]=[]),e.eventListenerRemoveFunctions[n]||(e.eventListenerRemoveFunctions[n]=[]),e.eventListeners[n].push(r),R.includes(n)&&(_.value,e.instance&&!g.includes(e)&&(o=e,g.push(o),e.eventListenerRemoveFunctions[n].push((()=>(e=>{const t=g.indexOf(e);-1!==t&&g.splice(t,1)})(e))))),"onClick"===n||"onPointerDown"===n||"onPointerUp"===n){const r=t.watch((()=>b.value),(t=>{const r=P.map((e=>e.element)).findIndex((t=>t.instance&&t.instance.uuid===e.instance?.uuid));-1!==r&&((!t||"onClick"!==n&&"onPointerDown"!==n)&&(t||"onPointerUp"!==n)||e.eventListeners[n].forEach((e=>{e({intersection:P[r].intersection})})))}));e.eventListenerRemoveFunctions[n].push(r)}return e}const R=["onClick","onPointerUp","onPointerDown","onPointerOver","onPointerOut","onPointerEnter","onPointerLeave","onPointerMove"];let w,C,E;const A=t.ref({x:1/0,y:1/0});let L=!1;let P=[];const M=()=>{const e=_.value?.instance,t=F.value?.instance;if(!e||!t)return;e.setFromCamera(me.mousePos.value,t);const n=e.intersectObjects(g.map((e=>e.instance)));let r=[],o=[],a=[];r=P.map((e=>e.intersection)),n?.forEach((e=>{const t=P.findIndex((t=>t.intersection.object===e.object));if(-1===t){const t=g.find((t=>t.instance?.uuid===e.object.uuid));t&&o.push({element:t,intersection:e})}else{const t=g.find((t=>t.instance?.uuid===e.object.uuid));t&&a.push({element:t,intersection:e})}const n=r.findIndex((t=>t.object.uuid===e.object.uuid));-1!==n&&r.splice(n,1)}));const s=r.map((e=>({element:g.find((t=>t.instance?.uuid===e.object.uuid)),intersection:e})));o.forEach((({element:e,intersection:t})=>{B({element:e,eventKeys:["onPointerEnter"],intersection:t})})),a.forEach((({element:e,intersection:t})=>{B({element:e,eventKeys:["onPointerOver","onPointerMove"],intersection:t})})),s.forEach((({element:e,intersection:t})=>{B({element:e,eventKeys:["onPointerLeave","onPointerOut"],intersection:t})})),P=[].concat(o,a)},B=({element:e,eventKeys:t,intersection:n})=>{e&&t.forEach((t=>{e.eventListeners[t]&&e.eventListeners[t].forEach((e=>{e({intersection:n})}))}))};function G(t={}){return e.lunchboxTree||(e.lunchboxTree=new J.RendererRootNode(t)),e.lunchboxTree}function N(e){Array.isArray(e)||(e=[e]);for(let t of e)if(O[t])return O[t];for(let t of e){const e=T[t]||s.find((e=>e.type?.toLowerCase()===t.toLowerCase()));if(e){const n=e;return T[t]=n,n}}return null}e.lunchboxTree=void 0;const T=t.reactive({}),O=t.reactive({});function j(e,n,r={},o=null){Array.isArray(e)||(e=[e]);for(let t of e)T[t]||(T[t]=null),O[t]||(O[t]=null);return t.computed({get(){const t=N(e);if(t)return t;const a=G(),s=v({type:e[0],uuid:n,props:r});return a.addChild(s),T[e[0]]=s,o&&o(s),s},set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);O[n]=e}})}const k="FALLBACK_CAMERA",S=j(["PerspectiveCamera","OrthographicCamera"],k,{args:[45,.5625,1,1e3]}),D=t.ref(!1),F=t.computed({get:()=>D.value?S.value:null,set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);O[n]=e}}),$="FALLBACK_RENDERER",U=j(["WebGLRenderer"],$,{}),W=t.ref(!1),I=t.computed({get:()=>W.value?U.value:null,set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);O[n]=e}}),K=j("Scene","FALLBACK_SCENE"),_=j("Raycaster","AUTO_RAYCASTER",{},(e=>(e=>{if(!e.instance)return;let n=null;n=t.watch((()=>I.value),(e=>{e?.instance&&(L||(w=t=>{const n=(e.instance.domElement.width??1)/me.dpr.value,r=(e.instance.domElement.height??1)/me.dpr.value;A.value.x=t.offsetX/n*2-1,A.value.y=-t.offsetY/r*2+1},C=()=>b.value=!0,E=()=>b.value=!1,e.instance.domElement.addEventListener("mousemove",w),e.instance.domElement.addEventListener("mousedown",C),e.instance.domElement.addEventListener("mouseup",E),ae(M),L=!0),n&&n())}),{immediate:!0})})(e))),V=e=>t.defineComponent({inheritAttrs:!1,name:e,render(){return t.h(e,this.$attrs,this.$slots?.default?.()||[])}});var q,z=new Uint8Array(16);function H(){if(!q&&!(q="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return q(z)}var Y=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function X(e){return"string"==typeof e&&Y.test(e)}for(var J,Q=[],Z=0;Z<256;++Z)Q.push((Z+256).toString(16).substr(1));function ee(e,t,n){var r=(e=e||{}).random||(e.rng||H)();if(r[6]=15&r[6]|64,r[8]=63&r[8]|128,t){n=n||0;for(var o=0;o<16;++o)t[n+o]=r[o];return t}return function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=(Q[e[t+0]]+Q[e[t+1]]+Q[e[t+2]]+Q[e[t+3]]+"-"+Q[e[t+4]]+Q[e[t+5]]+"-"+Q[e[t+6]]+Q[e[t+7]]+"-"+Q[e[t+8]]+Q[e[t+9]]+"-"+Q[e[t+10]]+Q[e[t+11]]+Q[e[t+12]]+Q[e[t+13]]+Q[e[t+14]]+Q[e[t+15]]).toLowerCase();if(!X(n))throw TypeError("Stringified UUID is invalid");return n}(r)}!function(e){e.BaseNode=class{constructor(e={},t){this.parentNode=e?.parentNode??t??null,this.minidomType="MinidomBaseNode",this.uuid=e?.uuid??ee(),s.push(this)}uuid;parentNode;get nextSibling(){if(!this.parentNode)return null;const e=this.parentNode.children.findIndex((e=>e.uuid===this.uuid));return-1!==e&&e<this.parentNode.children.length-1?this.parentNode.children[e+1]:null}insertBefore(e,t){e.removeAsChildFromAnyParents(),e.parentNode=this;const n=this.children.findIndex((e=>e.uuid===t?.uuid));-1!==n?this.children.splice(n,0,e):this.children.push(e)}removeChild(e){const t=this.children.findIndex((t=>t?.uuid===e?.uuid));-1!==t&&this.children.splice(t,1)}children=[];addChild(e){return e&&(e.removeAsChildFromAnyParents(),e.parentNode=this,this.insertBefore(e,null)),this}getPath(){const e=[];let t=this;for(;t;)e.unshift(t),t=t.parentNode;return e}drop(){this.parentNode=null,this.removeAsChildFromAnyParents()}walk(e){const t=[this,...this.children],n=[];let r=!0;for(;t.length&&r;){const o=t.shift();if(o){if(n.includes(o))continue;n.push(o),t.push(...o.children.filter((e=>!n.includes(e)))),r=e(o)}else r=!1}}minidomType;removeAsChildFromAnyParents(){s.forEach((e=>e.removeChild(this)))}};class t extends e.BaseNode{constructor(e={},t){super(e,t),this.minidomType="RendererNode",this.eventListeners={},this.eventListenerRemoveFunctions={},this.name=e.name??"",this.metaType=e.metaType??"standardMeta",this.props=e.props??[],this.type=e.type??""}eventListeners;eventListenerRemoveFunctions;name;metaType;props;type;drop(){super.drop(),Object.keys(this.eventListenerRemoveFunctions).forEach((e=>{this.eventListenerRemoveFunctions[e].forEach((e=>e()))}))}}e.RendererBaseNode=t;class n extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.domElement=e.domElement??document.createElement("div")}domElement;isLunchboxRootNode=!0}e.RendererRootNode=n;class r extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.text=e.text??""}text}e.RendererCommentNode=r;class o extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.domElement=e.domElement??document.createElement("div")}domElement}e.RendererDomNode=o;class a extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.text=e.text??""}text}e.RendererTextNode=a;class i extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.attached=e.attached??[],this.attachedArray=e.attachedArray??{},this.instance=e.instance??null}attached;attachedArray;instance}e.RendererStandardNode=i}(J||(J={}));let te;(new J.RendererRootNode).minidomType="RootNode";const ne=[],re=[],oe=e=>{te=requestAnimationFrame((()=>oe({app:e.app,renderer:I.value?.instance,scene:K.value.instance,camera:F.value?.instance})));const{app:n,renderer:r,scene:o,camera:a}=e;ne.forEach((t=>{t&&t(e)})),r&&o&&a&&(n.customRender?n.customRender(e):r.render(t.toRaw(o),t.toRaw(a))),re.forEach((t=>{t&&t(e)}))},ae=(e,t=1/0)=>{t===1/0?ne.push(e):ne.splice(t,0,e)},se=()=>{te&&cancelAnimationFrame(te)};const ie={x:"position.x",y:"position.y",z:"position.z"},ce=["","parameters"],de=["args","attach","attachArray","key","onAdded","ref","src"],ue=["geometry","material"];function le(e,t,n,r){const o=r??e.instance,a=t.instance;e.props.attach===n&&(t.attached={[n]:o,...t.attached||{}},a[n]=r??e.instance),e.props.attachArray===n&&(t.attachedArray[e.props.attachArray]||(t.attachedArray[e.props.attachArray]=[]),t.attachedArray[e.props.attachArray].push(o),a[n]=[a[n]])}const pe={createElement:(e,t,n,r)=>{const o={type:e};r&&(o.props=r);if(h(e)){const e=function(e={}){const t={domElement:document.createElement(e.type??"")};return new J.RendererDomNode({...t,...e,metaType:"domMeta"})}(o);return e}const a=v(o);return ue.forEach((t=>{e.toLowerCase().endsWith(t)&&(a.props.attach=t)})),a},createText:e=>function(e={}){const t={text:e.text??""};return new J.RendererTextNode({...e,...t,metaType:"textMeta"})}({text:e}),createComment:e=>function(e={}){const t={text:e.text??""};return new J.RendererCommentNode({...t,...e,metaType:"commentMeta"})}({text:e}),insert:(e,t,n)=>{let r=t??G();if(r.insertBefore(e,n),"commentMeta"!==e.metaType&&"textMeta"!==e.metaType&&(h(e)&&(h(t)||y(t))&&t.domElement.appendChild(e.domElement),f(e))){let n=r.metaType;if("textMeta"===n||"commentMeta"===n){const e=r.getPath();for(let t=e.length-1;t>=0;t--)if("textMeta"!==e[t].metaType&&"commentMeta"!==e[t].metaType){r=e[t];break}}if("standardMeta"===e.metaType&&"scene"!==e.type&&y(r)){const t=K.value;t.instance&&e&&t.addChild(e),e.instance&&e.instance.isObject3D&&t.instance&&t!==e&&t.instance.add(e.instance)}else f(e)&&e.instance?.isObject3D&&f(r)&&r.instance?.isObject3D&&r.instance?.add?.(e.instance);if(e?.props?.attach&&f(t)&&t?.instance){e.type?.toLowerCase().endsWith("loader")&&e.props.src&&(e.props.attach||e.props.attachArray)?function(e,t){const n=e.instance;if(t.attached=t.attached||{},t.attachedArray=t.attachedArray||{},!e.props.attach)return;if("textureloader"===e.type?.toLowerCase()){const r=n.load(e.props.src);le(e,t,e.props.attach,r)}else n.load(e.props.src,(n=>{le(e,t,e.props.attach,n)}),null,(e=>{throw new Error(e)}))}(e,t):le(e,t,e.props.attach)}e.props?.onAdded&&e.props.onAdded({instance:e.instance})}},nextSibling(e){const t=e.nextSibling;return t||null},parentNode(e){const t=e.parentNode;return t||null},patchProp(e,t,n,o){h(e)?"style"===t?Object.keys(o).forEach((t=>{e.domElement.style[t]=o[t]})):e.domElement.setAttribute(t,o):y(e)||t.startsWith("$")||function({node:e,key:t,value:n}){if((e=>["onClick","onContextMenu","onDoubleClick","onPointerUp","onPointerDown","onPointerOver","onPointerOut","onPointerEnter","onPointerLeave","onPointerMove","onWheel"].includes(e))(t))return x({node:e,key:t,value:n});if(de.includes(t))return e;if(!f(e))return e;if("string"==typeof n&&n.startsWith("$attached")){const t=n.replace("$attached.","");n=r.get(e.attached,t,null)}const o=e.instance;if(!o)return e;const a=t.replace(/-/g,".");let s,i=ie[a]||a;for(let e=0;e<ce.length&&!s;e++){const t=[ce[e],i].filter(Boolean).join(".");s=s=r.get(o,t)}if(s&&r.isNumber(n)&&s.setScalar)s.setScalar(n);else if(s&&s.set){const e=Array.isArray(n)?n:[n];o[i].set(...e)}else"function"==typeof s?s.bind(e.instance)(...n):void 0!==r.get(o,i,void 0)?r.set(o,i,""===n||n):console.log(`No property ${i} found on ${o}`);const c=o?.texture?.type||o?.type;if("string"==typeof c){const e=c.toLowerCase();switch(!0){case e.includes("material"):o.needsUpdate=!0;break;case e.includes("camera")&&o.updateProjectionMatrix:o.updateProjectionMatrix()}}}({node:e,key:t,value:o})},remove:e=>{if(!e)return;const t=Object.keys(O),n=[];e.walk((e=>(n.push(e),!0))),n.forEach((e=>{const n=t.find((t=>O[t]?.uuid===e.uuid));if(n&&(O[n]=null),f(e)){e.instance?.removeFromParent?.();const t="scene"!==e.type&&e.instance?.dispose;t&&t.bind(e.instance)(),e.instance=null}e.drop();const r=s.findIndex((t=>t.uuid===e.uuid));-1!==r&&s.splice(r,1)}))},setElementText(){},setText(){}},me={dpr:t.ref(1),inputActive:b,mousePos:A},he=t.computed((()=>F.value?.instance??null)),fe=t.computed((()=>I.value?.instance??null)),ye=t.computed((()=>K.value.instance));let ve=null,ge=null;e.camera=he,e.clearCustomRender=()=>{ve?ve.clearCustomRender():ge=null},e.createApp=e=>{ve=t.createRenderer(pe).createApp(e),Object.keys(p).forEach((e=>{ve.component(e,p[e])}));const{mount:n}=ve;return ve.mount=(e,...t)=>{const r=G({domElement:"string"==typeof e?document.querySelector(e):e,isLunchboxRootNode:!0,name:"root",metaType:"rootMeta",type:"root",uuid:"LUNCHBOX_ROOT"});ve.rootNode=r;return n(r,...t)},ve.extend=e=>((({app:e,...t})=>{Object.keys(t).forEach((n=>{e.component(n,V(n)),u[n]=t[n]}))})({app:ve,...e}),ve),ve.setCustomRender=e=>{ve.customRender=e},ge&&(ve.setCustomRender(ge),ge=null),ve.clearCustomRender=()=>{ve.customRender=null},ve},e.find=function(e){return e=t.isRef(e)?e.value:e,f(e)?e?.instance:m(e)?e?.$el?.instance:t.isVNode(e)?e.el?.instance:null},e.globals=me,e.onAfterRender=(e,t=1/0)=>{t===1/0?re.push(e):re.splice(t,0,e)},e.onBeforeRender=ae,e.renderer=fe,e.scene=ye,e.setCustomRender=e=>{ve?ve.setCustomRender(e):ge=e},Object.defineProperty(e,"__esModule",{value:!0})}));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("vue"),require("three"),require("lodash")):"function"==typeof define&&define.amd?define(["exports","vue","three","lodash"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).LunchboxRenderer={},e.vue,e.three,e.lodash)}(this,(function(e,t,n,r){"use strict";function o(e){if(e&&e.__esModule)return e;var t=Object.create(null);return e&&Object.keys(e).forEach((function(n){if("default"!==n){var r=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,r.get?r:{enumerable:!0,get:function(){return e[n]}})}})),t.default=e,Object.freeze(t)}var a=o(n);const s=[],i=(e,n)=>{const r=K.value?.instance,o=_.value.instance,a=$.value;if(!r?.domElement||!o||!a)return;const s=(e=e??window.innerWidth)/(n=n??window.innerHeight);if("perspectivecamera"===a.type?.toLowerCase()){const e=a.instance;e.aspect=s,e.updateProjectionMatrix()}else if("orthographiccamera"===a.type?.toLowerCase()){const t=a.instance,r=n/e;t.top=10*r,t.bottom=10*-r,t.right=10,t.left=-10,t.updateProjectionMatrix()}else console.log("TODO: non-ortho or perspective camera");r.setSize(e,n),o&&a.instance&&r.render(t.toRaw(o),t.toRaw(a.instance))},c=e=>({position:e,top:0,right:0,bottom:0,left:0,width:"100%",height:"100%"}),d={name:"Lunchbox",props:{background:String,cameraArgs:Array,cameraLook:Array,cameraLookAt:Array,cameraPosition:Array,dpr:Number,ortho:Boolean,orthographic:Boolean,rendererArguments:Object,rendererProperties:Object,shadow:[Boolean,Object],transparent:Boolean},setup(e,o){const a=t.ref(),s=t.ref(!0),d=t.ref(e.dpr??-1),u=t.ref();let l,p,m;return t.onMounted((()=>{if(!a.value)throw new Error("missing canvas");if(l=T(["WebGLRenderer"]),l)s.value=!1,I.value=!0;else{const t={alpha:e.transparent,antialias:!0,canvas:a.value.domElement,...e.rendererArguments??{}};K.value=g({type:"WebGLRenderer",uuid:U,props:{args:[t]}}),I.value=!0;const n=K,o={shadow:e.shadow};n.value.instance&&o?.shadow&&(n.value.instance.shadowMap.enabled=!0,"object"==typeof o.shadow&&(n.value.instance.shadowMap.type=o.shadow.type)),e.rendererProperties&&Object.keys(e.rendererProperties).forEach((t=>{r.set(n.value,t,e.rendererProperties[t])})),l=n.value}if(p=T(["PerspectiveCamera","OrthographicCamera"]),p?D.value=!0:(e.ortho||e.orthographic?$.value=g({props:{args:e.cameraArgs??[]},type:"OrthographicCamera",uuid:S}):$.value=g({props:{args:e.cameraArgs??[45,.5625,1,1e3]},type:"PerspectiveCamera",uuid:S}),D.value=!0,p=$.value),!p.instance)throw new Error("Error creating camera.");if(p&&e.cameraPosition&&p.instance.position.set(...e.cameraPosition),p&&(e.cameraLookAt||e.cameraLook)){const t=e.cameraLookAt||e.cameraLook;p.instance.lookAt(...t)}if(m=_.value,m&&m.instance&&e.background&&(m.instance.background=new n.Color(e.background)),-1===d.value&&(d.value=window.devicePixelRatio),!l?.instance)throw new Error("missing renderer");l.instance.setPixelRatio(d.value),fe.dpr.value=d.value,((e,t,n)=>{const r=e.value?.domElement;if(!r)throw new Error("missing container");i();const o=new ResizeObserver((([e])=>{i()}));r&&o.observe(r),n((()=>{t&&o.unobserve(t)}))})(u,l.instance.domElement,t.onBeforeUnmount);const o=t.getCurrentInstance().appContext.app;for(let e of ne)e({app:o,camera:p.instance,renderer:l.instance,scene:m.instance});se({app:o,camera:p.instance,renderer:l.instance,scene:m.instance})})),t.onBeforeUnmount((()=>{ce()})),()=>[o.slots.default?.()??null,t.h("div",{style:c("absolute"),ref:u},[s.value?t.h("canvas",{style:c("fixed"),class:"lunchbox-canvas",ref:a}):null])]}},u=["mesh","instancedMesh","scene","sprite","object3D","instancedBufferGeometry","bufferGeometry","boxBufferGeometry","circleBufferGeometry","coneBufferGeometry","cylinderBufferGeometry","dodecahedronBufferGeometry","extrudeBufferGeometry","icosahedronBufferGeometry","latheBufferGeometry","octahedronBufferGeometry","parametricBufferGeometry","planeBufferGeometry","polyhedronBufferGeometry","ringBufferGeometry","shapeBufferGeometry","sphereBufferGeometry","tetrahedronBufferGeometry","textBufferGeometry","torusBufferGeometry","torusKnotBufferGeometry","tubeBufferGeometry","wireframeGeometry","parametricGeometry","tetrahedronGeometry","octahedronGeometry","icosahedronGeometry","dodecahedronGeometry","polyhedronGeometry","tubeGeometry","torusKnotGeometry","torusGeometry","sphereGeometry","ringGeometry","planeGeometry","latheGeometry","shapeGeometry","extrudeGeometry","edgesGeometry","coneGeometry","cylinderGeometry","circleGeometry","boxGeometry","material","shadowMaterial","spriteMaterial","rawShaderMaterial","shaderMaterial","pointsMaterial","meshPhysicalMaterial","meshStandardMaterial","meshPhongMaterial","meshToonMaterial","meshNormalMaterial","meshLambertMaterial","meshDepthMaterial","meshDistanceMaterial","meshBasicMaterial","meshMatcapMaterial","lineDashedMaterial","lineBasicMaterial","light","spotLightShadow","spotLight","pointLight","rectAreaLight","hemisphereLight","directionalLightShadow","directionalLight","ambientLight","lightShadow","ambientLightProbe","hemisphereLightProbe","lightProbe","texture","videoTexture","dataTexture","dataTexture3D","compressedTexture","cubeTexture","canvasTexture","depthTexture","textureLoader","group","catmullRomCurve3","points","cameraHelper","camera","perspectiveCamera","orthographicCamera","cubeCamera","arrayCamera","webGLRenderer"],l={},p=["canvas","div","LunchboxWrapper"];u.map((e=>t.defineComponent({inheritAttrs:!1,name:e,setup:(n,r)=>()=>t.h(e,r.attrs,r.slots?.default?.()||[])}))).reduce(((e,t)=>(e[t.name]=t,e)));const m={...u,Lunchbox:d};const h=e=>e?.$el&&e?.$el?.hasOwnProperty?.("instance"),f=e=>{if("domMeta"===e?.metaType)return!0;const t="string"==typeof e?e:e?.type;return p.includes(t??"")},y=e=>"standardMeta"===e?.metaType,v=e=>e.isLunchboxRootNode;function g(e={},t={}){const n={attached:e.attached??[],attachedArray:e.attachedArray??{},instance:e.instance??null},r=new Q.RendererStandardNode({...e,...n,metaType:"standardMeta"});return!r.type||v(r)||r.instance||(r.instance=function(e){if(!e.type)return null;const t=e.type[0].toUpperCase()+e.type.slice(1),n=l[e.type]||a[t];if(!n)throw`${t} is not part of the THREE namespace! Did you forget to extend? import {extend} from 'lunchbox'; extend({app, YourComponent, ...})`;const r=(e.props.args??[]).map((t=>function({node:e,prop:t}){const n="string"==typeof t&&t.startsWith("$attachedArray"),r=function({node:e,prop:t}){if("string"==typeof t&&t.startsWith("$attachedArray"))return e.attachedArray[t.replace("$attachedArray.","")];if("string"==typeof t&&t.startsWith("$attached"))return e.attached[t.replace("$attached.","")];return t}({node:e,prop:t});return Array.isArray(r)&&n?r:[r]}({node:e,prop:t})));let o=[];r.forEach((e=>{o=o.concat(e)}));return new n(...o)}({...r,props:{...r.props,...t}})),"scene"===r.type&&(_.value=r),r}const b=[],x=t.ref(!1);function R({node:e,key:n,value:r}){var o;if(e.eventListeners[n]||(e.eventListeners[n]=[]),e.eventListenerRemoveFunctions[n]||(e.eventListenerRemoveFunctions[n]=[]),e.eventListeners[n].push(r),w.includes(n)&&(V.value,e.instance&&!b.includes(e)&&(o=e,b.push(o),e.eventListenerRemoveFunctions[n].push((()=>(e=>{const t=b.indexOf(e);-1!==t&&b.splice(t,1)})(e))))),"onClick"===n||"onPointerDown"===n||"onPointerUp"===n){const r=t.watch((()=>x.value),(t=>{const r=M.map((e=>e.element)).findIndex((t=>t.instance&&t.instance.uuid===e.instance?.uuid));-1!==r&&((!t||"onClick"!==n&&"onPointerDown"!==n)&&(t||"onPointerUp"!==n)||e.eventListeners[n].forEach((e=>{e({intersection:M[r].intersection})})))}));e.eventListenerRemoveFunctions[n].push(r)}return e}const w=["onClick","onPointerUp","onPointerDown","onPointerOver","onPointerOut","onPointerEnter","onPointerLeave","onPointerMove"];let A,C,E;const L=t.ref({x:1/0,y:1/0});let P=!1;let M=[];const B=()=>{const e=V.value?.instance,t=$.value?.instance;if(!e||!t)return;e.setFromCamera(fe.mousePos.value,t);const n=e.intersectObjects(b.map((e=>e.instance)));let r=[],o=[],a=[];r=M.map((e=>e.intersection)),n?.forEach((e=>{const t=M.findIndex((t=>t.intersection.object===e.object));if(-1===t){const t=b.find((t=>t.instance?.uuid===e.object.uuid));t&&o.push({element:t,intersection:e})}else{const t=b.find((t=>t.instance?.uuid===e.object.uuid));t&&a.push({element:t,intersection:e})}const n=r.findIndex((t=>t.object.uuid===e.object.uuid));-1!==n&&r.splice(n,1)}));const s=r.map((e=>({element:b.find((t=>t.instance?.uuid===e.object.uuid)),intersection:e})));o.forEach((({element:e,intersection:t})=>{G({element:e,eventKeys:["onPointerEnter"],intersection:t})})),a.forEach((({element:e,intersection:t})=>{G({element:e,eventKeys:["onPointerOver","onPointerMove"],intersection:t})})),s.forEach((({element:e,intersection:t})=>{G({element:e,eventKeys:["onPointerLeave","onPointerOut"],intersection:t})})),M=[].concat(o,a)},G=({element:e,eventKeys:t,intersection:n})=>{e&&t.forEach((t=>{e.eventListeners[t]&&e.eventListeners[t].forEach((e=>{e({intersection:n})}))}))};function N(t={}){return e.lunchboxTree||(e.lunchboxTree=new Q.RendererRootNode(t)),e.lunchboxTree}function T(e){Array.isArray(e)||(e=[e]);for(let t of e)if(j[t])return j[t];for(let t of e){const e=O[t]||s.find((e=>e.type?.toLowerCase()===t.toLowerCase()));if(e){const n=e;return O[t]=n,n}}return null}e.lunchboxTree=void 0;const O=t.reactive({}),j=t.reactive({});function k(e,n,r={},o=null){Array.isArray(e)||(e=[e]);for(let t of e)O[t]||(O[t]=null),j[t]||(j[t]=null);return t.computed({get(){const t=T(e);if(t)return t;const a=N(),s=g({type:e[0],uuid:n,props:r});return a.addChild(s),O[e[0]]=s,o&&o(s),s},set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);j[n]=e}})}const S="FALLBACK_CAMERA",F=k(["PerspectiveCamera","OrthographicCamera"],S,{args:[45,.5625,1,1e3]}),D=t.ref(!1),$=t.computed({get:()=>D.value?F.value:null,set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);j[n]=e}}),U="FALLBACK_RENDERER",W=k(["WebGLRenderer"],U,{}),I=t.ref(!1),K=t.computed({get:()=>I.value?W.value:null,set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);j[n]=e}}),_=k("Scene","FALLBACK_SCENE"),V=k("Raycaster","AUTO_RAYCASTER",{},(e=>(e=>{if(!e.instance)return;let n=null;n=t.watch((()=>K.value),(e=>{e?.instance&&(P||(A=t=>{const n=(e.instance.domElement.width??1)/fe.dpr.value,r=(e.instance.domElement.height??1)/fe.dpr.value;L.value.x=t.offsetX/n*2-1,L.value.y=-t.offsetY/r*2+1},C=()=>x.value=!0,E=()=>x.value=!1,e.instance.domElement.addEventListener("mousemove",A),e.instance.domElement.addEventListener("mousedown",C),e.instance.domElement.addEventListener("mouseup",E),ie(B),P=!0),n&&n())}),{immediate:!0})})(e))),q=e=>t.defineComponent({inheritAttrs:!1,name:e,render(){return t.h(e,this.$attrs,this.$slots?.default?.()||[])}});var z,H=new Uint8Array(16);function Y(){if(!z&&!(z="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return z(H)}var X=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function J(e){return"string"==typeof e&&X.test(e)}for(var Q,Z=[],ee=0;ee<256;++ee)Z.push((ee+256).toString(16).substr(1));function te(e,t,n){var r=(e=e||{}).random||(e.rng||Y)();if(r[6]=15&r[6]|64,r[8]=63&r[8]|128,t){n=n||0;for(var o=0;o<16;++o)t[n+o]=r[o];return t}return function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=(Z[e[t+0]]+Z[e[t+1]]+Z[e[t+2]]+Z[e[t+3]]+"-"+Z[e[t+4]]+Z[e[t+5]]+"-"+Z[e[t+6]]+Z[e[t+7]]+"-"+Z[e[t+8]]+Z[e[t+9]]+"-"+Z[e[t+10]]+Z[e[t+11]]+Z[e[t+12]]+Z[e[t+13]]+Z[e[t+14]]+Z[e[t+15]]).toLowerCase();if(!J(n))throw TypeError("Stringified UUID is invalid");return n}(r)}!function(e){e.BaseNode=class{constructor(e={},t){this.parentNode=e?.parentNode??t??null,this.minidomType="MinidomBaseNode",this.uuid=e?.uuid??te(),s.push(this)}uuid;parentNode;get nextSibling(){if(!this.parentNode)return null;const e=this.parentNode.children.findIndex((e=>e.uuid===this.uuid));return-1!==e&&e<this.parentNode.children.length-1?this.parentNode.children[e+1]:null}insertBefore(e,t){e.removeAsChildFromAnyParents(),e.parentNode=this;const n=this.children.findIndex((e=>e.uuid===t?.uuid));-1!==n?this.children.splice(n,0,e):this.children.push(e)}removeChild(e){const t=this.children.findIndex((t=>t?.uuid===e?.uuid));-1!==t&&this.children.splice(t,1)}children=[];addChild(e){return e&&(e.removeAsChildFromAnyParents(),e.parentNode=this,this.insertBefore(e,null)),this}getPath(){const e=[];let t=this;for(;t;)e.unshift(t),t=t.parentNode;return e}drop(){this.parentNode=null,this.removeAsChildFromAnyParents()}walk(e){const t=[this,...this.children],n=[];let r=!0;for(;t.length&&r;){const o=t.shift();if(o){if(n.includes(o))continue;n.push(o),t.push(...o.children.filter((e=>!n.includes(e)))),r=e(o)}else r=!1}}minidomType;removeAsChildFromAnyParents(){s.forEach((e=>e.removeChild(this)))}};class t extends e.BaseNode{constructor(e={},t){super(e,t),this.minidomType="RendererNode",this.eventListeners={},this.eventListenerRemoveFunctions={},this.name=e.name??"",this.metaType=e.metaType??"standardMeta",this.props=e.props??[],this.type=e.type??""}eventListeners;eventListenerRemoveFunctions;name;metaType;props;type;drop(){super.drop(),Object.keys(this.eventListenerRemoveFunctions).forEach((e=>{this.eventListenerRemoveFunctions[e].forEach((e=>e()))}))}}e.RendererBaseNode=t;class n extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.domElement=e.domElement??document.createElement("div")}domElement;isLunchboxRootNode=!0}e.RendererRootNode=n;class r extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.text=e.text??""}text}e.RendererCommentNode=r;class o extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.domElement=e.domElement??document.createElement("div")}domElement}e.RendererDomNode=o;class a extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.text=e.text??""}text}e.RendererTextNode=a;class i extends e.RendererBaseNode{constructor(e={},t){super(e,t),this.attached=e.attached??[],this.attachedArray=e.attachedArray??{},this.instance=e.instance??null}attached;attachedArray;instance}e.RendererStandardNode=i}(Q||(Q={}));(new Q.RendererRootNode).minidomType="RootNode";const ne=[];let re;const oe=[],ae=[],se=e=>{re=requestAnimationFrame((()=>se({app:e.app,renderer:K.value?.instance,scene:_.value.instance,camera:$.value?.instance})));const{app:n,renderer:r,scene:o,camera:a}=e;oe.forEach((t=>{t&&t(e)})),r&&o&&a&&(n.customRender?n.customRender(e):r.render(t.toRaw(o),t.toRaw(a))),ae.forEach((t=>{t&&t(e)}))},ie=(e,t=1/0)=>{t===1/0?oe.push(e):oe.splice(t,0,e)},ce=()=>{re&&cancelAnimationFrame(re)};const de={x:"position.x",y:"position.y",z:"position.z"},ue=["","parameters"],le=["args","attach","attachArray","key","onAdded","ref","src"],pe=["geometry","material"];function me(e,t,n,r){const o=r??e.instance,a=t.instance;e.props.attach===n&&(t.attached={[n]:o,...t.attached||{}},a[n]=r??e.instance),e.props.attachArray===n&&(t.attachedArray[e.props.attachArray]||(t.attachedArray[e.props.attachArray]=[]),t.attachedArray[e.props.attachArray].push(o),a[n]=[a[n]])}const he={createElement:(e,t,n,r)=>{const o={type:e};r&&(o.props=r);if(f(e)){const e=function(e={}){const t={domElement:document.createElement(e.type??"")};return new Q.RendererDomNode({...t,...e,metaType:"domMeta"})}(o);return e}const a=g(o);return pe.forEach((t=>{e.toLowerCase().endsWith(t)&&(a.props.attach=t)})),a},createText:e=>function(e={}){const t={text:e.text??""};return new Q.RendererTextNode({...e,...t,metaType:"textMeta"})}({text:e}),createComment:e=>function(e={}){const t={text:e.text??""};return new Q.RendererCommentNode({...t,...e,metaType:"commentMeta"})}({text:e}),insert:(e,t,n)=>{let r=t??N();if(r.insertBefore(e,n),"commentMeta"!==e.metaType&&"textMeta"!==e.metaType&&(f(e)&&(f(t)||v(t))&&t.domElement.appendChild(e.domElement),y(e))){let n=r.metaType;if("textMeta"===n||"commentMeta"===n){const e=r.getPath();for(let t=e.length-1;t>=0;t--)if("textMeta"!==e[t].metaType&&"commentMeta"!==e[t].metaType){r=e[t];break}}if("standardMeta"===e.metaType&&"scene"!==e.type&&v(r)){const t=_.value;t.instance&&e&&t.addChild(e),e.instance&&e.instance.isObject3D&&t.instance&&t!==e&&t.instance.add(e.instance)}else y(e)&&e.instance?.isObject3D&&y(r)&&r.instance?.isObject3D&&r.instance?.add?.(e.instance);if(e?.props?.attach&&y(t)&&t?.instance){e.type?.toLowerCase().endsWith("loader")&&e.props.src&&(e.props.attach||e.props.attachArray)?function(e,t){const n=e.instance;if(t.attached=t.attached||{},t.attachedArray=t.attachedArray||{},!e.props.attach)return;if("textureloader"===e.type?.toLowerCase()){const r=n.load(e.props.src);me(e,t,e.props.attach,r)}else n.load(e.props.src,(n=>{me(e,t,e.props.attach,n)}),null,(e=>{throw new Error(e)}))}(e,t):me(e,t,e.props.attach)}e.props?.onAdded&&e.props.onAdded({instance:e.instance})}},nextSibling(e){const t=e.nextSibling;return t||null},parentNode(e){const t=e.parentNode;return t||null},patchProp(e,t,n,o){f(e)?"style"===t?Object.keys(o).forEach((t=>{e.domElement.style[t]=o[t]})):e.domElement.setAttribute(t,o):v(e)||t.startsWith("$")||function({node:e,key:t,value:n}){if((e=>["onClick","onContextMenu","onDoubleClick","onPointerUp","onPointerDown","onPointerOver","onPointerOut","onPointerEnter","onPointerLeave","onPointerMove","onWheel"].includes(e))(t))return R({node:e,key:t,value:n});if(le.includes(t))return e;if(!y(e))return e;if("string"==typeof n&&n.startsWith("$attached")){const t=n.replace("$attached.","");n=r.get(e.attached,t,null)}const o=e.instance;if(!o)return e;const a=t.replace(/-/g,".");let s,i=de[a]||a;for(let e=0;e<ue.length&&!s;e++){const t=[ue[e],i].filter(Boolean).join(".");s=s=r.get(o,t)}if(s&&r.isNumber(n)&&s.setScalar)s.setScalar(n);else if(s&&s.set){const e=Array.isArray(n)?n:[n];o[i].set(...e)}else"function"==typeof s?s.bind(e.instance)(...n):void 0!==r.get(o,i,void 0)?r.set(o,i,""===n||n):console.log(`No property ${i} found on ${o}`);const c=o?.texture?.type||o?.type;if("string"==typeof c){const e=c.toLowerCase();switch(!0){case e.includes("material"):o.needsUpdate=!0;break;case e.includes("camera")&&o.updateProjectionMatrix:o.updateProjectionMatrix()}}}({node:e,key:t,value:o})},remove:e=>{if(!e)return;const t=Object.keys(j),n=[];e.walk((e=>(n.push(e),!0))),n.forEach((e=>{const n=t.find((t=>j[t]?.uuid===e.uuid));if(n&&(j[n]=null),y(e)){e.instance?.removeFromParent?.();const t="scene"!==e.type&&e.instance?.dispose;t&&t.bind(e.instance)(),e.instance=null}e.drop();const r=s.findIndex((t=>t.uuid===e.uuid));-1!==r&&s.splice(r,1)}))},setElementText(){},setText(){}},fe={dpr:t.ref(1),inputActive:x,mousePos:L},ye=t.computed((()=>$.value?.instance??null));const ve=t.computed((()=>K.value?.instance??null));const ge=t.computed((()=>_.value.instance));let be=null,xe=null;e.camera=ye,e.clearCustomRender=()=>{be?be.clearCustomRender():xe=null},e.createApp=e=>{be=t.createRenderer(he).createApp(e),Object.keys(m).forEach((e=>{be.component(e,m[e])}));const{mount:n}=be;return be.mount=(e,...t)=>{const r=N({domElement:"string"==typeof e?document.querySelector(e):e,isLunchboxRootNode:!0,name:"root",metaType:"rootMeta",type:"root",uuid:"LUNCHBOX_ROOT"});be.rootNode=r;return n(r,...t)},be.extend=e=>((({app:e,...t})=>{Object.keys(t).forEach((n=>{e.component(n,q(n)),l[n]=t[n]}))})({app:be,...e}),be),be.setCustomRender=e=>{be.customRender=e},xe&&(be.setCustomRender(xe),xe=null),be.clearCustomRender=()=>{be.customRender=null},be},e.find=function(e){return e=t.isRef(e)?e.value:e,y(e)?e?.instance:h(e)?e?.$el?.instance:t.isVNode(e)?e.el?.instance:null},e.globals=fe,e.offAfterRender=e=>{if(isFinite(e))ae.splice(e,1);else{const t=ae.findIndex((t=>t==e));ae.splice(t,1)}},e.offBeforeRender=e=>{if(isFinite(e))oe.splice(e,1);else{const t=oe.findIndex((t=>t==e));oe.splice(t,1)}},e.onAfterRender=(e,t=1/0)=>{t===1/0?ae.push(e):ae.splice(t,0,e)},e.onBeforeRender=ie,e.onStart=(e,t=1/0)=>{t===1/0?ne.push(e):ne.splice(t,0,e)},e.renderer=ve,e.scene=ge,e.setCustomRender=e=>{be?be.setCustomRender(e):xe=e},e.useCamera=function(e,n=!0){let r;r=t.watch(ye,(t=>{t&&(e(t),n&&r?.())}),{immediate:!0})},e.useRenderer=function(e,n=!0){let r;r=t.watch(ve,(t=>{t&&(e(t),n&&r?.())}),{immediate:!0})},e.useScene=function(e,n=!0){let r;r=t.watch(ge,(t=>{t&&(e(t),n&&r?.())}),{immediate:!0})},Object.defineProperty(e,"__esModule",{value:!0})}));
|
|
@@ -84,10 +84,13 @@ const LunchboxWrapper = {
|
|
|
84
84
|
// These should match the Lunchbox.WrapperProps interface
|
|
85
85
|
background: String,
|
|
86
86
|
cameraArgs: Array,
|
|
87
|
+
cameraLook: Array,
|
|
88
|
+
cameraLookAt: Array,
|
|
87
89
|
cameraPosition: Array,
|
|
88
90
|
dpr: Number,
|
|
89
91
|
ortho: Boolean,
|
|
90
92
|
orthographic: Boolean,
|
|
93
|
+
rendererArguments: Object,
|
|
91
94
|
rendererProperties: Object,
|
|
92
95
|
shadow: [Boolean, Object],
|
|
93
96
|
transparent: Boolean,
|
|
@@ -117,12 +120,11 @@ const LunchboxWrapper = {
|
|
|
117
120
|
if (!renderer) {
|
|
118
121
|
// build renderer args
|
|
119
122
|
const rendererArgs = {
|
|
123
|
+
alpha: props.transparent,
|
|
120
124
|
antialias: true,
|
|
121
125
|
canvas: canvas.value.domElement,
|
|
126
|
+
...(props.rendererArguments ?? {}),
|
|
122
127
|
};
|
|
123
|
-
if (props.transparent) {
|
|
124
|
-
rendererArgs.alpha = true;
|
|
125
|
-
}
|
|
126
128
|
// create new renderer
|
|
127
129
|
ensureRenderer.value = createNode({
|
|
128
130
|
type: 'WebGLRenderer',
|
|
@@ -160,7 +162,6 @@ const LunchboxWrapper = {
|
|
|
160
162
|
// the user has initialized the renderer, so anything depending
|
|
161
163
|
// on the renderer can execute
|
|
162
164
|
rendererReady.value = true;
|
|
163
|
-
return;
|
|
164
165
|
}
|
|
165
166
|
// CAMERA
|
|
166
167
|
// ====================
|
|
@@ -173,7 +174,6 @@ const LunchboxWrapper = {
|
|
|
173
174
|
if (!camera) {
|
|
174
175
|
// create ortho camera
|
|
175
176
|
if (props.ortho || props.orthographic) {
|
|
176
|
-
// const size: Vector2 = new Vector2()
|
|
177
177
|
ensuredCamera.value = createNode({
|
|
178
178
|
props: { args: props.cameraArgs ?? [] },
|
|
179
179
|
type: 'OrthographicCamera',
|
|
@@ -195,9 +195,17 @@ const LunchboxWrapper = {
|
|
|
195
195
|
else {
|
|
196
196
|
cameraReady.value = true;
|
|
197
197
|
}
|
|
198
|
+
if (!camera.instance) {
|
|
199
|
+
throw new Error('Error creating camera.');
|
|
200
|
+
}
|
|
198
201
|
// move camera if needed
|
|
199
202
|
if (camera && props.cameraPosition) {
|
|
200
|
-
camera.instance
|
|
203
|
+
camera.instance.position.set(...props.cameraPosition);
|
|
204
|
+
}
|
|
205
|
+
// angle camera if needed
|
|
206
|
+
if (camera && (props.cameraLookAt || props.cameraLook)) {
|
|
207
|
+
const source = (props.cameraLookAt || props.cameraLook);
|
|
208
|
+
camera.instance.lookAt(...source);
|
|
201
209
|
}
|
|
202
210
|
// SCENE
|
|
203
211
|
// ====================
|
|
@@ -220,11 +228,23 @@ const LunchboxWrapper = {
|
|
|
220
228
|
else {
|
|
221
229
|
throw new Error('missing renderer');
|
|
222
230
|
}
|
|
231
|
+
// CALLBACK PREP
|
|
232
|
+
// ====================
|
|
233
|
+
const app = getCurrentInstance().appContext.app;
|
|
234
|
+
// START
|
|
235
|
+
// ====================
|
|
236
|
+
for (let startCallback of startCallbacks) {
|
|
237
|
+
startCallback({
|
|
238
|
+
app,
|
|
239
|
+
camera: camera.instance,
|
|
240
|
+
renderer: renderer.instance,
|
|
241
|
+
scene: scene.instance,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
223
244
|
// KICK UPDATE
|
|
224
245
|
// ====================
|
|
225
|
-
// console.log(scene)
|
|
226
246
|
update({
|
|
227
|
-
app
|
|
247
|
+
app,
|
|
228
248
|
camera: camera.instance,
|
|
229
249
|
renderer: renderer.instance,
|
|
230
250
|
scene: scene.instance,
|
|
@@ -255,21 +275,6 @@ const LunchboxWrapper = {
|
|
|
255
275
|
},
|
|
256
276
|
};
|
|
257
277
|
|
|
258
|
-
const catalogue = {};
|
|
259
|
-
|
|
260
|
-
const lunchboxDomComponentNames = [
|
|
261
|
-
'canvas',
|
|
262
|
-
'div',
|
|
263
|
-
'LunchboxWrapper',
|
|
264
|
-
];
|
|
265
|
-
// component creation utility
|
|
266
|
-
const createComponent$1 = (tag) => defineComponent({
|
|
267
|
-
inheritAttrs: false,
|
|
268
|
-
name: tag,
|
|
269
|
-
setup(props, context) {
|
|
270
|
-
return () => h(tag, context.attrs, context.slots?.default?.() || []);
|
|
271
|
-
},
|
|
272
|
-
});
|
|
273
278
|
// list of all components to register out of the box
|
|
274
279
|
const autoGeneratedComponents = [
|
|
275
280
|
// ThreeJS basics
|
|
@@ -382,21 +387,11 @@ const autoGeneratedComponents = [
|
|
|
382
387
|
'arrayCamera',
|
|
383
388
|
// renderers
|
|
384
389
|
'webGLRenderer',
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
});
|
|
389
|
-
const components = {
|
|
390
|
-
...autoGeneratedComponents,
|
|
391
|
-
'Lunchbox': LunchboxWrapper,
|
|
392
|
-
// Gltf,
|
|
393
|
-
};
|
|
394
|
-
// console.log(components, Gltf)
|
|
395
|
-
/*
|
|
396
|
-
// List copied from r3f
|
|
397
|
-
// https://github.com/pmndrs/react-three-fiber/blob/master/packages/fiber/src/three-types.ts
|
|
390
|
+
/*
|
|
391
|
+
// List copied from r3f:
|
|
392
|
+
// https://github.com/pmndrs/react-three-fiber/blob/master/packages/fiber/src/three-types.ts
|
|
398
393
|
|
|
399
|
-
// NOT IMPLEMENTED:
|
|
394
|
+
// NOT IMPLEMENTED (can be added via Extend - docs.lunchboxjs.com/components/extend/):
|
|
400
395
|
audioListener: AudioListenerProps
|
|
401
396
|
positionalAudio: PositionalAudioProps
|
|
402
397
|
|
|
@@ -444,6 +439,27 @@ const components = {
|
|
|
444
439
|
fogExp2: FogExp2Props
|
|
445
440
|
shape: ShapeProps
|
|
446
441
|
*/
|
|
442
|
+
];
|
|
443
|
+
|
|
444
|
+
const catalogue = {};
|
|
445
|
+
|
|
446
|
+
const lunchboxDomComponentNames = ['canvas', 'div', 'LunchboxWrapper'];
|
|
447
|
+
// component creation utility
|
|
448
|
+
const createComponent$1 = (tag) => defineComponent({
|
|
449
|
+
inheritAttrs: false,
|
|
450
|
+
name: tag,
|
|
451
|
+
setup(props, context) {
|
|
452
|
+
return () => h(tag, context.attrs, context.slots?.default?.() || []);
|
|
453
|
+
},
|
|
454
|
+
});
|
|
455
|
+
autoGeneratedComponents.map(createComponent$1).reduce((acc, curr) => {
|
|
456
|
+
acc[curr.name] = curr;
|
|
457
|
+
return acc;
|
|
458
|
+
});
|
|
459
|
+
const components = {
|
|
460
|
+
...autoGeneratedComponents,
|
|
461
|
+
Lunchbox: LunchboxWrapper,
|
|
462
|
+
};
|
|
447
463
|
|
|
448
464
|
function find(target) {
|
|
449
465
|
target = isRef(target) ? target.value : target;
|
|
@@ -1237,6 +1253,16 @@ var MiniDom;
|
|
|
1237
1253
|
const rootNode = new MiniDom.RendererRootNode();
|
|
1238
1254
|
rootNode.minidomType = 'RootNode';
|
|
1239
1255
|
|
|
1256
|
+
const startCallbacks = [];
|
|
1257
|
+
const onStart = (cb, index = Infinity) => {
|
|
1258
|
+
if (index === Infinity) {
|
|
1259
|
+
startCallbacks.push(cb);
|
|
1260
|
+
}
|
|
1261
|
+
else {
|
|
1262
|
+
startCallbacks.splice(index, 0, cb);
|
|
1263
|
+
}
|
|
1264
|
+
};
|
|
1265
|
+
|
|
1240
1266
|
let frameID;
|
|
1241
1267
|
const beforeRender = [];
|
|
1242
1268
|
const afterRender = [];
|
|
@@ -1280,6 +1306,15 @@ const onBeforeRender = (cb, index = Infinity) => {
|
|
|
1280
1306
|
beforeRender.splice(index, 0, cb);
|
|
1281
1307
|
}
|
|
1282
1308
|
};
|
|
1309
|
+
const offBeforeRender = (cb) => {
|
|
1310
|
+
if (isFinite(cb)) {
|
|
1311
|
+
beforeRender.splice(cb, 1);
|
|
1312
|
+
}
|
|
1313
|
+
else {
|
|
1314
|
+
const idx = beforeRender.findIndex((v) => v == cb);
|
|
1315
|
+
beforeRender.splice(idx, 1);
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1283
1318
|
const onAfterRender = (cb, index = Infinity) => {
|
|
1284
1319
|
if (index === Infinity) {
|
|
1285
1320
|
afterRender.push(cb);
|
|
@@ -1288,6 +1323,15 @@ const onAfterRender = (cb, index = Infinity) => {
|
|
|
1288
1323
|
afterRender.splice(index, 0, cb);
|
|
1289
1324
|
}
|
|
1290
1325
|
};
|
|
1326
|
+
const offAfterRender = (cb) => {
|
|
1327
|
+
if (isFinite(cb)) {
|
|
1328
|
+
afterRender.splice(cb, 1);
|
|
1329
|
+
}
|
|
1330
|
+
else {
|
|
1331
|
+
const idx = afterRender.findIndex((v) => v == cb);
|
|
1332
|
+
afterRender.splice(idx, 1);
|
|
1333
|
+
}
|
|
1334
|
+
};
|
|
1291
1335
|
const cancelUpdate = () => {
|
|
1292
1336
|
if (frameID)
|
|
1293
1337
|
cancelAnimationFrame(frameID);
|
|
@@ -1641,9 +1685,51 @@ const globals = {
|
|
|
1641
1685
|
inputActive,
|
|
1642
1686
|
mousePos,
|
|
1643
1687
|
};
|
|
1688
|
+
/** The current camera. Often easier to use `useCamera` instead of this. */
|
|
1644
1689
|
const camera = computed(() => ensuredCamera.value?.instance ?? null);
|
|
1690
|
+
/** Run a function using the current camera when it's present. */
|
|
1691
|
+
function useCamera(callback, once = true) {
|
|
1692
|
+
let destroy;
|
|
1693
|
+
destroy = watch(camera, (newVal) => {
|
|
1694
|
+
if (!newVal)
|
|
1695
|
+
return;
|
|
1696
|
+
// TODO: better fix than `any`?
|
|
1697
|
+
callback(newVal);
|
|
1698
|
+
if (once) {
|
|
1699
|
+
destroy?.();
|
|
1700
|
+
}
|
|
1701
|
+
}, { immediate: true });
|
|
1702
|
+
}
|
|
1703
|
+
/** The current renderer. Often easier to use `useRenderer` instead of this. */
|
|
1645
1704
|
const renderer = computed(() => ensureRenderer.value?.instance ?? null);
|
|
1705
|
+
/** Run a function using the current renderer when it's present. */
|
|
1706
|
+
function useRenderer(callback, once = true) {
|
|
1707
|
+
let destroy;
|
|
1708
|
+
destroy = watch(renderer, (newVal) => {
|
|
1709
|
+
if (!newVal)
|
|
1710
|
+
return;
|
|
1711
|
+
// TODO: better fix than `any`?
|
|
1712
|
+
callback(newVal);
|
|
1713
|
+
if (once) {
|
|
1714
|
+
destroy?.();
|
|
1715
|
+
}
|
|
1716
|
+
}, { immediate: true });
|
|
1717
|
+
}
|
|
1718
|
+
/** The current scene. Often easier to use `useScene` instead of this. */
|
|
1646
1719
|
const scene = computed(() => ensuredScene.value.instance);
|
|
1720
|
+
/** Run a function using the current scene when it's present. */
|
|
1721
|
+
function useScene(callback, once = true) {
|
|
1722
|
+
let destroy;
|
|
1723
|
+
destroy = watch(scene, (newVal) => {
|
|
1724
|
+
if (!newVal)
|
|
1725
|
+
return;
|
|
1726
|
+
// TODO: better fix than `any`?
|
|
1727
|
+
callback(newVal);
|
|
1728
|
+
if (once) {
|
|
1729
|
+
destroy?.();
|
|
1730
|
+
}
|
|
1731
|
+
}, { immediate: true });
|
|
1732
|
+
}
|
|
1647
1733
|
// CUSTOM RENDER SUPPORT
|
|
1648
1734
|
// ====================
|
|
1649
1735
|
let app = null;
|
|
@@ -1710,4 +1796,4 @@ const createApp = (root) => {
|
|
|
1710
1796
|
return app;
|
|
1711
1797
|
};
|
|
1712
1798
|
|
|
1713
|
-
export { camera, clearCustomRender, createApp, find, globals, lunchboxRootNode as lunchboxTree, onAfterRender, onBeforeRender, renderer, scene, setCustomRender };
|
|
1799
|
+
export { camera, clearCustomRender, createApp, find, globals, lunchboxRootNode as lunchboxTree, offAfterRender, offBeforeRender, onAfterRender, onBeforeRender, onStart, renderer, scene, setCustomRender, useCamera, useRenderer, useScene };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lunchboxjs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4010",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"dev": "vite -c utils/vite.config.ts",
|
|
6
6
|
"build": "vue-tsc --noEmit && vite build -c utils/vite.config.ts",
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
"@types/three": "0.133.0",
|
|
26
26
|
"@types/uuid": "8.3.1",
|
|
27
27
|
"@vitejs/plugin-vue": "^1.9.3",
|
|
28
|
+
"chroma-js": "2.1.2",
|
|
29
|
+
"nice-color-palettes": "3.0.0",
|
|
28
30
|
"rollup-plugin-delete": "2.0.0",
|
|
29
31
|
"rollup-plugin-terser": "7.0.2",
|
|
30
32
|
"typescript": "^4.4.3",
|
|
@@ -18,6 +18,7 @@ import {
|
|
|
18
18
|
fallbackRendererUuid,
|
|
19
19
|
MiniDom,
|
|
20
20
|
rendererReady,
|
|
21
|
+
startCallbacks,
|
|
21
22
|
tryGetNodeWithInstanceType,
|
|
22
23
|
update,
|
|
23
24
|
} from '../../core'
|
|
@@ -45,10 +46,13 @@ export const LunchboxWrapper: ComponentOptions = {
|
|
|
45
46
|
// These should match the Lunchbox.WrapperProps interface
|
|
46
47
|
background: String,
|
|
47
48
|
cameraArgs: Array,
|
|
49
|
+
cameraLook: Array,
|
|
50
|
+
cameraLookAt: Array,
|
|
48
51
|
cameraPosition: Array,
|
|
49
52
|
dpr: Number,
|
|
50
53
|
ortho: Boolean,
|
|
51
54
|
orthographic: Boolean,
|
|
55
|
+
rendererArguments: Object,
|
|
52
56
|
rendererProperties: Object,
|
|
53
57
|
shadow: [Boolean, Object],
|
|
54
58
|
transparent: Boolean,
|
|
@@ -80,11 +84,10 @@ export const LunchboxWrapper: ComponentOptions = {
|
|
|
80
84
|
if (!renderer) {
|
|
81
85
|
// build renderer args
|
|
82
86
|
const rendererArgs: THREE.WebGLRendererParameters = {
|
|
87
|
+
alpha: props.transparent,
|
|
83
88
|
antialias: true,
|
|
84
89
|
canvas: canvas.value.domElement,
|
|
85
|
-
|
|
86
|
-
if (props.transparent) {
|
|
87
|
-
rendererArgs.alpha = true
|
|
90
|
+
...(props.rendererArguments ?? {}),
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
// create new renderer
|
|
@@ -135,7 +138,6 @@ export const LunchboxWrapper: ComponentOptions = {
|
|
|
135
138
|
// the user has initialized the renderer, so anything depending
|
|
136
139
|
// on the renderer can execute
|
|
137
140
|
rendererReady.value = true
|
|
138
|
-
return
|
|
139
141
|
}
|
|
140
142
|
|
|
141
143
|
// CAMERA
|
|
@@ -149,8 +151,6 @@ export const LunchboxWrapper: ComponentOptions = {
|
|
|
149
151
|
if (!camera) {
|
|
150
152
|
// create ortho camera
|
|
151
153
|
if (props.ortho || props.orthographic) {
|
|
152
|
-
// const size: Vector2 = new Vector2()
|
|
153
|
-
|
|
154
154
|
ensuredCamera.value = createNode<THREE.OrthographicCamera>({
|
|
155
155
|
props: { args: props.cameraArgs ?? [] },
|
|
156
156
|
type: 'OrthographicCamera',
|
|
@@ -172,9 +172,17 @@ export const LunchboxWrapper: ComponentOptions = {
|
|
|
172
172
|
} else {
|
|
173
173
|
cameraReady.value = true
|
|
174
174
|
}
|
|
175
|
+
if (!camera.instance) {
|
|
176
|
+
throw new Error('Error creating camera.')
|
|
177
|
+
}
|
|
175
178
|
// move camera if needed
|
|
176
179
|
if (camera && props.cameraPosition) {
|
|
177
|
-
camera.instance
|
|
180
|
+
camera.instance.position.set(...props.cameraPosition)
|
|
181
|
+
}
|
|
182
|
+
// angle camera if needed
|
|
183
|
+
if (camera && (props.cameraLookAt || props.cameraLook)) {
|
|
184
|
+
const source = (props.cameraLookAt || props.cameraLook)!
|
|
185
|
+
camera.instance.lookAt(...source)
|
|
178
186
|
}
|
|
179
187
|
|
|
180
188
|
// SCENE
|
|
@@ -204,11 +212,25 @@ export const LunchboxWrapper: ComponentOptions = {
|
|
|
204
212
|
throw new Error('missing renderer')
|
|
205
213
|
}
|
|
206
214
|
|
|
215
|
+
// CALLBACK PREP
|
|
216
|
+
// ====================
|
|
217
|
+
const app = getCurrentInstance()!.appContext.app as Lunch.App
|
|
218
|
+
|
|
219
|
+
// START
|
|
220
|
+
// ====================
|
|
221
|
+
for (let startCallback of startCallbacks) {
|
|
222
|
+
startCallback({
|
|
223
|
+
app,
|
|
224
|
+
camera: camera.instance,
|
|
225
|
+
renderer: renderer.instance,
|
|
226
|
+
scene: scene.instance,
|
|
227
|
+
})
|
|
228
|
+
}
|
|
229
|
+
|
|
207
230
|
// KICK UPDATE
|
|
208
231
|
// ====================
|
|
209
|
-
// console.log(scene)
|
|
210
232
|
update({
|
|
211
|
-
app
|
|
233
|
+
app,
|
|
212
234
|
camera: camera.instance,
|
|
213
235
|
renderer: renderer.instance,
|
|
214
236
|
scene: scene.instance,
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// list of all components to register out of the box
|
|
2
|
+
export const autoGeneratedComponents = [
|
|
3
|
+
// ThreeJS basics
|
|
4
|
+
'mesh',
|
|
5
|
+
'instancedMesh',
|
|
6
|
+
'scene',
|
|
7
|
+
'sprite',
|
|
8
|
+
'object3D',
|
|
9
|
+
|
|
10
|
+
// geometry
|
|
11
|
+
'instancedBufferGeometry',
|
|
12
|
+
'bufferGeometry',
|
|
13
|
+
'boxBufferGeometry',
|
|
14
|
+
'circleBufferGeometry',
|
|
15
|
+
'coneBufferGeometry',
|
|
16
|
+
'cylinderBufferGeometry',
|
|
17
|
+
'dodecahedronBufferGeometry',
|
|
18
|
+
'extrudeBufferGeometry',
|
|
19
|
+
'icosahedronBufferGeometry',
|
|
20
|
+
'latheBufferGeometry',
|
|
21
|
+
'octahedronBufferGeometry',
|
|
22
|
+
'parametricBufferGeometry',
|
|
23
|
+
'planeBufferGeometry',
|
|
24
|
+
'polyhedronBufferGeometry',
|
|
25
|
+
'ringBufferGeometry',
|
|
26
|
+
'shapeBufferGeometry',
|
|
27
|
+
'sphereBufferGeometry',
|
|
28
|
+
'tetrahedronBufferGeometry',
|
|
29
|
+
'textBufferGeometry',
|
|
30
|
+
'torusBufferGeometry',
|
|
31
|
+
'torusKnotBufferGeometry',
|
|
32
|
+
'tubeBufferGeometry',
|
|
33
|
+
'wireframeGeometry',
|
|
34
|
+
'parametricGeometry',
|
|
35
|
+
'tetrahedronGeometry',
|
|
36
|
+
'octahedronGeometry',
|
|
37
|
+
'icosahedronGeometry',
|
|
38
|
+
'dodecahedronGeometry',
|
|
39
|
+
'polyhedronGeometry',
|
|
40
|
+
'tubeGeometry',
|
|
41
|
+
'torusKnotGeometry',
|
|
42
|
+
'torusGeometry',
|
|
43
|
+
// textgeometry has been moved to /examples/jsm/geometries/TextGeometry
|
|
44
|
+
// 'textGeometry',
|
|
45
|
+
'sphereGeometry',
|
|
46
|
+
'ringGeometry',
|
|
47
|
+
'planeGeometry',
|
|
48
|
+
'latheGeometry',
|
|
49
|
+
'shapeGeometry',
|
|
50
|
+
'extrudeGeometry',
|
|
51
|
+
'edgesGeometry',
|
|
52
|
+
'coneGeometry',
|
|
53
|
+
'cylinderGeometry',
|
|
54
|
+
'circleGeometry',
|
|
55
|
+
'boxGeometry',
|
|
56
|
+
|
|
57
|
+
// materials
|
|
58
|
+
'material',
|
|
59
|
+
'shadowMaterial',
|
|
60
|
+
'spriteMaterial',
|
|
61
|
+
'rawShaderMaterial',
|
|
62
|
+
'shaderMaterial',
|
|
63
|
+
'pointsMaterial',
|
|
64
|
+
'meshPhysicalMaterial',
|
|
65
|
+
'meshStandardMaterial',
|
|
66
|
+
'meshPhongMaterial',
|
|
67
|
+
'meshToonMaterial',
|
|
68
|
+
'meshNormalMaterial',
|
|
69
|
+
'meshLambertMaterial',
|
|
70
|
+
'meshDepthMaterial',
|
|
71
|
+
'meshDistanceMaterial',
|
|
72
|
+
'meshBasicMaterial',
|
|
73
|
+
'meshMatcapMaterial',
|
|
74
|
+
'lineDashedMaterial',
|
|
75
|
+
'lineBasicMaterial',
|
|
76
|
+
|
|
77
|
+
// lights
|
|
78
|
+
'light',
|
|
79
|
+
'spotLightShadow',
|
|
80
|
+
'spotLight',
|
|
81
|
+
'pointLight',
|
|
82
|
+
'rectAreaLight',
|
|
83
|
+
'hemisphereLight',
|
|
84
|
+
'directionalLightShadow',
|
|
85
|
+
'directionalLight',
|
|
86
|
+
'ambientLight',
|
|
87
|
+
'lightShadow',
|
|
88
|
+
'ambientLightProbe',
|
|
89
|
+
'hemisphereLightProbe',
|
|
90
|
+
'lightProbe',
|
|
91
|
+
|
|
92
|
+
// textures
|
|
93
|
+
'texture',
|
|
94
|
+
'videoTexture',
|
|
95
|
+
'dataTexture',
|
|
96
|
+
'dataTexture3D',
|
|
97
|
+
'compressedTexture',
|
|
98
|
+
'cubeTexture',
|
|
99
|
+
'canvasTexture',
|
|
100
|
+
'depthTexture',
|
|
101
|
+
|
|
102
|
+
// Texture loaders
|
|
103
|
+
'textureLoader',
|
|
104
|
+
|
|
105
|
+
// misc
|
|
106
|
+
'group',
|
|
107
|
+
'catmullRomCurve3',
|
|
108
|
+
'points',
|
|
109
|
+
|
|
110
|
+
// helpers
|
|
111
|
+
'cameraHelper',
|
|
112
|
+
|
|
113
|
+
// cameras
|
|
114
|
+
'camera',
|
|
115
|
+
'perspectiveCamera',
|
|
116
|
+
'orthographicCamera',
|
|
117
|
+
'cubeCamera',
|
|
118
|
+
'arrayCamera',
|
|
119
|
+
|
|
120
|
+
// renderers
|
|
121
|
+
'webGLRenderer',
|
|
122
|
+
|
|
123
|
+
/*
|
|
124
|
+
// List copied from r3f:
|
|
125
|
+
// https://github.com/pmndrs/react-three-fiber/blob/master/packages/fiber/src/three-types.ts
|
|
126
|
+
|
|
127
|
+
// NOT IMPLEMENTED (can be added via Extend - docs.lunchboxjs.com/components/extend/):
|
|
128
|
+
audioListener: AudioListenerProps
|
|
129
|
+
positionalAudio: PositionalAudioProps
|
|
130
|
+
|
|
131
|
+
lOD: LODProps
|
|
132
|
+
skinnedMesh: SkinnedMeshProps
|
|
133
|
+
skeleton: SkeletonProps
|
|
134
|
+
bone: BoneProps
|
|
135
|
+
lineSegments: LineSegmentsProps
|
|
136
|
+
lineLoop: LineLoopProps
|
|
137
|
+
// see `audio`
|
|
138
|
+
// line: LineProps
|
|
139
|
+
immediateRenderObject: ImmediateRenderObjectProps
|
|
140
|
+
|
|
141
|
+
// primitive
|
|
142
|
+
primitive: PrimitiveProps
|
|
143
|
+
|
|
144
|
+
// helpers
|
|
145
|
+
spotLightHelper: SpotLightHelperProps
|
|
146
|
+
skeletonHelper: SkeletonHelperProps
|
|
147
|
+
pointLightHelper: PointLightHelperProps
|
|
148
|
+
hemisphereLightHelper: HemisphereLightHelperProps
|
|
149
|
+
gridHelper: GridHelperProps
|
|
150
|
+
polarGridHelper: PolarGridHelperProps
|
|
151
|
+
directionalLightHelper: DirectionalLightHelperProps
|
|
152
|
+
boxHelper: BoxHelperProps
|
|
153
|
+
box3Helper: Box3HelperProps
|
|
154
|
+
planeHelper: PlaneHelperProps
|
|
155
|
+
arrowHelper: ArrowHelperProps
|
|
156
|
+
axesHelper: AxesHelperProps
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
// misc
|
|
160
|
+
raycaster: RaycasterProps
|
|
161
|
+
vector2: Vector2Props
|
|
162
|
+
vector3: Vector3Props
|
|
163
|
+
vector4: Vector4Props
|
|
164
|
+
euler: EulerProps
|
|
165
|
+
matrix3: Matrix3Props
|
|
166
|
+
matrix4: Matrix4Props
|
|
167
|
+
quaternion: QuaternionProps
|
|
168
|
+
bufferAttribute: BufferAttributeProps
|
|
169
|
+
instancedBufferAttribute: InstancedBufferAttributeProps
|
|
170
|
+
color: ColorProps
|
|
171
|
+
fog: FogProps
|
|
172
|
+
fogExp2: FogExp2Props
|
|
173
|
+
shape: ShapeProps
|
|
174
|
+
*/
|
|
175
|
+
]
|
package/src/components/index.ts
CHANGED
|
@@ -1,16 +1,11 @@
|
|
|
1
1
|
import { h, defineComponent } from 'vue'
|
|
2
|
-
// import Gltf from './Gltf'
|
|
3
|
-
// import { Lunchbox } from '../types'
|
|
4
2
|
import { LunchboxWrapper } from './LunchboxWrapper/LunchboxWrapper'
|
|
3
|
+
import { autoGeneratedComponents } from './autoGeneratedComponents'
|
|
5
4
|
|
|
6
5
|
import { catalogue } from './catalogue'
|
|
7
6
|
export { catalogue }
|
|
8
7
|
|
|
9
|
-
export const lunchboxDomComponentNames = [
|
|
10
|
-
'canvas',
|
|
11
|
-
'div',
|
|
12
|
-
'LunchboxWrapper',
|
|
13
|
-
]
|
|
8
|
+
export const lunchboxDomComponentNames = ['canvas', 'div', 'LunchboxWrapper']
|
|
14
9
|
|
|
15
10
|
// component creation utility
|
|
16
11
|
const createComponent = (tag: string) =>
|
|
@@ -22,190 +17,12 @@ const createComponent = (tag: string) =>
|
|
|
22
17
|
},
|
|
23
18
|
})
|
|
24
19
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
// ThreeJS basics
|
|
29
|
-
'mesh',
|
|
30
|
-
'instancedMesh',
|
|
31
|
-
'scene',
|
|
32
|
-
'sprite',
|
|
33
|
-
'object3D',
|
|
34
|
-
|
|
35
|
-
// geometry
|
|
36
|
-
'instancedBufferGeometry',
|
|
37
|
-
'bufferGeometry',
|
|
38
|
-
'boxBufferGeometry',
|
|
39
|
-
'circleBufferGeometry',
|
|
40
|
-
'coneBufferGeometry',
|
|
41
|
-
'cylinderBufferGeometry',
|
|
42
|
-
'dodecahedronBufferGeometry',
|
|
43
|
-
'extrudeBufferGeometry',
|
|
44
|
-
'icosahedronBufferGeometry',
|
|
45
|
-
'latheBufferGeometry',
|
|
46
|
-
'octahedronBufferGeometry',
|
|
47
|
-
'parametricBufferGeometry',
|
|
48
|
-
'planeBufferGeometry',
|
|
49
|
-
'polyhedronBufferGeometry',
|
|
50
|
-
'ringBufferGeometry',
|
|
51
|
-
'shapeBufferGeometry',
|
|
52
|
-
'sphereBufferGeometry',
|
|
53
|
-
'tetrahedronBufferGeometry',
|
|
54
|
-
'textBufferGeometry',
|
|
55
|
-
'torusBufferGeometry',
|
|
56
|
-
'torusKnotBufferGeometry',
|
|
57
|
-
'tubeBufferGeometry',
|
|
58
|
-
'wireframeGeometry',
|
|
59
|
-
'parametricGeometry',
|
|
60
|
-
'tetrahedronGeometry',
|
|
61
|
-
'octahedronGeometry',
|
|
62
|
-
'icosahedronGeometry',
|
|
63
|
-
'dodecahedronGeometry',
|
|
64
|
-
'polyhedronGeometry',
|
|
65
|
-
'tubeGeometry',
|
|
66
|
-
'torusKnotGeometry',
|
|
67
|
-
'torusGeometry',
|
|
68
|
-
// textgeometry has been moved to /examples/jsm/geometries/TextGeometry
|
|
69
|
-
// 'textGeometry',
|
|
70
|
-
'sphereGeometry',
|
|
71
|
-
'ringGeometry',
|
|
72
|
-
'planeGeometry',
|
|
73
|
-
'latheGeometry',
|
|
74
|
-
'shapeGeometry',
|
|
75
|
-
'extrudeGeometry',
|
|
76
|
-
'edgesGeometry',
|
|
77
|
-
'coneGeometry',
|
|
78
|
-
'cylinderGeometry',
|
|
79
|
-
'circleGeometry',
|
|
80
|
-
'boxGeometry',
|
|
81
|
-
|
|
82
|
-
// materials
|
|
83
|
-
'material',
|
|
84
|
-
'shadowMaterial',
|
|
85
|
-
'spriteMaterial',
|
|
86
|
-
'rawShaderMaterial',
|
|
87
|
-
'shaderMaterial',
|
|
88
|
-
'pointsMaterial',
|
|
89
|
-
'meshPhysicalMaterial',
|
|
90
|
-
'meshStandardMaterial',
|
|
91
|
-
'meshPhongMaterial',
|
|
92
|
-
'meshToonMaterial',
|
|
93
|
-
'meshNormalMaterial',
|
|
94
|
-
'meshLambertMaterial',
|
|
95
|
-
'meshDepthMaterial',
|
|
96
|
-
'meshDistanceMaterial',
|
|
97
|
-
'meshBasicMaterial',
|
|
98
|
-
'meshMatcapMaterial',
|
|
99
|
-
'lineDashedMaterial',
|
|
100
|
-
'lineBasicMaterial',
|
|
101
|
-
|
|
102
|
-
// lights
|
|
103
|
-
'light',
|
|
104
|
-
'spotLightShadow',
|
|
105
|
-
'spotLight',
|
|
106
|
-
'pointLight',
|
|
107
|
-
'rectAreaLight',
|
|
108
|
-
'hemisphereLight',
|
|
109
|
-
'directionalLightShadow',
|
|
110
|
-
'directionalLight',
|
|
111
|
-
'ambientLight',
|
|
112
|
-
'lightShadow',
|
|
113
|
-
'ambientLightProbe',
|
|
114
|
-
'hemisphereLightProbe',
|
|
115
|
-
'lightProbe',
|
|
116
|
-
|
|
117
|
-
// textures
|
|
118
|
-
'texture',
|
|
119
|
-
'videoTexture',
|
|
120
|
-
'dataTexture',
|
|
121
|
-
'dataTexture3D',
|
|
122
|
-
'compressedTexture',
|
|
123
|
-
'cubeTexture',
|
|
124
|
-
'canvasTexture',
|
|
125
|
-
'depthTexture',
|
|
126
|
-
|
|
127
|
-
// Texture loaders
|
|
128
|
-
'textureLoader',
|
|
129
|
-
|
|
130
|
-
// misc
|
|
131
|
-
'group',
|
|
132
|
-
'catmullRomCurve3',
|
|
133
|
-
'points',
|
|
134
|
-
|
|
135
|
-
// helpers
|
|
136
|
-
'cameraHelper',
|
|
137
|
-
|
|
138
|
-
// cameras
|
|
139
|
-
'camera',
|
|
140
|
-
'perspectiveCamera',
|
|
141
|
-
'orthographicCamera',
|
|
142
|
-
'cubeCamera',
|
|
143
|
-
'arrayCamera',
|
|
144
|
-
|
|
145
|
-
// renderers
|
|
146
|
-
'webGLRenderer',
|
|
147
|
-
].map(createComponent).reduce((acc, curr) => {
|
|
148
|
-
; (acc as any)[curr.name] = curr
|
|
20
|
+
autoGeneratedComponents.map(createComponent).reduce((acc, curr) => {
|
|
21
|
+
;(acc as any)[curr.name] = curr
|
|
149
22
|
return acc
|
|
150
23
|
})
|
|
151
24
|
|
|
152
25
|
export const components = {
|
|
153
26
|
...autoGeneratedComponents,
|
|
154
|
-
|
|
155
|
-
// Gltf,
|
|
27
|
+
Lunchbox: LunchboxWrapper,
|
|
156
28
|
}
|
|
157
|
-
|
|
158
|
-
// console.log(components, Gltf)
|
|
159
|
-
|
|
160
|
-
/*
|
|
161
|
-
// List copied from r3f
|
|
162
|
-
// https://github.com/pmndrs/react-three-fiber/blob/master/packages/fiber/src/three-types.ts
|
|
163
|
-
|
|
164
|
-
// NOT IMPLEMENTED:
|
|
165
|
-
audioListener: AudioListenerProps
|
|
166
|
-
positionalAudio: PositionalAudioProps
|
|
167
|
-
|
|
168
|
-
lOD: LODProps
|
|
169
|
-
skinnedMesh: SkinnedMeshProps
|
|
170
|
-
skeleton: SkeletonProps
|
|
171
|
-
bone: BoneProps
|
|
172
|
-
lineSegments: LineSegmentsProps
|
|
173
|
-
lineLoop: LineLoopProps
|
|
174
|
-
// see `audio`
|
|
175
|
-
// line: LineProps
|
|
176
|
-
immediateRenderObject: ImmediateRenderObjectProps
|
|
177
|
-
|
|
178
|
-
// primitive
|
|
179
|
-
primitive: PrimitiveProps
|
|
180
|
-
|
|
181
|
-
// helpers
|
|
182
|
-
spotLightHelper: SpotLightHelperProps
|
|
183
|
-
skeletonHelper: SkeletonHelperProps
|
|
184
|
-
pointLightHelper: PointLightHelperProps
|
|
185
|
-
hemisphereLightHelper: HemisphereLightHelperProps
|
|
186
|
-
gridHelper: GridHelperProps
|
|
187
|
-
polarGridHelper: PolarGridHelperProps
|
|
188
|
-
directionalLightHelper: DirectionalLightHelperProps
|
|
189
|
-
boxHelper: BoxHelperProps
|
|
190
|
-
box3Helper: Box3HelperProps
|
|
191
|
-
planeHelper: PlaneHelperProps
|
|
192
|
-
arrowHelper: ArrowHelperProps
|
|
193
|
-
axesHelper: AxesHelperProps
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
// misc
|
|
197
|
-
raycaster: RaycasterProps
|
|
198
|
-
vector2: Vector2Props
|
|
199
|
-
vector3: Vector3Props
|
|
200
|
-
vector4: Vector4Props
|
|
201
|
-
euler: EulerProps
|
|
202
|
-
matrix3: Matrix3Props
|
|
203
|
-
matrix4: Matrix4Props
|
|
204
|
-
quaternion: QuaternionProps
|
|
205
|
-
bufferAttribute: BufferAttributeProps
|
|
206
|
-
instancedBufferAttribute: InstancedBufferAttributeProps
|
|
207
|
-
color: ColorProps
|
|
208
|
-
fog: FogProps
|
|
209
|
-
fogExp2: FogExp2Props
|
|
210
|
-
shape: ShapeProps
|
|
211
|
-
*/
|
package/src/core/index.ts
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Lunch } from '..'
|
|
2
|
+
|
|
3
|
+
export const startCallbacks = [] as Lunch.UpdateCallback[]
|
|
4
|
+
|
|
5
|
+
export const onStart = (cb: Lunch.UpdateCallback, index = Infinity) => {
|
|
6
|
+
if (index === Infinity) {
|
|
7
|
+
startCallbacks.push(cb)
|
|
8
|
+
} else {
|
|
9
|
+
startCallbacks.splice(index, 0, cb)
|
|
10
|
+
}
|
|
11
|
+
}
|
package/src/core/update.ts
CHANGED
|
@@ -53,6 +53,15 @@ export const onBeforeRender = (cb: Lunch.UpdateCallback, index = Infinity) => {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
export const offBeforeRender = (cb: Lunch.UpdateCallback | number) => {
|
|
57
|
+
if (isFinite(cb as number)) {
|
|
58
|
+
beforeRender.splice(cb as number, 1)
|
|
59
|
+
} else {
|
|
60
|
+
const idx = beforeRender.findIndex((v) => v == cb)
|
|
61
|
+
beforeRender.splice(idx, 1)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
56
65
|
export const onAfterRender = (cb: Lunch.UpdateCallback, index = Infinity) => {
|
|
57
66
|
if (index === Infinity) {
|
|
58
67
|
afterRender.push(cb)
|
|
@@ -61,6 +70,15 @@ export const onAfterRender = (cb: Lunch.UpdateCallback, index = Infinity) => {
|
|
|
61
70
|
}
|
|
62
71
|
}
|
|
63
72
|
|
|
73
|
+
export const offAfterRender = (cb: Lunch.UpdateCallback | number) => {
|
|
74
|
+
if (isFinite(cb as number)) {
|
|
75
|
+
afterRender.splice(cb as number, 1)
|
|
76
|
+
} else {
|
|
77
|
+
const idx = afterRender.findIndex((v) => v == cb)
|
|
78
|
+
afterRender.splice(idx, 1)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
64
82
|
export const cancelUpdate = () => {
|
|
65
83
|
if (frameID) cancelAnimationFrame(frameID)
|
|
66
84
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
computed,
|
|
3
|
+
createRenderer,
|
|
4
|
+
Component,
|
|
5
|
+
ref,
|
|
6
|
+
watch,
|
|
7
|
+
WatchStopHandle,
|
|
8
|
+
} from 'vue'
|
|
2
9
|
import { nodeOps } from './nodeOps'
|
|
3
10
|
import {
|
|
4
11
|
// createdCamera,
|
|
@@ -17,7 +24,13 @@ import { components } from './components'
|
|
|
17
24
|
import { Lunch } from './types'
|
|
18
25
|
|
|
19
26
|
export { lunchboxRootNode as lunchboxTree } from './core'
|
|
20
|
-
export {
|
|
27
|
+
export {
|
|
28
|
+
offAfterRender,
|
|
29
|
+
offBeforeRender,
|
|
30
|
+
onAfterRender,
|
|
31
|
+
onBeforeRender,
|
|
32
|
+
onStart,
|
|
33
|
+
} from './core'
|
|
21
34
|
export * from './types'
|
|
22
35
|
|
|
23
36
|
// Utilities
|
|
@@ -30,9 +43,74 @@ export const globals = {
|
|
|
30
43
|
mousePos,
|
|
31
44
|
}
|
|
32
45
|
|
|
46
|
+
/** The current camera. Often easier to use `useCamera` instead of this. */
|
|
33
47
|
export const camera = computed(() => ensuredCamera.value?.instance ?? null)
|
|
48
|
+
/** Run a function using the current camera when it's present. */
|
|
49
|
+
export function useCamera<T extends THREE.Camera = THREE.PerspectiveCamera>(
|
|
50
|
+
callback: (cam: T) => void,
|
|
51
|
+
once = true
|
|
52
|
+
) {
|
|
53
|
+
let destroy: WatchStopHandle
|
|
54
|
+
destroy = watch(
|
|
55
|
+
camera,
|
|
56
|
+
(newVal) => {
|
|
57
|
+
if (!newVal) return
|
|
58
|
+
|
|
59
|
+
// TODO: better fix than `any`?
|
|
60
|
+
callback(newVal as any)
|
|
61
|
+
if (once) {
|
|
62
|
+
destroy?.()
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{ immediate: true }
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** The current renderer. Often easier to use `useRenderer` instead of this. */
|
|
34
70
|
export const renderer = computed(() => ensureRenderer.value?.instance ?? null)
|
|
71
|
+
/** Run a function using the current renderer when it's present. */
|
|
72
|
+
export function useRenderer<T extends THREE.Renderer = THREE.WebGLRenderer>(
|
|
73
|
+
callback: (rend: T) => void,
|
|
74
|
+
once = true
|
|
75
|
+
) {
|
|
76
|
+
let destroy: WatchStopHandle
|
|
77
|
+
destroy = watch(
|
|
78
|
+
renderer,
|
|
79
|
+
(newVal) => {
|
|
80
|
+
if (!newVal) return
|
|
81
|
+
|
|
82
|
+
// TODO: better fix than `any`?
|
|
83
|
+
callback(newVal as any)
|
|
84
|
+
if (once) {
|
|
85
|
+
destroy?.()
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
{ immediate: true }
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** The current scene. Often easier to use `useScene` instead of this. */
|
|
35
93
|
export const scene = computed(() => ensuredScene.value.instance)
|
|
94
|
+
/** Run a function using the current scene when it's present. */
|
|
95
|
+
export function useScene(
|
|
96
|
+
callback: (newScene: THREE.Scene) => void,
|
|
97
|
+
once = true
|
|
98
|
+
) {
|
|
99
|
+
let destroy: WatchStopHandle
|
|
100
|
+
destroy = watch(
|
|
101
|
+
scene,
|
|
102
|
+
(newVal) => {
|
|
103
|
+
if (!newVal) return
|
|
104
|
+
|
|
105
|
+
// TODO: better fix than `any`?
|
|
106
|
+
callback(newVal as any)
|
|
107
|
+
if (once) {
|
|
108
|
+
destroy?.()
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
{ immediate: true }
|
|
112
|
+
)
|
|
113
|
+
}
|
|
36
114
|
|
|
37
115
|
// CUSTOM RENDER SUPPORT
|
|
38
116
|
// ====================
|
package/src/types.ts
CHANGED
|
@@ -139,10 +139,14 @@ export declare namespace Lunch {
|
|
|
139
139
|
interface WrapperProps {
|
|
140
140
|
background?: string
|
|
141
141
|
cameraArgs?: any[]
|
|
142
|
+
cameraLook?: [number, number, number]
|
|
143
|
+
cameraLookAt?: [number, number, number]
|
|
142
144
|
cameraPosition?: [number, number, number]
|
|
143
145
|
dpr?: number
|
|
144
146
|
ortho?: boolean
|
|
145
147
|
orthographic?: boolean
|
|
148
|
+
// TODO: Why doesn't ConstructorParameters<THREE.WebGLRenderer> work here?
|
|
149
|
+
rendererArguments?: object
|
|
146
150
|
rendererProperties?: Partial<THREE.WebGLRenderer>
|
|
147
151
|
shadow?: ShadowSugar
|
|
148
152
|
transparent?: boolean
|