lunchboxjs 0.1.4002 → 0.1.4003
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lunchboxjs.js +47 -5
- package/dist/lunchboxjs.min.js +1 -1
- package/dist/lunchboxjs.module.js +46 -5
- package/package.json +1 -1
- package/src/core/update.ts +8 -8
- package/src/index.ts +49 -7
- package/src/types.ts +5 -0
package/dist/lunchboxjs.js
CHANGED
|
@@ -1200,12 +1200,14 @@
|
|
|
1200
1200
|
const beforeRender = [];
|
|
1201
1201
|
const afterRender = [];
|
|
1202
1202
|
const update = (opts) => {
|
|
1203
|
+
// request next frame
|
|
1203
1204
|
frameID = requestAnimationFrame(() => update({
|
|
1204
1205
|
app: opts.app,
|
|
1205
1206
|
renderer: ensureRenderer.value?.instance,
|
|
1206
1207
|
scene: ensuredScene.value.instance,
|
|
1207
1208
|
camera: ensuredCamera.value.instance,
|
|
1208
1209
|
}));
|
|
1210
|
+
// prep options
|
|
1209
1211
|
const { app, renderer, scene, camera } = opts;
|
|
1210
1212
|
// BEFORE RENDER
|
|
1211
1213
|
beforeRender.forEach((cb) => {
|
|
@@ -1214,9 +1216,13 @@
|
|
|
1214
1216
|
}
|
|
1215
1217
|
});
|
|
1216
1218
|
// RENDER
|
|
1217
|
-
// console.log(camera?.position.z)
|
|
1218
1219
|
if (renderer && scene && camera) {
|
|
1219
|
-
|
|
1220
|
+
if (app.customRender) {
|
|
1221
|
+
app.customRender(opts);
|
|
1222
|
+
}
|
|
1223
|
+
else {
|
|
1224
|
+
renderer.render(vue.toRaw(scene), vue.toRaw(camera));
|
|
1225
|
+
}
|
|
1220
1226
|
}
|
|
1221
1227
|
// AFTER RENDER
|
|
1222
1228
|
afterRender.forEach((cb) => {
|
|
@@ -1597,8 +1603,30 @@
|
|
|
1597
1603
|
const camera = vue.computed(() => ensuredCamera.value.instance);
|
|
1598
1604
|
const renderer = vue.computed(() => ensureRenderer.value?.instance ?? null);
|
|
1599
1605
|
const scene = vue.computed(() => ensuredScene.value.instance);
|
|
1606
|
+
// CUSTOM RENDER SUPPORT
|
|
1607
|
+
// ====================
|
|
1608
|
+
let app = null;
|
|
1609
|
+
let queuedCustomRenderFunction = null;
|
|
1610
|
+
/** Set a custom render function, overriding the Lunchbox app's default render function.
|
|
1611
|
+
* Changing this requires the user to manually render their scene.
|
|
1612
|
+
*/
|
|
1613
|
+
const setCustomRender = (render) => {
|
|
1614
|
+
if (app)
|
|
1615
|
+
app.setCustomRender(render);
|
|
1616
|
+
else
|
|
1617
|
+
queuedCustomRenderFunction = render;
|
|
1618
|
+
};
|
|
1619
|
+
/** Clear the active app's custom render function. */
|
|
1620
|
+
const clearCustomRender = () => {
|
|
1621
|
+
if (app)
|
|
1622
|
+
app.clearCustomRender();
|
|
1623
|
+
else
|
|
1624
|
+
queuedCustomRenderFunction = null;
|
|
1625
|
+
};
|
|
1626
|
+
// CREATE APP
|
|
1627
|
+
// ====================
|
|
1600
1628
|
const createApp = (root) => {
|
|
1601
|
-
|
|
1629
|
+
app = vue.createRenderer(nodeOps).createApp(root);
|
|
1602
1630
|
// register all components
|
|
1603
1631
|
Object.keys(components).forEach((key) => {
|
|
1604
1632
|
app.component(key, components[key]);
|
|
@@ -1621,14 +1649,28 @@
|
|
|
1621
1649
|
};
|
|
1622
1650
|
// embed .extend function
|
|
1623
1651
|
app.extend = (targets) => {
|
|
1624
|
-
extend({ app, ...targets });
|
|
1652
|
+
extend({ app: app, ...targets });
|
|
1625
1653
|
return app;
|
|
1626
1654
|
};
|
|
1655
|
+
// prep for custom render support
|
|
1656
|
+
app.setCustomRender = (newRender) => {
|
|
1657
|
+
app.customRender = newRender;
|
|
1658
|
+
};
|
|
1659
|
+
// add queued custom render if we have one
|
|
1660
|
+
if (queuedCustomRenderFunction) {
|
|
1661
|
+
app.setCustomRender(queuedCustomRenderFunction);
|
|
1662
|
+
queuedCustomRenderFunction = null;
|
|
1663
|
+
}
|
|
1664
|
+
// add custom render removal
|
|
1665
|
+
app.clearCustomRender = () => {
|
|
1666
|
+
app.customRender = null;
|
|
1667
|
+
};
|
|
1627
1668
|
// done
|
|
1628
1669
|
return app;
|
|
1629
1670
|
};
|
|
1630
1671
|
|
|
1631
1672
|
exports.camera = camera;
|
|
1673
|
+
exports.clearCustomRender = clearCustomRender;
|
|
1632
1674
|
exports.createApp = createApp;
|
|
1633
1675
|
exports.find = find;
|
|
1634
1676
|
exports.globals = globals;
|
|
@@ -1636,7 +1678,7 @@
|
|
|
1636
1678
|
exports.onBeforeRender = onBeforeRender;
|
|
1637
1679
|
exports.renderer = renderer;
|
|
1638
1680
|
exports.scene = scene;
|
|
1639
|
-
exports.
|
|
1681
|
+
exports.setCustomRender = setCustomRender;
|
|
1640
1682
|
|
|
1641
1683
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
1642
1684
|
|
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=$.value?.instance,o=U.value.instance;if(!r?.domElement||!o)return;const a=(e=e??window.innerWidth)/(n=n??window.innerHeight),s=k.value;if("perspectivecamera"===s.type?.toLowerCase()){const e=s.instance;e.aspect=a,e.updateProjectionMatrix()}else console.log("TODO: ortho camera update");r.setSize(e,n),o&&s.instance&&r.render(t.toRaw(o),t.toRaw(s.instance))},c=e=>({position:e,top:0,right:0,bottom:0,left:0,width:"100%",height:"100%"}),d={name:"Lunchbox",props:{background:String,cameraPosition:Array,dpr:Number,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;return t.onMounted((()=>{if(!a.value)throw new Error("missing canvas");const o=k.value.instance;if(o&&e.cameraPosition&&o.position.set(...e.cameraPosition),l=B(["WebGLRenderer"]),l)return s.value=!1,void(F.value=!0);{const t={antialias:!0,canvas:a.value.domElement};e.transparent&&(t.alpha=!0),$.value=v({type:"WebGLRenderer",uuid:S,props:{args:[t]}}),F.value=!0;const n=$,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=U.value,p&&p.instance&&e.background&&(p.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),ue.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),te({app:t.getCurrentInstance().appContext.app,camera:o,renderer:l.instance,scene:p.instance})})),t.onBeforeUnmount((()=>{re()})),()=>[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 h=e=>e?.$el&&e?.$el?.hasOwnProperty?.("instance"),m=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 H.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&&(U.value=r),r}const b=[],x=t.ref(!1);function g({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)&&(W.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=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 w=["onClick","onPointerUp","onPointerDown","onPointerOver","onPointerOut","onPointerEnter","onPointerLeave","onPointerMove"];let E,R,A;const L=t.ref({x:1/0,y:1/0});let C=!1;let P=[];const M=()=>{const e=W.value?.instance,t=k.value?.instance;if(!e||!t)return;e.setFromCamera(ue.mousePos.value,t);const n=e.intersectObjects(b.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=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})})),P=[].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 H.RendererRootNode(t)),e.lunchboxTree}function B(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=B(e);if(t)return t;const a=N(),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=j(["PerspectiveCamera","OrthographicCamera"],"FALLBACK_CAMERA",{args:[45,.5625,1,1e3]}),S="FALLBACK_RENDERER",D=j(["WebGLRenderer"],S,{}),F=t.ref(!1),$=t.computed({get:()=>F.value?D.value:null,set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);O[n]=e}}),U=j("Scene","FALLBACK_SCENE"),W=j("Raycaster","AUTO_RAYCASTER",{},(e=>(e=>{if(!e.instance)return;let n=null;n=t.watch((()=>$.value),(e=>{e?.instance&&(C||(E=t=>{const n=(e.instance.domElement.width??1)/ue.dpr.value,r=(e.instance.domElement.height??1)/ue.dpr.value;L.value.x=t.offsetX/n*2-1,L.value.y=-t.offsetY/r*2+1},R=()=>x.value=!0,A=()=>x.value=!1,e.instance.domElement.addEventListener("mousemove",E),e.instance.domElement.addEventListener("mousedown",R),e.instance.domElement.addEventListener("mouseup",A),ne(M),C=!0),n&&n())}),{immediate:!0})})(e))),I=e=>t.defineComponent({inheritAttrs:!1,name:e,render(){return t.h(e,this.$attrs,this.$slots?.default?.()||[])}});var K,_=new Uint8Array(16);function V(){if(!K&&!(K="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 K(_)}var q=/^(?:[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 z(e){return"string"==typeof e&&q.test(e)}for(var H,Y=[],X=0;X<256;++X)Y.push((X+256).toString(16).substr(1));function J(e,t,n){var r=(e=e||{}).random||(e.rng||V)();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=(Y[e[t+0]]+Y[e[t+1]]+Y[e[t+2]]+Y[e[t+3]]+"-"+Y[e[t+4]]+Y[e[t+5]]+"-"+Y[e[t+6]]+Y[e[t+7]]+"-"+Y[e[t+8]]+Y[e[t+9]]+"-"+Y[e[t+10]]+Y[e[t+11]]+Y[e[t+12]]+Y[e[t+13]]+Y[e[t+14]]+Y[e[t+15]]).toLowerCase();if(!z(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??J(),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}(H||(H={}));let Q;(new H.RendererRootNode).minidomType="RootNode";const Z=[],ee=[],te=e=>{Q=requestAnimationFrame((()=>te({app:e.app,renderer:$.value?.instance,scene:U.value.instance,camera:k.value.instance})));const{app:n,renderer:r,scene:o,camera:a}=e;Z.forEach((t=>{t&&t(e)})),r&&o&&a&&r.render(t.toRaw(o),t.toRaw(a)),ee.forEach((t=>{t&&t(e)}))},ne=(e,t=1/0)=>{t===1/0?Z.push(e):Z.splice(t,0,e)},re=()=>{Q&&cancelAnimationFrame(Q)};const oe={x:"position.x",y:"position.y",z:"position.z"},ae=["","parameters"],se=["args","attach","attachArray","key","onAdded","ref","src"],ie=["geometry","material"];function ce(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 de={createElement:(e,t,n,r)=>{const o={type:e};r&&(o.props=r);if(m(e)){const e=function(e={}){const t={domElement:document.createElement(e.type??"")};return new H.RendererDomNode({...t,...e,metaType:"domMeta"})}(o);return e}const a=v(o);return ie.forEach((t=>{e.toLowerCase().endsWith(t)&&(a.props.attach=t)})),a},createText:e=>function(e={}){const t={text:e.text??""};return new H.RendererTextNode({...e,...t,metaType:"textMeta"})}({text:e}),createComment:e=>function(e={}){const t={text:e.text??""};return new H.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&&(m(e)&&(m(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=U.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);ce(e,t,e.props.attach,r)}else n.load(e.props.src,(n=>{ce(e,t,e.props.attach,n)}),null,(e=>{throw new Error(e)}))}(e,t):ce(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){m(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 g({node:e,key:t,value:n});if(se.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=oe[a]||a;for(let e=0;e<ae.length&&!s;e++){const t=[ae[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(){}},ue={dpr:t.ref(1),inputActive:x,mousePos:L},le=t.computed((()=>k.value.instance)),pe=t.computed((()=>$.value?.instance??null)),he=t.computed((()=>U.value.instance));e.camera=le,e.createApp=e=>{const n=t.createRenderer(de).createApp(e);Object.keys(p).forEach((e=>{n.component(e,p[e])}));const{mount:r}=n;return n.mount=(e,...t)=>{const o=N({domElement:"string"==typeof e?document.querySelector(e):e,isLunchboxRootNode:!0,name:"root",metaType:"rootMeta",type:"root",uuid:"LUNCHBOX_ROOT"});n.rootNode=o;return r(o,...t)},n.extend=e=>((({app:e,...t})=>{Object.keys(t).forEach((n=>{e.component(n,I(n)),u[n]=t[n]}))})({app:n,...e}),n),n},e.find=function(e){return e=t.isRef(e)?e.value:e,f(e)?e?.instance:h(e)?e?.$el?.instance:t.isVNode(e)?e.el?.instance:null},e.globals=ue,e.onAfterRender=(e,t=1/0)=>{t===1/0?ee.push(e):ee.splice(t,0,e)},e.onBeforeRender=ne,e.renderer=pe,e.scene=he,e.update=te,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=$.value?.instance,o=U.value.instance;if(!r?.domElement||!o)return;const a=(e=e??window.innerWidth)/(n=n??window.innerHeight),s=k.value;if("perspectivecamera"===s.type?.toLowerCase()){const e=s.instance;e.aspect=a,e.updateProjectionMatrix()}else console.log("TODO: ortho camera update");r.setSize(e,n),o&&s.instance&&r.render(t.toRaw(o),t.toRaw(s.instance))},c=e=>({position:e,top:0,right:0,bottom:0,left:0,width:"100%",height:"100%"}),d={name:"Lunchbox",props:{background:String,cameraPosition:Array,dpr:Number,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;return t.onMounted((()=>{if(!a.value)throw new Error("missing canvas");const o=k.value.instance;if(o&&e.cameraPosition&&o.position.set(...e.cameraPosition),l=B(["WebGLRenderer"]),l)return s.value=!1,void(F.value=!0);{const t={antialias:!0,canvas:a.value.domElement};e.transparent&&(t.alpha=!0),$.value=v({type:"WebGLRenderer",uuid:S,props:{args:[t]}}),F.value=!0;const n=$,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=U.value,p&&p.instance&&e.background&&(p.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),ue.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),te({app:t.getCurrentInstance().appContext.app,camera:o,renderer:l.instance,scene:p.instance})})),t.onBeforeUnmount((()=>{re()})),()=>[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 H.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&&(U.value=r),r}const b=[],x=t.ref(!1);function g({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)&&(W.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=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,E,A;const C=t.ref({x:1/0,y:1/0});let L=!1;let P=[];const M=()=>{const e=W.value?.instance,t=k.value?.instance;if(!e||!t)return;e.setFromCamera(ue.mousePos.value,t);const n=e.intersectObjects(b.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=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})})),P=[].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 H.RendererRootNode(t)),e.lunchboxTree}function B(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=B(e);if(t)return t;const a=N(),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=j(["PerspectiveCamera","OrthographicCamera"],"FALLBACK_CAMERA",{args:[45,.5625,1,1e3]}),S="FALLBACK_RENDERER",D=j(["WebGLRenderer"],S,{}),F=t.ref(!1),$=t.computed({get:()=>F.value?D.value:null,set(e){const t=e.type??"",n=t[0].toUpperCase()+t.slice(1);O[n]=e}}),U=j("Scene","FALLBACK_SCENE"),W=j("Raycaster","AUTO_RAYCASTER",{},(e=>(e=>{if(!e.instance)return;let n=null;n=t.watch((()=>$.value),(e=>{e?.instance&&(L||(w=t=>{const n=(e.instance.domElement.width??1)/ue.dpr.value,r=(e.instance.domElement.height??1)/ue.dpr.value;C.value.x=t.offsetX/n*2-1,C.value.y=-t.offsetY/r*2+1},E=()=>x.value=!0,A=()=>x.value=!1,e.instance.domElement.addEventListener("mousemove",w),e.instance.domElement.addEventListener("mousedown",E),e.instance.domElement.addEventListener("mouseup",A),ne(M),L=!0),n&&n())}),{immediate:!0})})(e))),I=e=>t.defineComponent({inheritAttrs:!1,name:e,render(){return t.h(e,this.$attrs,this.$slots?.default?.()||[])}});var K,_=new Uint8Array(16);function V(){if(!K&&!(K="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 K(_)}var q=/^(?:[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 z(e){return"string"==typeof e&&q.test(e)}for(var H,Y=[],X=0;X<256;++X)Y.push((X+256).toString(16).substr(1));function J(e,t,n){var r=(e=e||{}).random||(e.rng||V)();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=(Y[e[t+0]]+Y[e[t+1]]+Y[e[t+2]]+Y[e[t+3]]+"-"+Y[e[t+4]]+Y[e[t+5]]+"-"+Y[e[t+6]]+Y[e[t+7]]+"-"+Y[e[t+8]]+Y[e[t+9]]+"-"+Y[e[t+10]]+Y[e[t+11]]+Y[e[t+12]]+Y[e[t+13]]+Y[e[t+14]]+Y[e[t+15]]).toLowerCase();if(!z(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??J(),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}(H||(H={}));let Q;(new H.RendererRootNode).minidomType="RootNode";const Z=[],ee=[],te=e=>{Q=requestAnimationFrame((()=>te({app:e.app,renderer:$.value?.instance,scene:U.value.instance,camera:k.value.instance})));const{app:n,renderer:r,scene:o,camera:a}=e;Z.forEach((t=>{t&&t(e)})),r&&o&&a&&(n.customRender?n.customRender(e):r.render(t.toRaw(o),t.toRaw(a))),ee.forEach((t=>{t&&t(e)}))},ne=(e,t=1/0)=>{t===1/0?Z.push(e):Z.splice(t,0,e)},re=()=>{Q&&cancelAnimationFrame(Q)};const oe={x:"position.x",y:"position.y",z:"position.z"},ae=["","parameters"],se=["args","attach","attachArray","key","onAdded","ref","src"],ie=["geometry","material"];function ce(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 de={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 H.RendererDomNode({...t,...e,metaType:"domMeta"})}(o);return e}const a=v(o);return ie.forEach((t=>{e.toLowerCase().endsWith(t)&&(a.props.attach=t)})),a},createText:e=>function(e={}){const t={text:e.text??""};return new H.RendererTextNode({...e,...t,metaType:"textMeta"})}({text:e}),createComment:e=>function(e={}){const t={text:e.text??""};return new H.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&&(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=U.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);ce(e,t,e.props.attach,r)}else n.load(e.props.src,(n=>{ce(e,t,e.props.attach,n)}),null,(e=>{throw new Error(e)}))}(e,t):ce(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 g({node:e,key:t,value:n});if(se.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=oe[a]||a;for(let e=0;e<ae.length&&!s;e++){const t=[ae[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(){}},ue={dpr:t.ref(1),inputActive:x,mousePos:C},le=t.computed((()=>k.value.instance)),pe=t.computed((()=>$.value?.instance??null)),me=t.computed((()=>U.value.instance));let he=null,fe=null;e.camera=le,e.clearCustomRender=()=>{he?he.clearCustomRender():fe=null},e.createApp=e=>{he=t.createRenderer(de).createApp(e),Object.keys(p).forEach((e=>{he.component(e,p[e])}));const{mount:n}=he;return he.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"});he.rootNode=r;return n(r,...t)},he.extend=e=>((({app:e,...t})=>{Object.keys(t).forEach((n=>{e.component(n,I(n)),u[n]=t[n]}))})({app:he,...e}),he),he.setCustomRender=e=>{he.customRender=e},fe&&(he.setCustomRender(fe),fe=null),he.clearCustomRender=()=>{he.customRender=null},he},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=ue,e.onAfterRender=(e,t=1/0)=>{t===1/0?ee.push(e):ee.splice(t,0,e)},e.onBeforeRender=ne,e.renderer=pe,e.scene=me,e.setCustomRender=e=>{he?he.setCustomRender(e):fe=e},Object.defineProperty(e,"__esModule",{value:!0})}));
|
|
@@ -1179,12 +1179,14 @@ let frameID;
|
|
|
1179
1179
|
const beforeRender = [];
|
|
1180
1180
|
const afterRender = [];
|
|
1181
1181
|
const update = (opts) => {
|
|
1182
|
+
// request next frame
|
|
1182
1183
|
frameID = requestAnimationFrame(() => update({
|
|
1183
1184
|
app: opts.app,
|
|
1184
1185
|
renderer: ensureRenderer.value?.instance,
|
|
1185
1186
|
scene: ensuredScene.value.instance,
|
|
1186
1187
|
camera: ensuredCamera.value.instance,
|
|
1187
1188
|
}));
|
|
1189
|
+
// prep options
|
|
1188
1190
|
const { app, renderer, scene, camera } = opts;
|
|
1189
1191
|
// BEFORE RENDER
|
|
1190
1192
|
beforeRender.forEach((cb) => {
|
|
@@ -1193,9 +1195,13 @@ const update = (opts) => {
|
|
|
1193
1195
|
}
|
|
1194
1196
|
});
|
|
1195
1197
|
// RENDER
|
|
1196
|
-
// console.log(camera?.position.z)
|
|
1197
1198
|
if (renderer && scene && camera) {
|
|
1198
|
-
|
|
1199
|
+
if (app.customRender) {
|
|
1200
|
+
app.customRender(opts);
|
|
1201
|
+
}
|
|
1202
|
+
else {
|
|
1203
|
+
renderer.render(toRaw(scene), toRaw(camera));
|
|
1204
|
+
}
|
|
1199
1205
|
}
|
|
1200
1206
|
// AFTER RENDER
|
|
1201
1207
|
afterRender.forEach((cb) => {
|
|
@@ -1576,8 +1582,30 @@ const globals = {
|
|
|
1576
1582
|
const camera = computed(() => ensuredCamera.value.instance);
|
|
1577
1583
|
const renderer = computed(() => ensureRenderer.value?.instance ?? null);
|
|
1578
1584
|
const scene = computed(() => ensuredScene.value.instance);
|
|
1585
|
+
// CUSTOM RENDER SUPPORT
|
|
1586
|
+
// ====================
|
|
1587
|
+
let app = null;
|
|
1588
|
+
let queuedCustomRenderFunction = null;
|
|
1589
|
+
/** Set a custom render function, overriding the Lunchbox app's default render function.
|
|
1590
|
+
* Changing this requires the user to manually render their scene.
|
|
1591
|
+
*/
|
|
1592
|
+
const setCustomRender = (render) => {
|
|
1593
|
+
if (app)
|
|
1594
|
+
app.setCustomRender(render);
|
|
1595
|
+
else
|
|
1596
|
+
queuedCustomRenderFunction = render;
|
|
1597
|
+
};
|
|
1598
|
+
/** Clear the active app's custom render function. */
|
|
1599
|
+
const clearCustomRender = () => {
|
|
1600
|
+
if (app)
|
|
1601
|
+
app.clearCustomRender();
|
|
1602
|
+
else
|
|
1603
|
+
queuedCustomRenderFunction = null;
|
|
1604
|
+
};
|
|
1605
|
+
// CREATE APP
|
|
1606
|
+
// ====================
|
|
1579
1607
|
const createApp = (root) => {
|
|
1580
|
-
|
|
1608
|
+
app = createRenderer(nodeOps).createApp(root);
|
|
1581
1609
|
// register all components
|
|
1582
1610
|
Object.keys(components).forEach((key) => {
|
|
1583
1611
|
app.component(key, components[key]);
|
|
@@ -1600,11 +1628,24 @@ const createApp = (root) => {
|
|
|
1600
1628
|
};
|
|
1601
1629
|
// embed .extend function
|
|
1602
1630
|
app.extend = (targets) => {
|
|
1603
|
-
extend({ app, ...targets });
|
|
1631
|
+
extend({ app: app, ...targets });
|
|
1604
1632
|
return app;
|
|
1605
1633
|
};
|
|
1634
|
+
// prep for custom render support
|
|
1635
|
+
app.setCustomRender = (newRender) => {
|
|
1636
|
+
app.customRender = newRender;
|
|
1637
|
+
};
|
|
1638
|
+
// add queued custom render if we have one
|
|
1639
|
+
if (queuedCustomRenderFunction) {
|
|
1640
|
+
app.setCustomRender(queuedCustomRenderFunction);
|
|
1641
|
+
queuedCustomRenderFunction = null;
|
|
1642
|
+
}
|
|
1643
|
+
// add custom render removal
|
|
1644
|
+
app.clearCustomRender = () => {
|
|
1645
|
+
app.customRender = null;
|
|
1646
|
+
};
|
|
1606
1647
|
// done
|
|
1607
1648
|
return app;
|
|
1608
1649
|
};
|
|
1609
1650
|
|
|
1610
|
-
export { camera, createApp, find, globals, lunchboxRootNode as lunchboxTree, onAfterRender, onBeforeRender, renderer, scene,
|
|
1651
|
+
export { camera, clearCustomRender, createApp, find, globals, lunchboxRootNode as lunchboxTree, onAfterRender, onBeforeRender, renderer, scene, setCustomRender };
|
package/package.json
CHANGED
package/src/core/update.ts
CHANGED
|
@@ -7,12 +7,8 @@ let frameID: number
|
|
|
7
7
|
export const beforeRender = [] as Lunch.UpdateCallback[]
|
|
8
8
|
export const afterRender = [] as Lunch.UpdateCallback[]
|
|
9
9
|
|
|
10
|
-
export const update: Lunch.UpdateCallback = (opts
|
|
11
|
-
|
|
12
|
-
renderer?: THREE.Renderer | null
|
|
13
|
-
scene?: THREE.Scene | null
|
|
14
|
-
camera?: THREE.Camera | null
|
|
15
|
-
}) => {
|
|
10
|
+
export const update: Lunch.UpdateCallback = (opts) => {
|
|
11
|
+
// request next frame
|
|
16
12
|
frameID = requestAnimationFrame(() =>
|
|
17
13
|
update({
|
|
18
14
|
app: opts.app,
|
|
@@ -22,6 +18,7 @@ export const update: Lunch.UpdateCallback = (opts: {
|
|
|
22
18
|
})
|
|
23
19
|
)
|
|
24
20
|
|
|
21
|
+
// prep options
|
|
25
22
|
const { app, renderer, scene, camera } = opts
|
|
26
23
|
|
|
27
24
|
// BEFORE RENDER
|
|
@@ -32,9 +29,12 @@ export const update: Lunch.UpdateCallback = (opts: {
|
|
|
32
29
|
})
|
|
33
30
|
|
|
34
31
|
// RENDER
|
|
35
|
-
// console.log(camera?.position.z)
|
|
36
32
|
if (renderer && scene && camera) {
|
|
37
|
-
|
|
33
|
+
if (app.customRender) {
|
|
34
|
+
app.customRender(opts)
|
|
35
|
+
} else {
|
|
36
|
+
renderer.render(toRaw(scene), toRaw(camera))
|
|
37
|
+
}
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
// AFTER RENDER
|
package/src/index.ts
CHANGED
|
@@ -12,13 +12,12 @@ import {
|
|
|
12
12
|
inputActive,
|
|
13
13
|
mousePos,
|
|
14
14
|
rootUuid,
|
|
15
|
-
update,
|
|
16
15
|
} from './core'
|
|
17
16
|
import { components } from './components'
|
|
18
17
|
import { Lunch } from './types'
|
|
19
18
|
|
|
20
19
|
export { lunchboxRootNode as lunchboxTree } from './core'
|
|
21
|
-
export { onBeforeRender, onAfterRender
|
|
20
|
+
export { onBeforeRender, onAfterRender } from './core'
|
|
22
21
|
export * from './types'
|
|
23
22
|
|
|
24
23
|
// Utilities
|
|
@@ -35,12 +34,37 @@ export const camera = computed(() => ensuredCamera.value.instance)
|
|
|
35
34
|
export const renderer = computed(() => ensureRenderer.value?.instance ?? null)
|
|
36
35
|
export const scene = computed(() => ensuredScene.value.instance)
|
|
37
36
|
|
|
37
|
+
// CUSTOM RENDER SUPPORT
|
|
38
|
+
// ====================
|
|
39
|
+
let app: Lunch.App | null = null
|
|
40
|
+
let queuedCustomRenderFunction:
|
|
41
|
+
| ((opts: Lunch.UpdateCallbackProperties) => void)
|
|
42
|
+
| null = null
|
|
43
|
+
|
|
44
|
+
/** Set a custom render function, overriding the Lunchbox app's default render function.
|
|
45
|
+
* Changing this requires the user to manually render their scene.
|
|
46
|
+
*/
|
|
47
|
+
export const setCustomRender = (
|
|
48
|
+
render: (opts: Lunch.UpdateCallbackProperties) => void
|
|
49
|
+
) => {
|
|
50
|
+
if (app) app.setCustomRender(render)
|
|
51
|
+
else queuedCustomRenderFunction = render
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Clear the active app's custom render function. */
|
|
55
|
+
export const clearCustomRender = () => {
|
|
56
|
+
if (app) app.clearCustomRender()
|
|
57
|
+
else queuedCustomRenderFunction = null
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// CREATE APP
|
|
61
|
+
// ====================
|
|
38
62
|
export const createApp = (root: Component) => {
|
|
39
|
-
|
|
63
|
+
app = createRenderer(nodeOps).createApp(root) as Lunch.App
|
|
40
64
|
|
|
41
65
|
// register all components
|
|
42
66
|
Object.keys(components).forEach((key) => {
|
|
43
|
-
app
|
|
67
|
+
app!.component(key, (components as any)[key])
|
|
44
68
|
})
|
|
45
69
|
|
|
46
70
|
// update mount function to match Lunchbox.Node
|
|
@@ -57,15 +81,33 @@ export const createApp = (root: Component) => {
|
|
|
57
81
|
type: 'root',
|
|
58
82
|
uuid: rootUuid,
|
|
59
83
|
})
|
|
60
|
-
app
|
|
84
|
+
app!.rootNode = rootNode
|
|
61
85
|
const mounted = mount(rootNode, ...args)
|
|
62
86
|
return mounted
|
|
63
87
|
}
|
|
64
88
|
|
|
65
89
|
// embed .extend function
|
|
66
90
|
app.extend = (targets: Record<string, any>) => {
|
|
67
|
-
extend({ app
|
|
68
|
-
return app
|
|
91
|
+
extend({ app: app!, ...targets })
|
|
92
|
+
return app!
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// prep for custom render support
|
|
96
|
+
app.setCustomRender = (
|
|
97
|
+
newRender: (opts: Lunch.UpdateCallbackProperties) => void
|
|
98
|
+
) => {
|
|
99
|
+
app!.customRender = newRender
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// add queued custom render if we have one
|
|
103
|
+
if (queuedCustomRenderFunction) {
|
|
104
|
+
app.setCustomRender(queuedCustomRenderFunction)
|
|
105
|
+
queuedCustomRenderFunction = null
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// add custom render removal
|
|
109
|
+
app.clearCustomRender = () => {
|
|
110
|
+
app!.customRender = null
|
|
69
111
|
}
|
|
70
112
|
|
|
71
113
|
// done
|
package/src/types.ts
CHANGED
|
@@ -7,8 +7,13 @@ type RendererStandardNode<T = THREE.Object3D> =
|
|
|
7
7
|
export declare namespace Lunch {
|
|
8
8
|
/** Lunchbox app. */
|
|
9
9
|
type App = VueApp<any> & {
|
|
10
|
+
clearCustomRender: () => void
|
|
11
|
+
customRender: ((opts: UpdateCallbackProperties) => void) | null
|
|
10
12
|
extend: (v: Record<string, any>) => App
|
|
11
13
|
rootNode: RootNode
|
|
14
|
+
setCustomRender: (
|
|
15
|
+
update: (opts: UpdateCallbackProperties) => void
|
|
16
|
+
) => void
|
|
12
17
|
update: UpdateCallback
|
|
13
18
|
}
|
|
14
19
|
|