lunchboxjs 0.1.4010 → 0.1.4013

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/LICENSE.md ADDED
@@ -0,0 +1,7 @@
1
+ Copyright 2022 Breakfast Studio, LLC
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -115,6 +115,7 @@
115
115
  rendererProperties: Object,
116
116
  shadow: [Boolean, Object],
117
117
  transparent: Boolean,
118
+ zoom: Number,
118
119
  },
119
120
  setup(props, context) {
120
121
  const canvas = vue.ref();
@@ -228,6 +229,10 @@
228
229
  const source = (props.cameraLookAt || props.cameraLook);
229
230
  camera.instance.lookAt(...source);
230
231
  }
232
+ // zoom camera if needed
233
+ if (camera && props.zoom !== undefined) {
234
+ camera.instance.zoom = props.zoom;
235
+ }
231
236
  // SCENE
232
237
  // ====================
233
238
  scene = ensuredScene.value;
@@ -470,15 +475,20 @@
470
475
  inheritAttrs: false,
471
476
  name: tag,
472
477
  setup(props, context) {
473
- return () => vue.h(tag, context.attrs, context.slots?.default?.() || []);
478
+ return () => {
479
+ return vue.h(tag, context.attrs, context.slots?.default?.() || []);
480
+ };
474
481
  },
475
482
  });
476
- autoGeneratedComponents.map(createComponent$1).reduce((acc, curr) => {
483
+ // turn components into registered map
484
+ const processed = autoGeneratedComponents
485
+ .map(createComponent$1)
486
+ .reduce((acc, curr) => {
477
487
  acc[curr.name] = curr;
478
488
  return acc;
479
- });
489
+ }, {});
480
490
  const components = {
481
- ...autoGeneratedComponents,
491
+ ...processed,
482
492
  Lunchbox: LunchboxWrapper,
483
493
  };
484
494
 
@@ -833,6 +843,12 @@
833
843
  const found = autoCreated[singleType] ||
834
844
  allNodes.find((node) => node.type?.toLowerCase() ===
835
845
  singleType.toLowerCase());
846
+ // cancel if found example is marked !isDefault
847
+ if (isMinidomNode(found) &&
848
+ (found.props['is-default'] === false ||
849
+ !found.props['isDefault'] === false)) {
850
+ return null;
851
+ }
836
852
  // if we have one, save and return
837
853
  if (found) {
838
854
  const createdAsNode = found;
@@ -964,10 +980,10 @@
964
980
  name: tag,
965
981
  render() {
966
982
  return vue.h(tag, this.$attrs, this.$slots?.default?.() || []);
967
- }
983
+ },
968
984
  });
969
985
  const extend = ({ app, ...targets }) => {
970
- Object.keys(targets).forEach(key => {
986
+ Object.keys(targets).forEach((key) => {
971
987
  app.component(key, createComponent(key));
972
988
  catalogue[key] = targets[key];
973
989
  });
@@ -1271,6 +1287,9 @@
1271
1287
  }
1272
1288
  MiniDom.RendererStandardNode = RendererStandardNode;
1273
1289
  })(MiniDom || (MiniDom = {}));
1290
+ function isMinidomNode(item) {
1291
+ return item?.minidomType === 'RendererNode';
1292
+ }
1274
1293
  const rootNode = new MiniDom.RendererRootNode();
1275
1294
  rootNode.minidomType = 'RootNode';
1276
1295
 
@@ -1365,8 +1384,13 @@
1365
1384
  if (isEventKey(key)) {
1366
1385
  return addEventListener({ node, key, value });
1367
1386
  }
1387
+ // update THREE property
1388
+ // get final key
1389
+ const camelKey = key.replace(/-/g, '.');
1390
+ const finalKey = propertyShortcuts[camelKey] || camelKey;
1368
1391
  // handle and return early if prop is specific to Vue/Lunchbox
1369
- if (internalLunchboxVueKeys.includes(key))
1392
+ if (internalLunchboxVueKeys.includes(key) ||
1393
+ internalLunchboxVueKeys.includes(finalKey))
1370
1394
  return node;
1371
1395
  // everything else should be Three-specific, so let's cancel if this isn't a standard node
1372
1396
  if (!isLunchboxStandardNode(node))
@@ -1381,12 +1405,8 @@
1381
1405
  // cancel if no target
1382
1406
  if (!target)
1383
1407
  return node;
1384
- // update THREE property
1385
- // get final key
1386
- const camelKey = key.replace(/-/g, '.');
1387
- let finalKey = propertyShortcuts[camelKey] || camelKey;
1388
- let liveProperty;
1389
1408
  // burrow down until we get property to change
1409
+ let liveProperty;
1390
1410
  for (let i = 0; i < nestedPropertiesToCheck.length && !liveProperty; i++) {
1391
1411
  const nestedProperty = nestedPropertiesToCheck[i];
1392
1412
  const fullPath = [nestedProperty, finalKey].filter(Boolean).join('.');
@@ -1451,6 +1471,8 @@
1451
1471
  'args',
1452
1472
  'attach',
1453
1473
  'attachArray',
1474
+ 'is.default',
1475
+ 'isDefault',
1454
1476
  'key',
1455
1477
  'onAdded',
1456
1478
  // 'onReady',
@@ -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=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})}));
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=z.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,cameraLook:Array,cameraLookAt:Array,cameraPosition:Array,dpr:Number,ortho:Boolean,orthographic:Boolean,rendererArguments:Object,rendererProperties:Object,shadow:[Boolean,Object],transparent:Boolean,zoom:Number},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=G(["WebGLRenderer"]),l)s.value=!1,W.value=!0;else{const t={alpha:e.transparent,antialias:!0,canvas:a.value.domElement,...e.rendererArguments??{}};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=G(["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.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(p&&void 0!==e.zoom&&(p.instance.zoom=e.zoom),m=z.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),he.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 te)e({app:o,camera:p.instance,renderer:l.instance,scene:m.instance});ae({app:o,camera:p.instance,renderer:l.instance,scene:m.instance})})),t.onBeforeUnmount((()=>{ie()})),()=>[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&&(z.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)&&(K.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,A,C;const E=t.ref({x:1/0,y:1/0});let L=!1;let P=[];const M=()=>{const e=K.value?.instance,t=F.value?.instance;if(!e||!t)return;e.setFromCamera(he.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})=>{N({element:e,eventKeys:["onPointerEnter"],intersection:t})})),a.forEach((({element:e,intersection:t})=>{N({element:e,eventKeys:["onPointerOver","onPointerMove"],intersection:t})})),s.forEach((({element:e,intersection:t})=>{N({element:e,eventKeys:["onPointerLeave","onPointerOut"],intersection:t})})),P=[].concat(o,a)},N=({element:e,eventKeys:t,intersection:n})=>{e&&t.forEach((t=>{e.eventListeners[t]&&e.eventListeners[t].forEach((e=>{e({intersection:n})}))}))};function B(t={}){return e.lunchboxTree||(e.lunchboxTree=new J.RendererRootNode(t)),e.lunchboxTree}function G(e){Array.isArray(e)||(e=[e]);for(let t of e)if(O[t])return O[t];for(let n of e){const e=T[n]||s.find((e=>e.type?.toLowerCase()===n.toLowerCase()));if(!(t=e,"RendererNode"!==t?.minidomType||!1!==e.props["is-default"]&&!1!=!e.props.isDefault))return null;if(e){const t=e;return T[n]=t,t}}var t;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=G(e);if(t)return t;const a=B(),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}}),z=j("Scene","FALLBACK_SCENE"),K=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)/he.dpr.value,r=(e.instance.domElement.height??1)/he.dpr.value;E.value.x=t.offsetX/n*2-1,E.value.y=-t.offsetY/r*2+1},A=()=>b.value=!0,C=()=>b.value=!1,e.instance.domElement.addEventListener("mousemove",w),e.instance.domElement.addEventListener("mousedown",A),e.instance.domElement.addEventListener("mouseup",C),se(M),L=!0),n&&n())}),{immediate:!0})})(e))),_=e=>t.defineComponent({inheritAttrs:!1,name:e,render(){return t.h(e,this.$attrs,this.$slots?.default?.()||[])}});var V,q=new Uint8Array(16);function H(){if(!V&&!(V="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 V(q)}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={}));(new J.RendererRootNode).minidomType="RootNode";const te=[];let ne;const re=[],oe=[],ae=e=>{ne=requestAnimationFrame((()=>ae({app:e.app,renderer:I.value?.instance,scene:z.value.instance,camera:F.value?.instance})));const{app:n,renderer:r,scene:o,camera:a}=e;re.forEach((t=>{t&&t(e)})),r&&o&&a&&(n.customRender?n.customRender(e):r.render(t.toRaw(o),t.toRaw(a))),oe.forEach((t=>{t&&t(e)}))},se=(e,t=1/0)=>{t===1/0?re.push(e):re.splice(t,0,e)},ie=()=>{ne&&cancelAnimationFrame(ne)};const ce={x:"position.x",y:"position.y",z:"position.z"},de=["","parameters"],ue=["args","attach","attachArray","is.default","isDefault","key","onAdded","ref","src"],le=["geometry","material"];function pe(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 me={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 le.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??B();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=z.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);pe(e,t,e.props.attach,r)}else n.load(e.props.src,(n=>{pe(e,t,e.props.attach,n)}),null,(e=>{throw new Error(e)}))}(e,t):pe(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});const o=t.replace(/-/g,"."),a=ce[o]||o;if(ue.includes(t)||ue.includes(a))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 s=e.instance;if(!s)return e;let i;for(let e=0;e<de.length&&!i;e++){const t=[de[e],a].filter(Boolean).join(".");i=i=r.get(s,t)}if(i&&r.isNumber(n)&&i.setScalar)i.setScalar(n);else if(i&&i.set){const e=Array.isArray(n)?n:[n];s[a].set(...e)}else"function"==typeof i?i.bind(e.instance)(...n):void 0!==r.get(s,a,void 0)?r.set(s,a,""===n||n):console.log(`No property ${a} found on ${s}`);const c=s?.texture?.type||s?.type;if("string"==typeof c){const e=c.toLowerCase();switch(!0){case e.includes("material"):s.needsUpdate=!0;break;case e.includes("camera")&&s.updateProjectionMatrix:s.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(){}},he={dpr:t.ref(1),inputActive:b,mousePos:E},fe=t.computed((()=>F.value?.instance??null));const ye=t.computed((()=>I.value?.instance??null));const ve=t.computed((()=>z.value.instance));let ge=null,be=null;e.camera=fe,e.clearCustomRender=()=>{ge?ge.clearCustomRender():be=null},e.createApp=e=>{ge=t.createRenderer(me).createApp(e),Object.keys(p).forEach((e=>{ge.component(e,p[e])}));const{mount:n}=ge;return ge.mount=(e,...t)=>{const r=B({domElement:"string"==typeof e?document.querySelector(e):e,isLunchboxRootNode:!0,name:"root",metaType:"rootMeta",type:"root",uuid:"LUNCHBOX_ROOT"});ge.rootNode=r;return n(r,...t)},ge.extend=e=>((({app:e,...t})=>{Object.keys(t).forEach((n=>{e.component(n,_(n)),u[n]=t[n]}))})({app:ge,...e}),ge),ge.setCustomRender=e=>{ge.customRender=e},be&&(ge.setCustomRender(be),be=null),ge.clearCustomRender=()=>{ge.customRender=null},ge},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=he,e.offAfterRender=e=>{if(isFinite(e))oe.splice(e,1);else{const t=oe.findIndex((t=>t==e));oe.splice(t,1)}},e.offBeforeRender=e=>{if(isFinite(e))re.splice(e,1);else{const t=re.findIndex((t=>t==e));re.splice(t,1)}},e.onAfterRender=(e,t=1/0)=>{t===1/0?oe.push(e):oe.splice(t,0,e)},e.onBeforeRender=se,e.onStart=(e,t=1/0)=>{t===1/0?te.push(e):te.splice(t,0,e)},e.renderer=ye,e.scene=ve,e.setCustomRender=e=>{ge?ge.setCustomRender(e):be=e},e.useCamera=function(e,n=!0){let r;r=t.watch(fe,(t=>{t&&(e(t),n&&r?.())}),{immediate:!0})},e.useRenderer=function(e,n=!0){let r;r=t.watch(ye,(t=>{t&&(e(t),n&&r?.())}),{immediate:!0})},e.useScene=function(e,n=!0){let r;r=t.watch(ve,(t=>{t&&(e(t),n&&r?.())}),{immediate:!0})},Object.defineProperty(e,"__esModule",{value:!0})}));
@@ -94,6 +94,7 @@ const LunchboxWrapper = {
94
94
  rendererProperties: Object,
95
95
  shadow: [Boolean, Object],
96
96
  transparent: Boolean,
97
+ zoom: Number,
97
98
  },
98
99
  setup(props, context) {
99
100
  const canvas = ref();
@@ -207,6 +208,10 @@ const LunchboxWrapper = {
207
208
  const source = (props.cameraLookAt || props.cameraLook);
208
209
  camera.instance.lookAt(...source);
209
210
  }
211
+ // zoom camera if needed
212
+ if (camera && props.zoom !== undefined) {
213
+ camera.instance.zoom = props.zoom;
214
+ }
210
215
  // SCENE
211
216
  // ====================
212
217
  scene = ensuredScene.value;
@@ -449,15 +454,20 @@ const createComponent$1 = (tag) => defineComponent({
449
454
  inheritAttrs: false,
450
455
  name: tag,
451
456
  setup(props, context) {
452
- return () => h(tag, context.attrs, context.slots?.default?.() || []);
457
+ return () => {
458
+ return h(tag, context.attrs, context.slots?.default?.() || []);
459
+ };
453
460
  },
454
461
  });
455
- autoGeneratedComponents.map(createComponent$1).reduce((acc, curr) => {
462
+ // turn components into registered map
463
+ const processed = autoGeneratedComponents
464
+ .map(createComponent$1)
465
+ .reduce((acc, curr) => {
456
466
  acc[curr.name] = curr;
457
467
  return acc;
458
- });
468
+ }, {});
459
469
  const components = {
460
- ...autoGeneratedComponents,
470
+ ...processed,
461
471
  Lunchbox: LunchboxWrapper,
462
472
  };
463
473
 
@@ -812,6 +822,12 @@ function tryGetNodeWithInstanceType(pascalCaseTypes) {
812
822
  const found = autoCreated[singleType] ||
813
823
  allNodes.find((node) => node.type?.toLowerCase() ===
814
824
  singleType.toLowerCase());
825
+ // cancel if found example is marked !isDefault
826
+ if (isMinidomNode(found) &&
827
+ (found.props['is-default'] === false ||
828
+ !found.props['isDefault'] === false)) {
829
+ return null;
830
+ }
815
831
  // if we have one, save and return
816
832
  if (found) {
817
833
  const createdAsNode = found;
@@ -943,10 +959,10 @@ const createComponent = (tag) => defineComponent({
943
959
  name: tag,
944
960
  render() {
945
961
  return h(tag, this.$attrs, this.$slots?.default?.() || []);
946
- }
962
+ },
947
963
  });
948
964
  const extend = ({ app, ...targets }) => {
949
- Object.keys(targets).forEach(key => {
965
+ Object.keys(targets).forEach((key) => {
950
966
  app.component(key, createComponent(key));
951
967
  catalogue[key] = targets[key];
952
968
  });
@@ -1250,6 +1266,9 @@ var MiniDom;
1250
1266
  }
1251
1267
  MiniDom.RendererStandardNode = RendererStandardNode;
1252
1268
  })(MiniDom || (MiniDom = {}));
1269
+ function isMinidomNode(item) {
1270
+ return item?.minidomType === 'RendererNode';
1271
+ }
1253
1272
  const rootNode = new MiniDom.RendererRootNode();
1254
1273
  rootNode.minidomType = 'RootNode';
1255
1274
 
@@ -1344,8 +1363,13 @@ function updateObjectProp({ node, key, value, }) {
1344
1363
  if (isEventKey(key)) {
1345
1364
  return addEventListener({ node, key, value });
1346
1365
  }
1366
+ // update THREE property
1367
+ // get final key
1368
+ const camelKey = key.replace(/-/g, '.');
1369
+ const finalKey = propertyShortcuts[camelKey] || camelKey;
1347
1370
  // handle and return early if prop is specific to Vue/Lunchbox
1348
- if (internalLunchboxVueKeys.includes(key))
1371
+ if (internalLunchboxVueKeys.includes(key) ||
1372
+ internalLunchboxVueKeys.includes(finalKey))
1349
1373
  return node;
1350
1374
  // everything else should be Three-specific, so let's cancel if this isn't a standard node
1351
1375
  if (!isLunchboxStandardNode(node))
@@ -1360,12 +1384,8 @@ function updateObjectProp({ node, key, value, }) {
1360
1384
  // cancel if no target
1361
1385
  if (!target)
1362
1386
  return node;
1363
- // update THREE property
1364
- // get final key
1365
- const camelKey = key.replace(/-/g, '.');
1366
- let finalKey = propertyShortcuts[camelKey] || camelKey;
1367
- let liveProperty;
1368
1387
  // burrow down until we get property to change
1388
+ let liveProperty;
1369
1389
  for (let i = 0; i < nestedPropertiesToCheck.length && !liveProperty; i++) {
1370
1390
  const nestedProperty = nestedPropertiesToCheck[i];
1371
1391
  const fullPath = [nestedProperty, finalKey].filter(Boolean).join('.');
@@ -1430,6 +1450,8 @@ const internalLunchboxVueKeys = [
1430
1450
  'args',
1431
1451
  'attach',
1432
1452
  'attachArray',
1453
+ 'is.default',
1454
+ 'isDefault',
1433
1455
  'key',
1434
1456
  'onAdded',
1435
1457
  // 'onReady',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lunchboxjs",
3
- "version": "0.1.4010",
3
+ "version": "0.1.4013",
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",
@@ -36,7 +36,7 @@
36
36
  "vue-tsc": "^0.3.0"
37
37
  },
38
38
  "peerDependencies": {
39
- "three": "^0.133.1"
39
+ "three": "0.137.5"
40
40
  },
41
41
  "files": [
42
42
  "dist",
@@ -56,6 +56,7 @@ export const LunchboxWrapper: ComponentOptions = {
56
56
  rendererProperties: Object,
57
57
  shadow: [Boolean, Object],
58
58
  transparent: Boolean,
59
+ zoom: Number,
59
60
  },
60
61
  setup(props: Lunch.WrapperProps, context) {
61
62
  const canvas = ref<MiniDom.RendererDomNode>()
@@ -184,6 +185,10 @@ export const LunchboxWrapper: ComponentOptions = {
184
185
  const source = (props.cameraLookAt || props.cameraLook)!
185
186
  camera.instance.lookAt(...source)
186
187
  }
188
+ // zoom camera if needed
189
+ if (camera && props.zoom !== undefined) {
190
+ ;(camera.instance as THREE.OrthographicCamera).zoom = props.zoom
191
+ }
187
192
 
188
193
  // SCENE
189
194
  // ====================
@@ -13,16 +13,21 @@ const createComponent = (tag: string) =>
13
13
  inheritAttrs: false,
14
14
  name: tag,
15
15
  setup(props, context) {
16
- return () => h(tag, context.attrs, context.slots?.default?.() || [])
16
+ return () => {
17
+ return h(tag, context.attrs, context.slots?.default?.() || [])
18
+ }
17
19
  },
18
20
  })
19
21
 
20
- autoGeneratedComponents.map(createComponent).reduce((acc, curr) => {
21
- ;(acc as any)[curr.name] = curr
22
- return acc
23
- })
22
+ // turn components into registered map
23
+ const processed = autoGeneratedComponents
24
+ .map(createComponent)
25
+ .reduce((acc, curr) => {
26
+ acc[curr.name] = curr
27
+ return acc
28
+ }, {} as Record<string, ReturnType<typeof defineComponent>>)
24
29
 
25
30
  export const components = {
26
- ...autoGeneratedComponents,
31
+ ...processed,
27
32
  Lunchbox: LunchboxWrapper,
28
33
  }
@@ -1,4 +1,4 @@
1
- import { allNodes, createNode, MiniDom } from '.'
1
+ import { allNodes, createNode, isMinidomNode, MiniDom } from '.'
2
2
  import { setupAutoRaycaster } from './interaction/setupAutoRaycaster'
3
3
  import { computed, reactive, ref, WritableComputedRef } from 'vue'
4
4
  import { Lunch } from '..'
@@ -38,6 +38,15 @@ export function tryGetNodeWithInstanceType<T extends THREE.Object3D>(
38
38
  singleType.toLowerCase()
39
39
  )
40
40
 
41
+ // cancel if found example is marked !isDefault
42
+ if (
43
+ isMinidomNode(found) &&
44
+ (found.props['is-default'] === false ||
45
+ !found.props['isDefault'] === false)
46
+ ) {
47
+ return null
48
+ }
49
+
41
50
  // if we have one, save and return
42
51
  if (found) {
43
52
  const createdAsNode = found as MiniDom.RendererStandardNode<T>
@@ -8,12 +8,18 @@ const createComponent = (tag: string) =>
8
8
  name: tag,
9
9
  render() {
10
10
  return h(tag, this.$attrs, this.$slots?.default?.() || [])
11
- }
11
+ },
12
12
  })
13
13
 
14
- export const extend = ({ app, ...targets }: { app: Lunch.App, [key: string]: any }) => {
15
- Object.keys(targets).forEach(key => {
14
+ export const extend = ({
15
+ app,
16
+ ...targets
17
+ }: {
18
+ app: Lunch.App
19
+ [key: string]: any
20
+ }) => {
21
+ Object.keys(targets).forEach((key) => {
16
22
  app.component(key, createComponent(key))
17
23
  catalogue[key] = targets[key]
18
24
  })
19
- }
25
+ }
@@ -31,8 +31,17 @@ export function updateObjectProp({
31
31
  return addEventListener({ node, key, value })
32
32
  }
33
33
 
34
+ // update THREE property
35
+ // get final key
36
+ const camelKey = key.replace(/-/g, '.')
37
+ const finalKey = propertyShortcuts[camelKey] || camelKey
38
+
34
39
  // handle and return early if prop is specific to Vue/Lunchbox
35
- if (internalLunchboxVueKeys.includes(key)) return node
40
+ if (
41
+ internalLunchboxVueKeys.includes(key) ||
42
+ internalLunchboxVueKeys.includes(finalKey)
43
+ )
44
+ return node
36
45
 
37
46
  // everything else should be Three-specific, so let's cancel if this isn't a standard node
38
47
  if (!isLunchboxStandardNode(node)) return node
@@ -49,12 +58,8 @@ export function updateObjectProp({
49
58
  // cancel if no target
50
59
  if (!target) return node
51
60
 
52
- // update THREE property
53
- // get final key
54
- const camelKey = key.replace(/-/g, '.')
55
- let finalKey = propertyShortcuts[camelKey] || camelKey
56
- let liveProperty
57
61
  // burrow down until we get property to change
62
+ let liveProperty
58
63
  for (let i = 0; i < nestedPropertiesToCheck.length && !liveProperty; i++) {
59
64
  const nestedProperty = nestedPropertiesToCheck[i]
60
65
  const fullPath = [nestedProperty, finalKey].filter(Boolean).join('.')
@@ -128,6 +133,8 @@ const internalLunchboxVueKeys = [
128
133
  'args',
129
134
  'attach',
130
135
  'attachArray',
136
+ 'is.default',
137
+ 'isDefault',
131
138
  'key',
132
139
  'onAdded',
133
140
  // 'onReady',
package/src/types.ts CHANGED
@@ -150,5 +150,6 @@ export declare namespace Lunch {
150
150
  rendererProperties?: Partial<THREE.WebGLRenderer>
151
151
  shadow?: ShadowSugar
152
152
  transparent?: boolean
153
+ zoom?: number
153
154
  }
154
155
  }
@@ -23,7 +23,9 @@ export const isEventKey = (target: any): target is Lunch.EventKey => {
23
23
  ].includes(target)
24
24
  }
25
25
 
26
- export const isLunchboxComponent = (node: any): node is Lunch.LunchboxComponent => {
26
+ export const isLunchboxComponent = (
27
+ node: any
28
+ ): node is Lunch.LunchboxComponent => {
27
29
  return node?.$el && node?.$el?.hasOwnProperty?.('instance')
28
30
  }
29
31
 
@@ -35,10 +37,12 @@ export const isLunchboxDomComponent = (node: any): node is Lunch.DomMeta => {
35
37
  return lunchboxDomComponentNames.includes(typeToCheck ?? '')
36
38
  }
37
39
 
38
- export const isLunchboxStandardNode = (node: any): node is Lunch.StandardMeta => {
40
+ export const isLunchboxStandardNode = (
41
+ node: any
42
+ ): node is Lunch.StandardMeta => {
39
43
  return node?.metaType === 'standardMeta'
40
44
  }
41
45
 
42
46
  export const isLunchboxRootNode = (node: any): node is Lunch.RootMeta => {
43
47
  return node.isLunchboxRootNode
44
- }
48
+ }