UNPKG

@yaelg/tresjs-core

Version:

Declarative ThreeJS using Vue Components

9 lines (8 loc) 18.8 kB
/** * name: @yaelg/tresjs-core * version: v3.3.0 * (c) 2023 * description: Declarative ThreeJS using Vue Components * author: Alvaro Saburido <hola@alvarosaburido.dev> (https://github.com/alvarosabu/) */ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const c=require("vue"),P=require("three"),C=require("@vueuse/core");function oe(e){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e){for(const t in e)if(t!=="default"){const r=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(n,t,r.get?r:{enumerable:!0,get:()=>e[t]})}}return n.default=e,Object.freeze(n)}const ae=oe(P),N=({sizes:e,scene:n})=>{const t=c.ref([]),r=c.computed(()=>t.value[0]),o=(s,p=!1)=>{t.value.some(({uuid:i})=>i===s.uuid)||(p?f(s):t.value.push(s))},a=s=>{t.value=t.value.filter(({uuid:p})=>p!==s.uuid)},f=s=>{const p=s instanceof P.Camera?s:t.value.find(m=>m.uuid===s);if(!p)return;const i=t.value.filter(({uuid:m})=>m!==p.uuid);t.value=[p,...i]};return c.watchEffect(()=>{e.aspectRatio.value&&t.value.forEach(s=>{s instanceof P.PerspectiveCamera&&(s.aspect=e.aspectRatio.value),(s instanceof P.PerspectiveCamera||s instanceof P.OrthographicCamera)&&s.updateProjectionMatrix()})}),n.userData.tres__registerCamera=o,n.userData.tres__deregisterCamera=a,c.onUnmounted(()=>{t.value=[]}),{camera:r,cameras:t,registerCamera:o,deregisterCamera:a,setCameraActive:f}},q=C.createEventHook(),U=C.createEventHook(),V=C.createEventHook(),x=new P.Clock;let B=0,S=0;const{pause:se,resume:ie,isActive:ue}=C.useRafFn(()=>{q.trigger({delta:B,elapsed:S,clock:x}),U.trigger({delta:B,elapsed:S,clock:x}),V.trigger({delta:B,elapsed:S,clock:x})},{immediate:!1});V.on(()=>{B=x.getDelta(),S=x.getElapsedTime()});const z=()=>({onBeforeLoop:q.on,onLoop:U.on,onAfterLoop:V.on,pause:se,resume:ie,isActive:ue}),le=!0,F="[TresJS ▲ ■ ●] ";function D(){function e(r,o){console.error(`${F} ${r}`,o||"")}function n(r){console.warn(`${F} ${r}`)}function t(r,o){}return{logError:e,logWarning:n,logMessage:t}}function ce(e){return typeof e=="number"?[e,e,e]:e instanceof P.Vector3?[e.x,e.y,e.z]:e}function J(e){return e instanceof P.Color?e:Array.isArray(e)?new P.Color(...e):new P.Color(e)}const K=(e,n)=>{for(const t of Object.keys(n))n[t]instanceof Object&&Object.assign(n[t],K(e[t],n[t]));return Object.assign(e||{},n),e},fe="html,body,base,head,link,meta,style,title,address,article,aside,footer,header,hgroup,h1,h2,h3,h4,h5,h6,nav,section,div,dd,dl,dt,figcaption,figure,picture,hr,img,li,main,ol,p,pre,ul,a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,ruby,s,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,embed,object,param,source,canvas,script,noscript,del,ins,caption,col,colgroup,table,thead,tbody,td,th,tr,button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,output,progress,select,textarea,details,dialog,menu,summary,template,blockquote,iframe,tfoot",pe=me(fe);function G(e){return e&&e.nodeType===1}function L(e){return e.replace(/-([a-z])/g,(n,t)=>t.toUpperCase())}function me(e,n){const t=Object.create(null),r=e.split(",");for(let o=0;o<r.length;o++)t[r[o]]=!0;return n?o=>!!t[o.toLowerCase()]:o=>!!t[o]}const ve=(e,n)=>{const t=new Set,r=[];for(const o of e){const a=n(o);t.has(a)||(t.add(a),r.push(o))}return r},I=(e,n)=>{if(!n)return;const t=Array.isArray(n)?n:n.match(/([^[.\]])+/g);return t==null?void 0:t.reduce((r,o)=>r&&r[o],e)},de=(e,n,t)=>{const r=Array.isArray(n)?n:n.match(/([^[.\]])+/g);r&&r.reduce((o,a,f)=>(o[a]===void 0&&(o[a]={}),f===r.length-1&&(o[a]=t),o[a]),e)};function X(e,n){if(G(e)&&G(n)){const o=e.attributes,a=n.attributes;return o.length!==a.length?!1:Array.from(o).every(({name:f,value:s})=>n.getAttribute(f)===s)}if(e===n)return!0;if(e===null||typeof e!="object"||n===null||typeof n!="object")return!1;const t=Object.keys(e),r=Object.keys(n);if(t.length!==r.length)return!1;for(const o of t)if(!r.includes(o)||!X(e[o],n[o]))return!1;return!0}function ge(e,n){if(!Array.isArray(e)||!Array.isArray(n)||e.length!==n.length)return!1;for(let t=0;t<e.length;t++)if(!X(e[t],n[t]))return!1;return!0}const ye=Array.isArray,we=Number.parseInt(P.REVISION.replace("dev","")),T={realistic:{shadows:!0,physicallyCorrectLights:!0,outputColorSpace:P.SRGBColorSpace,toneMapping:P.ACESFilmicToneMapping,toneMappingExposure:3,shadowMap:{enabled:!0,type:P.PCFSoftShadowMap}}};function Y({scene:e,canvas:n,options:t,disableRender:r,contextParts:{sizes:o,camera:a}}){const f=c.computed(()=>({alpha:C.toValue(t.alpha),depth:C.toValue(t.depth),canvas:C.unrefElement(n),context:C.toValue(t.context),stencil:C.toValue(t.stencil),antialias:C.toValue(t.antialias)===void 0?!0:C.toValue(t.antialias),precision:C.toValue(t.precision),powerPreference:C.toValue(t.powerPreference),premultipliedAlpha:C.toValue(t.premultipliedAlpha),preserveDrawingBuffer:C.toValue(t.preserveDrawingBuffer),logarithmicDepthBuffer:C.toValue(t.logarithmicDepthBuffer),failIfMajorPerformanceCaveat:C.toValue(t.failIfMajorPerformanceCaveat)})),s=c.shallowRef(new P.WebGLRenderer(f.value));c.watch(f,()=>{s.value.dispose(),s.value=new P.WebGLRenderer(f.value)}),c.watchEffect(()=>{s.value.setSize(o.width.value,o.height.value)});const{pixelRatio:p}=C.useDevicePixelRatio();c.watchEffect(()=>{s.value.setPixelRatio(p.value)});const{logError:i}=D(),l=(()=>{const g=new P.WebGLRenderer,_={shadowMap:{enabled:g.shadowMap.enabled,type:g.shadowMap.type},toneMapping:g.toneMapping,toneMappingExposure:g.toneMappingExposure,outputColorSpace:g.outputColorSpace};return g.dispose(),_})();c.watchEffect(()=>{const g=C.toValue(t.preset);g&&(g in T||i(`Renderer Preset must be one of these: ${Object.keys(T).join(", ")}`),K(s.value,T[g]));const _=(M,E)=>{const O=C.toValue(M),h=()=>{if(g)return I(T[g],E)};if(O!==void 0)return O;const w=h();return w!==void 0?w:I(l,E)},b=(M,E)=>de(s.value,E,_(M,E));b(t.shadows,"shadowMap.enabled"),b(t.toneMapping,"toneMapping"),b(t.shadowMapType,"shadowMap.type"),we<150&&b(!t.useLegacyLights,"physicallyCorrectLights"),b(t.outputColorSpace,"outputColorSpace"),b(t.toneMappingExposure,"toneMappingExposure");const A=_(t.clearColor,"clearColor");A&&s.value.setClearColor(A?J(A):new P.Color(0))});const{pause:u,resume:d,onLoop:v}=z();return v(()=>{a.value&&!C.toValue(r)&&s.value.render(e,a.value)}),d(),c.onUnmounted(()=>{u(),s.value.dispose(),s.value.forceContextLoss()}),{renderer:s}}const W=e=>typeof e=="function",Ce=e=>!!e&&e.constructor===Array;function Q(e){const n={nodes:{},materials:{}};return e&&e.traverse(t=>{t.name&&(n.nodes[t.name]=t),t.material&&!n.materials[t.material.name]&&(n.materials[t.material.name]=t.material)}),n}async function Pe(e,n,t,r,o){const{logError:a}=D(),f=new e;o&&o(f),t&&t(f);const p=(Array.isArray(n)?n:[n]).map(i=>new Promise((m,l)=>{f.load(i,u=>{u.scene&&Object.assign(u,Q(u.scene)),m(u)},r,u=>l(a("[useLoader] - Failed to load resource",u)))}));return Ce(n)?await Promise.all(p):await p[0]}async function _e(e){const n=new P.LoadingManager,t=new P.TextureLoader(n),r=o=>new Promise((a,f)=>{t.load(o,s=>a(s),()=>null,()=>{f(new Error("[useTextures] - Failed to load texture"))})});if(ye(e)){const o=await Promise.all(e.map(a=>r(a)));return e.length>1?o:o[0]}else{const{map:o,displacementMap:a,normalMap:f,roughnessMap:s,metalnessMap:p,aoMap:i,alphaMap:m,matcap:l}=e;return{map:o?await r(o):null,displacementMap:a?await r(a):null,normalMap:f?await r(f):null,roughnessMap:s?await r(s):null,metalnessMap:p?await r(p):null,aoMap:i?await r(i):null,alphaMap:m?await r(m):null,matcap:l?await r(l):null}}}const Z=(e,{renderer:n,camera:t,raycaster:r})=>{const o=c.computed(()=>n.value.domElement),{x:a,y:f}=C.usePointer({target:o}),{width:s,height:p,top:i,left:m}=C.useElementBounding(o),l=({x:w,y:k})=>{if(o.value)return{x:(w-m.value)/s.value*2-1,y:-((k-i.value)/p.value)*2+1}},u=({x:w,y:k})=>{if(t.value)return r.value.setFromCamera(new P.Vector2(w,k),t.value),r.value.intersectObjects(e.value,!1)},d=w=>{const k=l({x:(w==null?void 0:w.clientX)??a.value,y:(w==null?void 0:w.clientY)??f.value});return k?u(k)||[]:[]},v=c.computed(()=>d()),g=C.createEventHook(),_=C.createEventHook(),b=(w,k)=>{w.trigger({event:k,intersects:d(k)})},A=w=>{b(_,w)};let M;const E=w=>{var k;M=(k=d(w)[0])==null?void 0:k.object},O=w=>{var k;w instanceof PointerEvent&&M===((k=d(w)[0])==null?void 0:k.object)&&b(g,w)},h=w=>_.trigger({event:w,intersects:[]});return o.value.addEventListener("pointerup",O),o.value.addEventListener("pointerdown",E),o.value.addEventListener("pointermove",A),o.value.addEventListener("pointerleave",h),c.onUnmounted(()=>{o!=null&&o.value&&(o.value.removeEventListener("pointerup",O),o.value.removeEventListener("pointerdown",E),o.value.removeEventListener("pointermove",A),o.value.removeEventListener("pointerleave",h))}),{intersects:v,onClick:w=>g.on(w).off,onPointerMove:w=>_.on(w).off}};function Ee(){const{logWarning:e}=D();function n(r,o,a){let f=null;return r.traverse(s=>{s[o]===a&&(f=s)}),f||e(`Child with ${o} '${a}' not found.`),f}function t(r,o){return n(r,"name",o)}return{seek:n,seekByName:t}}const ee=({scene:e,contextParts:n})=>{const t=c.reactive({click:new Map,pointerMove:new Map,pointerEnter:new Map,pointerLeave:new Map}),r=c.ref(new Set),o=u=>{r.value.add(u)},a=u=>{r.value.delete(u)},f=u=>{Object.values(t).forEach(d=>d.delete(u)),a(u)},s=u=>{const{onClick:d,onPointerMove:v,onPointerEnter:g,onPointerLeave:_}=u;d&&t.click.set(u,d),v&&t.pointerMove.set(u,v),g&&t.pointerEnter.set(u,g),_&&t.pointerLeave.set(u,_)};e.userData.tres__registerAtPointerEventHandler=s,e.userData.tres__deregisterAtPointerEventHandler=f,e.userData.tres__registerBlockingObjectAtPointerEventHandler=o,e.userData.tres__deregisterBlockingObjectAtPointerEventHandler=a;const p=c.computed(()=>ve([...Array.from(r.value),...Object.values(t).map(u=>Array.from(u.keys())).flat()],({uuid:u})=>u)),{onClick:i,onPointerMove:m}=Z(p,n);i(({intersects:u,event:d})=>{var v;u.length&&((v=t.click.get(u[0].object))==null||v(u[0],d))});let l;return m(({intersects:u,event:d})=>{var A,M,E,O;const v=(A=u==null?void 0:u[0])==null?void 0:A.object,{pointerLeave:g,pointerEnter:_,pointerMove:b}=t;l&&l!==v&&((M=g.get(l))==null||M(l,d)),v&&(l!==v&&((E=_.get(v))==null||E(u[0],d)),(O=b.get(v))==null||O(u[0],d)),l=v||null}),{registerObject:s,deregisterObject:f}},R=c.ref({}),j=e=>Object.assign(R.value,e);function te({scene:e,canvas:n,windowSize:t,disableRender:r,rendererOptions:o}){const a=c.computed(()=>C.toValue(t)?C.useWindowSize():C.useElementSize(C.toValue(n).parentElement)),f=c.computed(()=>a.value.width.value),s=c.computed(()=>a.value.height.value),p=c.computed(()=>f.value/s.value),i={height:s,width:f,aspectRatio:p},m=c.shallowRef(e),{camera:l,cameras:u,registerCamera:d,deregisterCamera:v,setCameraActive:g}=N({sizes:i,scene:e}),{renderer:_}=Y({scene:e,canvas:n,options:o,contextParts:{sizes:i,camera:l},disableRender:r}),b={sizes:i,scene:m,camera:l,cameras:c.readonly(u),renderer:_,raycaster:c.shallowRef(new P.Raycaster),controls:c.ref(null),extend:j,registerCamera:d,setCameraActive:g,deregisterCamera:v};return c.provide("useTres",b),b}function re(){const e=c.inject("useTres");if(!e)throw new Error("useTresContext must be used together with useTresContextProvider");return e}const Me=re;let H=null,y=null;const{logError:$}=D(),be={createElement(e,n,t,r){var f,s;if(r||(r={}),r.args||(r.args=[]),e==="template"||pe(e))return null;let o=e.replace("Tres",""),a;if(e==="primitive"){(r==null?void 0:r.object)===void 0&&$("Tres primitives need a prop 'object'");const p=r.object;o=p.type,a=Object.assign(p,{type:o,attach:r.attach,primitive:!0})}else{const p=R.value[o];p||$(`${o} is not defined on the THREE namespace. Use extend to add it to the catalog.`),a=new p(...r.args)}return a.isCamera&&(r!=null&&r.position||a.position.set(3,3,3),r!=null&&r.lookAt||a.lookAt(0,0,0)),(r==null?void 0:r.attach)===void 0&&(a.isMaterial?a.attach="material":a.isBufferGeometry&&(a.attach="geometry")),a.isObject3D&&((f=r==null?void 0:r.material)!=null&&f.isMaterial&&(a.userData.tres__materialViaProp=!0),(s=r==null?void 0:r.geometry)!=null&&s.isBufferGeometry&&(a.userData.tres__geometryViaProp=!0)),a.userData={...a.userData,tres__name:o},a},insert(e,n){var t,r,o,a,f,s,p,i,m,l;if(n&&n.isScene&&(y=n),(((t=e==null?void 0:e.__vnode)==null?void 0:t.type)==="TresGroup"||((r=e==null?void 0:e.__vnode)==null?void 0:r.type)==="TresObject3D")&&n===null&&!((a=(o=e==null?void 0:e.__vnode)==null?void 0:o.ctx)!=null&&a.asyncResolved)){H=e;return}else n===null&&((f=e==null?void 0:e.__vnode)!=null&&f.type.includes("Controls")||(s=e==null?void 0:e.__vnode)!=null&&s.type.includes("Helper"))&&(H=y);if(n||(n=H),e!=null&&e.isObject3D){if(e!=null&&e.isCamera){if(!(y!=null&&y.userData.tres__registerCamera))throw"could not find tres__registerCamera on scene's userData";(i=y==null?void 0:(p=y.userData).tres__registerCamera)==null||i.call(p,e)}if(e!=null&&e.onClick||e!=null&&e.onPointerMove||e!=null&&e.onPointerEnter||e!=null&&e.onPointerLeave){if(!(y!=null&&y.userData.tres__registerAtPointerEventHandler))throw"could not find tres__registerAtPointerEventHandler on scene's userData";(l=y==null?void 0:(m=y.userData).tres__registerAtPointerEventHandler)==null||l.call(m,e)}}e!=null&&e.isObject3D&&(n!=null&&n.isObject3D)?(n.add(e),e.dispatchEvent({type:"added"})):e!=null&&e.isFog?n.fog=e:typeof(e==null?void 0:e.attach)=="string"&&(e.__previousAttach=e[n==null?void 0:n.attach],n&&(n[e.attach]=e))},remove(e){var n,t;if(e){if(e.isObject3D){const r=e,o=i=>{var l,u;const m=i;i.userData.tres__materialViaProp||(l=m.material)==null||l.dispose(),i.userData.tres__geometryViaProp||(u=m.geometry)==null||u.dispose()},a=y==null?void 0:y.userData.tres__deregisterAtPointerEventHandler,f=y==null?void 0:y.userData.tres__deregisterBlockingObjectAtPointerEventHandler,s=i=>{var m,l;if(!f)throw"could not find tres__deregisterBlockingObjectAtPointerEventHandler on scene's userData";if((l=y==null?void 0:(m=y.userData).tres__deregisterBlockingObjectAtPointerEventHandler)==null||l.call(m,i),!a)throw"could not find tres__deregisterAtPointerEventHandler on scene's userData";(i!=null&&i.onClick||i!=null&&i.onPointerMove||i!=null&&i.onPointerEnter||i!=null&&i.onPointerLeave)&&(a==null||a(i))},p=i=>{const m=y==null?void 0:y.userData.tres__deregisterCamera;if(!m)throw"could not find tres__deregisterCamera on scene's userData";i.isCamera&&(m==null||m(i))};r.traverse(i=>{o(i),p(i),s==null||s(i)}),o(r),p(r),s==null||s(r)}(n=e.removeFromParent)==null||n.call(e),(t=e.dispose)==null||t.call(e)}},patchProp(e,n,t,r){var o,a,f,s;if(e){let p=e,i=n;if(e.isObject3D&&i==="blocks-pointer-events"){r||r===""?(a=y==null?void 0:(o=y.userData).tres__registerBlockingObjectAtPointerEventHandler)==null||a.call(o,e):(s=y==null?void 0:(f=y.userData).tres__deregisterBlockingObjectAtPointerEventHandler)==null||s.call(f,e);return}let m=L(i),l=p==null?void 0:p[m];if(i==="args"){const d=e,v=t??[],g=r??[],_=e.userData.tres__name||e.type;_&&v.length&&!ge(v,g)&&(p=Object.assign(d,new R.value[_](...r)));return}if(p.type==="BufferGeometry"){if(i==="args")return;p.setAttribute(L(i),new P.BufferAttribute(...r));return}if(i.includes("-")&&l===void 0){const d=i.split("-");l=d.reduce((v,g)=>v[L(g)],p),i=d.pop(),m=i.toLowerCase(),l!=null&&l.set||(p=d.reduce((v,g)=>v[L(g)],p))}let u=r;if(u===""&&(u=!0),W(l)){Array.isArray(u)?e[m](...u):e[m](u);return}!(l!=null&&l.set)&&!W(l)?p[m]=u:l.constructor===u.constructor&&(l!=null&&l.copy)?l==null||l.copy(u):Array.isArray(u)?l.set(...u):!l.isColor&&l.setScalar?l.setScalar(u):l.set(u)}},parentNode(e){return(e==null?void 0:e.parent)||null},createText:()=>void 0,createComment:()=>void 0,setText:()=>void 0,setElementText:()=>void 0,nextSibling:()=>void 0,querySelector:()=>void 0,setScopeId:()=>void 0,cloneNode:()=>void 0,insertStaticContent:()=>void 0},{render:ke}=c.createRenderer(be);j(ae);const Ae=["data-scene"],ne=c.defineComponent({__name:"TresCanvas",props:{shadows:{type:Boolean,default:void 0},clearColor:{},toneMapping:{},shadowMapType:{},useLegacyLights:{type:Boolean,default:void 0},outputColorSpace:{},toneMappingExposure:{},camera:{},preset:{},windowSize:{type:Boolean,default:void 0},disableRender:{type:Boolean,default:void 0},context:{},precision:{},alpha:{type:Boolean,default:void 0},premultipliedAlpha:{type:Boolean},antialias:{type:Boolean,default:void 0},stencil:{type:Boolean,default:void 0},preserveDrawingBuffer:{type:Boolean,default:void 0},powerPreference:{},depth:{type:Boolean,default:void 0},logarithmicDepthBuffer:{type:Boolean,default:void 0},failIfMajorPerformanceCaveat:{type:Boolean,default:void 0}},setup(e,{expose:n}){var u;const t=e,{logWarning:r}=D(),o=c.ref(),a=c.shallowRef(new P.Scene);z();const f=c.useSlots(),s=(u=c.getCurrentInstance())==null?void 0:u.appContext.app,p=d=>c.defineComponent({setup(){var g;const v=(g=c.getCurrentInstance())==null?void 0:g.appContext;return v&&(v.app=s),c.provide("useTres",d),c.provide("extend",j),()=>c.h(c.Fragment,null,f!=null&&f.default?f.default():[])}}),i=d=>{const v=p(d);ke(c.h(v),a.value)},m=c.computed(()=>t.disableRender),l=c.shallowRef(null);return n({context:l}),c.onMounted(()=>{const d=o;l.value=te({scene:a.value,canvas:d,windowSize:t.windowSize,disableRender:m,rendererOptions:t}),ee({scene:a.value,contextParts:l.value});const{registerCamera:v,camera:g,cameras:_,deregisterCamera:b}=l.value;i(l.value);const A=()=>{const M=new P.PerspectiveCamera(45,window.innerWidth/window.innerHeight,.1,1e3);M.position.set(3,3,3),M.lookAt(0,0,0),v(M);const E=c.watchEffect(()=>{_.value.length>=2&&(M.removeFromParent(),b(M),E==null||E())})};c.watch(()=>t.camera,(M,E)=>{M&&v(M),E&&(E.removeFromParent(),b(E))},{immediate:!0}),g.value||(r("No camera found. Creating a default perspective camera. To have full control over a camera, please add one to the scene."),A())}),(d,v)=>(c.openBlock(),c.createElementBlock("canvas",{ref_key:"canvas",ref:o,"data-scene":a.value.uuid,style:c.normalizeStyle({display:"block",width:"100%",height:"100%",position:d.windowSize?"fixed":"relative",top:0,left:0,pointerEvents:"auto",touchAction:"none"})},null,12,Ae))}}),Oe=["TresCanvas","TresLeches","TresScene"],De={template:{compilerOptions:{isCustomElement:e=>e.startsWith("Tres")&&!Oe.includes(e)||e==="primitive"}}},xe=De,he={install(e){e.component("TresCanvas",ne)}};exports.TresCanvas=ne;exports.catalogue=R;exports.default=he;exports.extend=j;exports.isProd=le;exports.normalizeColor=J;exports.normalizeVectorFlexibleParam=ce;exports.templateCompilerOptions=xe;exports.trasverseObjects=Q;exports.useCamera=N;exports.useLoader=Pe;exports.useLogger=D;exports.usePointerEventHandler=ee;exports.useRaycaster=Z;exports.useRenderLoop=z;exports.useRenderer=Y;exports.useSeek=Ee;exports.useTexture=_e;exports.useTres=Me;exports.useTresContext=re;exports.useTresContextProvider=te;