string-tune-3d 0.0.2 → 0.0.4
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/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +32 -4
- package/dist/index.d.ts +32 -4
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -1
- package/readme.md +48 -19
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var P=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var Z=(c,e)=>{for(var t in e)P(c,t,{get:e[t],enumerable:!0})},Q=(c,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of W(e))!A.call(c,i)&&i!==t&&P(c,i,{get:()=>e[i],enumerable:!(r=G(e,i))||r.enumerable});return c};var X=c=>Q(P({},"__esModule",{value:!0}),c);var Y={};Z(Y,{String3D:()=>C,String3DCamera:()=>D,String3DObject:()=>h,String3DRenderer:()=>S,String3DScene:()=>f,String3DSynchronizer:()=>I,ThreeJSEngine:()=>x,ThreeJSProvider:()=>T});module.exports=X(Y);var z=require("@fiddle-digital/string-tune");var D=class{constructor(e,t="orthographic",r=50,i=.1,n=1e4){this.scaleCache=new Map;this._width=1;this._height=1;this.engine=e,this.mode=t,this.perspectiveFov=r,t==="orthographic"?this._camera=e.createOrthographicCamera(-1,1,1,-1,i,n):this._camera=e.createPerspectiveCamera(r,1,i,n),this._position=e.createVector3(0,0,1e3),this.update()}get camera(){return this._camera}resize(e,t){if(this._width=e,this._height=t,this.mode==="orthographic"){let r=this._camera;r.left=-e/2,r.right=e/2,r.top=t/2,r.bottom=-t/2}else this._camera.aspect=e/t;this.update()}setPosition(e,t,r){this._position.set(e,t,r),this._camera.position.copy(this._position),this.update()}lookAt(e,t,r){this._camera.lookAt(e,t,r),this.update()}update(){this._camera.updateProjectionMatrix(),this._camera.updateMatrixWorld?.()}screenToWorld(e,t,r=0){if(this.mode==="orthographic"){let i=e-this._width/2,n=-(t-this._height/2);return this.engine.createVector3(i,n,r)}else{let{width:i,height:n}=this.getFrustumSizeAt(r),a=e/this._width,o=t/this._height,s=(a-.5)*i,l=-(o-.5)*n;return this.engine.createVector3(s,l,r)}}getFrustumSizeAt(e){if(this.mode==="orthographic")return{width:this._width,height:this._height};let t=this.engine.degToRad(this.perspectiveFov),r=Math.abs(e-this._camera.position.z),i=2*Math.tan(t/2)*r;return{width:i*this._camera.aspect,height:i}}getScaleAtZ(e,t){if(this.mode==="orthographic")return 1;let r=Math.round(e*1e3)/1e3;if(this.scaleCache.has(r))return this.scaleCache.get(r);let{height:i}=this.getFrustumSizeAt(e),n=i/t;return this.scaleCache.set(r,n),n}clearScaleCache(){this.scaleCache.clear()}getMode(){return this.mode}};var S=class{constructor(e,t){this.engine=t,this._container=e;let{width:r,height:i}=e.getBoundingClientRect();this._width=r,this._height=i,this._renderer=t.createRenderer({antialias:!0,alpha:!0,logarithmicDepthBuffer:!0}),this._renderer.setPixelRatio(window.devicePixelRatio),this._renderer.setSize(r,i)}attach(){this._container.appendChild(this._renderer.domElement)}render(e,t){this._renderer.render(e.getScene(),t.camera)}resize(e){let{width:t,height:r}=this._container.getBoundingClientRect();this._width=t,this._height=r,this._renderer.setSize(t,r),e.resize(t,r)}get width(){return this._width}get height(){return this._height}get renderer(){return this._renderer}destroy(){this._renderer.dispose()}};var h=class{constructor(e,t,r,i){this._uniforms={};this._children=[];this.id=e,this.type=t,this._object=r,this.engine=i,this._quaternion=i.createQuaternion(),this._originalSize=i.createVector3(),this._bbox=i.createBox3(),this.updateBoundingBox()}get children(){return this._children}get object(){return this._object}get material(){return this._material}get originalSize(){return this._originalSize.clone()}get boundingBox(){return this._bbox.clone()}addChild(e){this._children.push(e),this.object.add(e.object)}getWorldMatrix(){return this._object.matrixWorld.clone()}getWorldPosition(){return this.engine.createVector3().setFromMatrixPosition(this._object.matrixWorld)}getOriginalBoundingBox(){if(!this._originalBoundingBox){let e=this.object.scale.clone();this.object.scale.set(1,1,1),this.object.updateMatrixWorld(!0),this._originalBoundingBox=this.engine.computeBoundingBoxRecursively(this.object),this.object.scale.copy(e),this.object.updateMatrixWorld(!0)}return this._originalBoundingBox.clone()}syncTransformFromMatrix(e){let t=this.engine.createVector3(),r=this.engine.createQuaternion(),i=this.engine.createVector3();e.decompose(t,r,i),this._object.position.copy(t),this._object.quaternion.copy(r),this._object.scale.copy(i),this._object.updateMatrix(),this._object.updateMatrixWorld()}applyWorldTransform(e,t,r){this._object.position.copy(e),this._object.quaternion.copy(t),this._object.scale.copy(r),this._object.updateMatrix(),this._object.updateMatrixWorld()}set quaternion(e){this._quaternion.copy(e),this._object.quaternion.copy(this._quaternion),this._object.updateMatrixWorld()}set position(e){this._object.position.copy(e)}set scale(e){this._object.scale.copy(e)}set rotation(e){this._object.rotation.copy(e)}set opacity(e){let t=this._object;t.material&&"opacity"in t.material&&(t.material.opacity=e)}set metalness(e){let t=this._object;t.material&&"metalness"in t.material&&(t.material.metalness=e)}set roughness(e){let t=this._object;t.material&&"roughness"in t.material&&(t.material.roughness=e)}set texture(e){this._texture=e,this._object.isMesh&&e?.applyTexture&&e.applyTexture(this._object)}updateBoundingBox(){this._bbox.setFromObject(this._object),this._bbox.getSize(this._originalSize)}destroy(){this._texture?.dispose?.(),this._material?.dispose(),this._geometry?.dispose()}};var f=class{constructor(e,t){this._objects=new Map;this._rootObjects=[];this._elementMap=new Map;this.engine=e,this._modelLoader=t,this._scene=e.createScene()}get rootObjects(){return this._rootObjects}getScene(){return this._scene}getObject(e){return this._objects.get(e)}hasObject(e){return this._objects.has(e)}deleteObject(e){let t=this._objects.get(e);return t?(this._scene.remove(t.object),this._objects.delete(e),t.destroy(),!0):!1}createFromElement(e){let t=e.getProperty("3d");if(!t)return;let r=e.htmlElement;if(!r)return;let i=n=>{if(n){let a=e.getProperty("parentId");a==null?(this._scene.add(n.object),this._rootObjects.push(n)):this._objects.get(a)?.addChild(n),this._objects.set(e.id,n),this._elementMap.set(e.id,r),n.el=r}};switch(t){case"group":this.createGroup(e,i);break;case"pointLight":this.createLight(e,"point",i);break;case"ambientLight":this.createLight(e,"ambient",i);break;case"directionalLight":this.createLight(e,"directional",i);break;case"model":this.createModel(e,i);break;case"box":this.createBox(e,i);break;case"sphere":this.createSphere(e,i);break;case"plane":this.createPlane(e,i);break;case"cylinder":this.createCylinder(e,i);break}}createGroup(e,t){let r=this.engine.createGroup(),i=new h(e.id,"group",r,this.engine);return t(i),i}createLight(e,t,r){let i=e.getProperty("3d-color")||"#ffffff",n=e.getProperty("3d-intensity")??1,a;if(t==="point"){let s=e.getProperty("3d-distance")??1e3,l=e.getProperty("3d-decay")??0;a=this.engine.createPointLight(i,n,s,l)}else t==="directional"?a=this.engine.createDirectionalLight(i,n):a=this.engine.createAmbientLight(i,n);let o=new h(e.id,t+"Light",a,this.engine);return r(o),o}createBox(e,t){let r=this.engine.createBoxGeometry(1,1,1),i=this.createMaterialFromObject(e),n=this.engine.createMesh(r,i),a=new h(e.id,"box",n,this.engine);return t(a),a}createSphere(e,t){let r=e.getProperty("3d-segments-width")??32,i=e.getProperty("3d-segments-height")??32,n=this.engine.createSphereGeometry(.5,r,i),a=this.createMaterialFromObject(e),o=this.engine.createMesh(n,a),s=new h(e.id,"sphere",o,this.engine);return t(s),s}createPlane(e,t){let r=this.engine.createPlaneGeometry(1,1),i=this.createMaterialFromObject(e),n=this.engine.createMesh(r,i),a=new h(e.id,"plane",n,this.engine);return t(a),a}createCylinder(e,t){let r=e.getProperty("3d-segments")??32,i=this.engine.createCylinderGeometry(.5,.5,1,r),n=this.createMaterialFromObject(e),a=this.engine.createMesh(i,n),o=new h(e.id,"cylinder",a,this.engine);return t(o),o}createModel(e,t){if(!this._modelLoader){console.warn("[String3D] Model loader not configured");return}let r=e.getProperty("3d-model");if(!r)return;let i=this.createMaterialFromObject(e);this._modelLoader.load(r,a=>{let o=a.scene;o.traverse(l=>{l.isMesh&&(l.material=i)});let s=new h(e.id,"model",o,this.engine);t(s)},a=>{console.log(a.loaded/a.total*100+"% loaded")},a=>{console.error("[String3D] Model loading error:",a)})}createMaterialFromObject(e){let t=e.getProperty("3d-material")||"basic[#ffffff]",[r,i]=t.split(/\[|\]/),n=i||"#ffffff",a=e.getProperty("3d-opacity")??1,o={color:n,transparent:a<1,opacity:a},s=e.el,l=s?.getAttribute("string-3d-map"),d=s?.getAttribute("string-3d-normalMap"),g=s?.getAttribute("string-3d-roughnessMap"),y=s?.getAttribute("string-3d-aoMap");return r==="standard"?(l&&(o.map=this.loadTexture(l)),d&&(o.normalMap=this.loadTexture(d)),g&&(o.roughnessMap=this.loadTexture(g)),y&&(o.aoMap=this.loadTexture(y)),this.engine.createMeshStandardMaterial(o)):this.engine.createMeshBasicMaterial(o)}loadTexture(e){return this.engine.createTextureLoader().load(e)}destroy(){this._objects.forEach(e=>e.destroy()),this._objects.clear(),this._rootObjects=[]}};var O=class{sync(e,t,r,i){let n=e.getBoundingClientRect(),a=n.left+n.width/2,o=n.top+n.height/2,s=getComputedStyle(e),l=parseFloat(s.getPropertyValue("--translate-z")||"0"),d=r.camera.screenToWorld(a,o,l);t.position=d;let g=parseFloat(s.getPropertyValue("--scale"))||1;t.scale=r.engine.createVector3(g,g,g);let y=-r.engine.degToRad(parseFloat(s.getPropertyValue("--rotate-x")||"0")),R=r.engine.degToRad(parseFloat(s.getPropertyValue("--rotate-y")||"0")),L=-r.engine.degToRad(parseFloat(s.getPropertyValue("--rotate-z")||"0"));return t.rotation=r.engine.createEuler(y,R,L,"XYZ"),t.object.updateMatrixWorld(!0),{scale:g}}};var v=class{sync(e,t,r,i){let n=e.getBoundingClientRect(),a=n.left+n.width/2,o=n.top+n.height/2,s=parseFloat(getComputedStyle(e).getPropertyValue("--translate-z")||"0"),l=r.camera.screenToWorld(a,o,s);return t.position=l,null}};var u=class{sync(e,t,r,i){let n=getComputedStyle(e),a=e.offsetWidth,o=e.offsetHeight,s=e.getBoundingClientRect(),l=parseFloat(n.getPropertyValue("--translate-z")||"0"),d=parseFloat(n.getPropertyValue("--scale")||"1"),g=s.left+s.width/2,y=s.top+s.height/2,R=r.camera.screenToWorld(g,y,l);t.position=R;let L=-r.engine.degToRad(parseFloat(n.getPropertyValue("--rotate-x")||"0")),V=r.engine.degToRad(parseFloat(n.getPropertyValue("--rotate-y")||"0")),k=-r.engine.degToRad(parseFloat(n.getPropertyValue("--rotate-z")||"0"));t.rotation=r.engine.createEuler(L,V,k,"XYZ");let E=a*d,M=o*d,B=parseFloat(n.getPropertyValue("--scale-z")||"1"),p=i?.scale||1,F=t.type,_,j,w;switch(F){case"box":case"sphere":{let b=Math.min(E,M);_=b*p,j=b*p,w=b*B*p;break}case"cylinder":{let b=E;_=b*p,j=M*p,w=b*B*p;break}case"plane":default:_=E*p,j=M*p,w=Math.min(E,M)*.5*B*p;break}return t.scale=r.engine.createVector3(_,j,w),{scale:d*p}}};var I=class{constructor(e,t,r,i){this.camera=e;this.viewportWidth=t;this.viewportHeight=r;this.engine=i;this.strategies=new Map;this.strategies.set("box",new u),this.strategies.set("sphere",new u),this.strategies.set("plane",new u),this.strategies.set("cylinder",new u),this.strategies.set("model",new u),this.strategies.set("group",new O),this.strategies.set("pointLight",new v),this.strategies.set("ambientLight",new v),this.strategies.set("directionalLight",new v)}syncElement(e,t,r){let i=this.strategies.get(t.type);return i?i.sync(e,t,{camera:this.camera,viewportWidth:this.viewportWidth,viewportHeight:this.viewportHeight,engine:this.engine},r):(console.warn(`[String3D Sync] No strategy for type "${t.type}"`),null)}updateViewportSize(e,t){this.viewportWidth=e,this.viewportHeight=t}};var H=require("@fiddle-digital/string-tune"),m=class m extends z.StringModule{constructor(t,r={}){super(t);this.renderer=null;this.camera=null;this.scene=null;this.synchronizer=null;this.engine=null;this.canvasContainer=null;this.isLoading=new Map;this.htmlKey="3d",this.options={hideHTML:r.hideHTML??!1,container:r.container,zIndex:r.zIndex??1},this.attributesToMap=[...this.attributesToMap,{key:"3d",type:"string",fallback:"box"},{key:"3d-material",type:"string",fallback:"basic[#ffffff]"},{key:"3d-color",type:"string",fallback:"#ffffff"},{key:"3d-opacity",type:"number",fallback:1},{key:"3d-intensity",type:"number",fallback:1},{key:"3d-distance",type:"number",fallback:1e3},{key:"3d-decay",type:"number",fallback:0},{key:"3d-model",type:"string",fallback:""},{key:"3d-segments",type:"number",fallback:32},{key:"3d-segments-width",type:"number",fallback:32},{key:"3d-segments-height",type:"number",fallback:32}]}static setProvider(t){m.provider=t}canConnect(t){let r=super.canConnect(t);return console.log("[String3D] canConnect:",t.id,"keys:",t.keys,"htmlKey:",this.htmlKey,"result:",r),r}initializeObject(t,r,i,n){super.initializeObject(t,r,i,n),r.setProperty("parentId",null);let a=i.parentElement?.closest('[string-3d="group"]');if(a){let o=a.getAttribute("string-id");o&&(r.setProperty("parentId",o),r.setProperty("parent",a))}}onResize(){this.renderer&&this.camera&&this.synchronizer&&(this.renderer.resize(this.camera),this.synchronizer.updateViewportSize(this.renderer.width,this.renderer.height),this.camera.clearScaleCache())}onInit(){if(!m.provider){console.error("[String3D] No provider set. Call String3D.setProvider() before use.");return}this.engine=m.provider.getEngine(),this.canvasContainer=this.createOrGetContainer(),this.injectCSS(),this.renderer=new S(this.canvasContainer,this.engine),this.renderer.attach(),this.camera=new D(this.engine,"orthographic"),this.camera.setPosition(0,0,1e3),this.camera.resize(this.renderer.width,this.renderer.height),this.scene=new f(this.engine),this.scene.getScene().add(this.camera.camera),this.synchronizer=new I(this.camera,this.renderer.width,this.renderer.height,this.engine),console.info(`[String3D] Initialized with: ${m.provider.getName()}`)}createOrGetContainer(){if(this.options.container instanceof HTMLElement)return this.applyContainerStyles(this.options.container),this.options.container;if(typeof this.options.container=="string"){let r=document.getElementById(this.options.container);if(r)return this.applyContainerStyles(r),r}let t=document.createElement("div");return t.id="string-3d-canvas",this.applyContainerStyles(t),document.body.insertBefore(t,document.body.firstChild),t}applyContainerStyles(t){Object.assign(t.style,{position:"fixed",left:"0",top:"0",width:"100vw",height:"100lvh",zIndex:String(this.options.zIndex),pointerEvents:"none"})}onObjectConnected(t){this.isLoading.has(t.id)||!this.scene||(this.isLoading.set(t.id,!0),this.scene.createFromElement(t),this.options.hideHTML&&t.htmlElement&&(t.htmlElement.style.opacity="0",t.htmlElement.style.pointerEvents="none"))}onFrame(t){!this.renderer||!this.scene||!this.camera||!this.synchronizer||(H.frameDOM.measure(()=>{this.scene.rootObjects.forEach(r=>{this.syncRecursive(r.el,r,{scale:1})})}),H.frameDOM.mutate(()=>{this.renderer.render(this.scene,this.camera)}))}syncRecursive(t,r,i){if(!this.synchronizer||!t)return;let n=this.synchronizer.syncElement(t,r,i);r.children.forEach(a=>this.syncRecursive(a.el,a,n))}injectCSS(){if(document.getElementById("string-3d-styles"))return;let t=document.createElement("style");t.id="string-3d-styles",t.textContent=`
|
|
1
|
+
"use strict";var G=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var U=Object.prototype.hasOwnProperty;var $=(l,e)=>{for(var t in e)G(l,t,{get:e[t],enumerable:!0})},J=(l,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of N(e))!U.call(l,i)&&i!==t&&G(l,i,{get:()=>e[i],enumerable:!(r=q(e,i))||r.enumerable});return l};var K=l=>J(G({},"__esModule",{value:!0}),l);var ee={};$(ee,{String3D:()=>F,String3DCamera:()=>O,String3DObject:()=>g,String3DRenderer:()=>w,String3DScene:()=>T,String3DSynchronizer:()=>j,ThreeJSEngine:()=>P,ThreeJSProvider:()=>V});module.exports=K(ee);var Z=require("@fiddle-digital/string-tune");var O=class{constructor(e,t="orthographic",r=50,i=.1,n=1e4){this.scaleCache=new Map;this._width=1;this._height=1;this.engine=e,this.mode=t,this.perspectiveFov=r,t==="orthographic"?this._camera=e.createOrthographicCamera(-1,1,1,-1,i,n):this._camera=e.createPerspectiveCamera(r,1,i,n),this._position=e.createVector3(0,0,1e3),this.update()}get camera(){return this._camera}resize(e,t){if(this._width=e,this._height=t,this.mode==="orthographic"){let r=this._camera;r.left=-e/2,r.right=e/2,r.top=t/2,r.bottom=-t/2}else this._camera.aspect=e/t;this.update()}setPosition(e,t,r){this._position.set(e,t,r),this._camera.position.copy(this._position),this.update()}lookAt(e,t,r){this._camera.lookAt(e,t,r),this.update()}update(){this._camera.updateProjectionMatrix(),this._camera.updateMatrixWorld?.()}screenToWorld(e,t,r=0){if(this.mode==="orthographic"){let i=e-this._width/2,n=-(t-this._height/2);return this.engine.createVector3(i,n,r)}else{let{width:i,height:n}=this.getFrustumSizeAt(r),o=e/this._width,s=t/this._height,a=(o-.5)*i,c=-(s-.5)*n;return this.engine.createVector3(a,c,r)}}getFrustumSizeAt(e){if(this.mode==="orthographic")return{width:this._width,height:this._height};let t=this.engine.degToRad(this.perspectiveFov),r=Math.abs(e-this._camera.position.z),i=2*Math.tan(t/2)*r;return{width:i*this._camera.aspect,height:i}}getScaleAtZ(e,t){if(this.mode==="orthographic")return 1;let r=Math.round(e*1e3)/1e3;if(this.scaleCache.has(r))return this.scaleCache.get(r);let{height:i}=this.getFrustumSizeAt(e),n=i/t;return this.scaleCache.set(r,n),n}clearScaleCache(){this.scaleCache.clear()}getMode(){return this.mode}};var w=class{constructor(e,t){this.engine=t,this._container=e;let{width:r,height:i}=e.getBoundingClientRect();this._width=r,this._height=i,this._renderer=t.createRenderer({antialias:!0,alpha:!0,logarithmicDepthBuffer:!0}),this._renderer.setPixelRatio(window.devicePixelRatio),this._renderer.setSize(r,i)}attach(){this._container.appendChild(this._renderer.domElement)}render(e,t){this._renderer.render(e.getScene(),t.camera)}resize(e){let{width:t,height:r}=this._container.getBoundingClientRect();this._width=t,this._height=r,this._renderer.setSize(t,r),e.resize(t,r)}get width(){return this._width}get height(){return this._height}get renderer(){return this._renderer}destroy(){this._renderer.dispose()}};var g=class{constructor(e,t,r,i,n={}){this._uniforms={};this._children=[];this.id=e,this.type=t,this._object=r,this.engine=i,this._material=n.material,this._geometry=n.geometry,this._texture=n.texture,this._quaternion=i.createQuaternion(),this._originalSize=i.createVector3(),this._bbox=i.createBox3(),this.updateBoundingBox()}get children(){return this._children}get object(){return this._object}get material(){return this._material}get originalSize(){return this._originalSize.clone()}get boundingBox(){return this._bbox.clone()}addChild(e){this._children.push(e),this.object.add(e.object)}getWorldMatrix(){return this._object.matrixWorld.clone()}getWorldPosition(){return this.engine.createVector3().setFromMatrixPosition(this._object.matrixWorld)}getOriginalBoundingBox(){if(!this._originalBoundingBox){let e=this.object.scale.clone();this.object.scale.set(1,1,1),this.object.updateMatrixWorld(!0),this._originalBoundingBox=this.engine.computeBoundingBoxRecursively(this.object),this.object.scale.copy(e),this.object.updateMatrixWorld(!0)}return this._originalBoundingBox.clone()}syncTransformFromMatrix(e){let t=this.engine.createVector3(),r=this.engine.createQuaternion(),i=this.engine.createVector3();e.decompose(t,r,i),this._object.position.copy(t),this._object.quaternion.copy(r),this._object.scale.copy(i),this._object.updateMatrix(),this._object.updateMatrixWorld()}applyWorldTransform(e,t,r){this._object.position.copy(e),this._object.quaternion.copy(t),this._object.scale.copy(r),this._object.updateMatrix(),this._object.updateMatrixWorld()}set quaternion(e){this._quaternion.copy(e),this._object.quaternion.copy(this._quaternion),this._object.updateMatrixWorld()}set position(e){this._object.position.copy(e)}set scale(e){this._object.scale.copy(e)}set rotation(e){this._object.rotation.copy(e)}set opacity(e){let t=this._object;t.material&&"opacity"in t.material&&(t.material.opacity=e)}set metalness(e){let t=this._object;t.material&&"metalness"in t.material&&(t.material.metalness=e)}set roughness(e){let t=this._object;t.material&&"roughness"in t.material&&(t.material.roughness=e)}set texture(e){this._texture=e,this._object.isMesh&&e?.applyTexture&&e.applyTexture(this._object)}set material(e){this._material=e}set geometry(e){this._geometry=e}updateBoundingBox(){this._bbox.setFromObject(this._object),this._bbox.getSize(this._originalSize)}destroy(){this.disposeObjectResources(this._object),this._texture?.dispose?.(),this._material?.dispose(),this._geometry?.dispose()}disposeObjectResources(e){let t=e;t?.geometry?.dispose&&t.geometry.dispose();let r=t?.material;Array.isArray(r)?r.forEach(i=>i?.dispose?.()):r?.dispose&&r.dispose(),typeof t?.traverse=="function"&&t.traverse(i=>{i?.geometry?.dispose&&i.geometry.dispose();let n=i?.material;Array.isArray(n)?n.forEach(o=>o?.dispose?.()):n?.dispose&&n.dispose()})}};var T=class{constructor(e,t={}){this._objects=new Map;this._rootObjects=[];this._elementMap=new Map;this._modelLoaderCache=new Map;this.engine=e,this._modelLoader=t.modelLoader,this._modelLoaderFactory=t.modelLoaderFactory,this._scene=e.createScene()}get rootObjects(){return this._rootObjects}getScene(){return this._scene}getObject(e){return this._objects.get(e)}hasObject(e){return this._objects.has(e)}deleteObject(e){let t=this._objects.get(e);return t?(this._scene.remove(t.object),this._objects.delete(e),t.destroy(),!0):!1}createFromElement(e){let t=e.getProperty("3d");if(!t)return;let r=e.htmlElement;if(!r)return;let i=n=>{if(n){let o=e.getProperty("parentId");o==null?(this._scene.add(n.object),this._rootObjects.push(n)):this._objects.get(o)?.addChild(n),this._objects.set(e.id,n),this._elementMap.set(e.id,r),n.el=r}};switch(t){case"group":this.createGroup(e,i);break;case"pointLight":this.createLight(e,"point",i);break;case"ambientLight":this.createLight(e,"ambient",i);break;case"directionalLight":this.createLight(e,"directional",i);break;case"model":this.createModel(e,i);break;case"box":this.createBox(e,i);break;case"sphere":this.createSphere(e,i);break;case"plane":this.createPlane(e,i);break;case"cylinder":this.createCylinder(e,i);break}}createGroup(e,t){let r=this.engine.createGroup(),i=new g(e.id,"group",r,this.engine);return t(i),i}createLight(e,t,r){let i=e.getProperty("3d-color")||"#ffffff",n=e.getProperty("3d-intensity")??1,o;if(t==="point"){let a=e.getProperty("3d-distance")??1e3,c=e.getProperty("3d-decay")??0;o=this.engine.createPointLight(i,n,a,c)}else t==="directional"?o=this.engine.createDirectionalLight(i,n):o=this.engine.createAmbientLight(i,n);let s=new g(e.id,t+"Light",o,this.engine);return r(s),s}createBox(e,t){let r=this.engine.createBoxGeometry(1,1,1),i=this.createMaterialFromObject(e),n=this.engine.createMesh(r,i),o=new g(e.id,"box",n,this.engine,{geometry:r,material:i});return t(o),o}createSphere(e,t){let r=e.getProperty("3d-segments-width")??32,i=e.getProperty("3d-segments-height")??32,n=this.engine.createSphereGeometry(.5,r,i),o=this.createMaterialFromObject(e),s=this.engine.createMesh(n,o),a=new g(e.id,"sphere",s,this.engine,{geometry:n,material:o});return t(a),a}createPlane(e,t){let r=this.engine.createPlaneGeometry(1,1),i=this.createMaterialFromObject(e),n=this.engine.createMesh(r,i),o=new g(e.id,"plane",n,this.engine,{geometry:r,material:i});return t(o),o}createCylinder(e,t){let r=e.getProperty("3d-segments")??32,i=this.engine.createCylinderGeometry(.5,.5,1,r),n=this.createMaterialFromObject(e),o=this.engine.createMesh(i,n),s=new g(e.id,"cylinder",o,this.engine,{geometry:i,material:n});return t(s),s}createModel(e,t){let r=e.getProperty("3d-model");if(!r)return;let i=e.getProperty("3d-model-loader")||void 0,n=this.resolveModelLoader(i);if(!n){console.warn("[String3D] Model loader not configured");return}let o=e.htmlElement;o&&this.applyModelTextureRemap(n,o);let s=e.getProperty("3d-model-center")??!1;n.load(r,a=>{let c=a?.scene||a?.object||a;if(!c){console.warn("[String3D] Model loader returned empty result");return}if(o&&this.shouldOverrideModelMaterial(o)){let h=this.createMaterialFromElement(o,e);typeof c.traverse=="function"&&c.traverse(u=>{u.isMesh&&(u.material=h)})}s&&this.centerObject(c);let d=new g(e.id,"model",c,this.engine);t(d)},a=>{console.log(a.loaded/a.total*100+"% loaded")},a=>{console.error("[String3D] Model loading error:",a)})}resolveModelLoader(e){if(e){if(this._modelLoaderCache.has(e))return this._modelLoaderCache.get(e);if(!this._modelLoaderFactory){console.warn(`[String3D] No model loader factory for type "${e}"`);return}let t=this._modelLoaderFactory(this.engine,e);return this._modelLoaderCache.set(e,t),t}if(this._modelLoader)return this._modelLoader;if(this._modelLoaderFactory)return this._modelLoaderFactory(this.engine)}centerObject(e){if(!e)return;let t=this.engine.computeBoundingBoxRecursively(e),r=this.getBoxCenter(t);e.position?.set&&e.position.set(-r.x,-r.y,-r.z),e.updateMatrixWorld(!0)}getBoxCenter(e){let t=this.engine.createVector3();return t.x=(e.min.x+e.max.x)/2,t.y=(e.min.y+e.max.y)/2,t.z=(e.min.z+e.max.z)/2,t}createMaterialFromObject(e){return this.createMaterialFromElement(e.htmlElement,e)}createMaterialFromElement(e,t){let r=t?.getProperty("3d-material")||"basic[#ffffff]",[i,n]=r.split(/\[|\]/),o=n||"#ffffff",s=t?.getProperty("3d-opacity")??1,a=t?.getProperty("3d-metalness"),c=t?.getProperty("3d-roughness"),d={color:o,transparent:s<1,opacity:s},h=e?.getAttribute("string-3d-map"),u=e?.getAttribute("string-3d-normalMap"),b=e?.getAttribute("string-3d-roughnessMap"),f=e?.getAttribute("string-3d-metalnessMap"),R=e?.getAttribute("string-3d-aoMap"),D=this.parseFlipY(t,e),m=t?.getProperty("3d-colorSpace")||e?.getAttribute("string-3d-colorSpace")||"";return i!=="standard"&&!!(h||u||b||f||R)&&(i="standard"),i==="standard"?(h&&(d.map=this.loadTexture(h,{flipY:D,colorSpace:m})),u&&(d.normalMap=this.loadTexture(u,{flipY:D})),b&&(d.roughnessMap=this.loadTexture(b,{flipY:D})),f&&(d.metalnessMap=this.loadTexture(f,{flipY:D})),R&&(d.aoMap=this.loadTexture(R,{flipY:D})),typeof a=="number"&&(d.metalness=a),typeof c=="number"&&(d.roughness=c),this.engine.createMeshStandardMaterial(d)):this.engine.createMeshBasicMaterial(d)}loadTexture(e,t={}){let i=this.engine.createTextureLoader().load(e);typeof t.flipY=="boolean"&&(i.flipY=t.flipY);let n=(t.colorSpace||"").toLowerCase().trim();return n&&"colorSpace"in i&&(i.colorSpace=n==="srgb"?"srgb":"linear"),i.needsUpdate=!0,i}parseFlipY(e,t){let r=e?.getProperty("3d-texture-flipY")??t?.getAttribute("string-3d-texture-flipY");if(r==null||r==="")return;if(typeof r=="boolean")return r;let i=String(r).toLowerCase().trim();if(i==="false"||i==="0"||i==="no")return!1;if(i==="true"||i==="1"||i==="yes")return!0}shouldOverrideModelMaterial(e){return["string-3d-material","string-3d-color","string-3d-opacity","string-3d-map","string-3d-normalMap","string-3d-roughnessMap","string-3d-metalnessMap","string-3d-aoMap","string-3d-metalness","string-3d-roughness"].some(r=>e.hasAttribute(r))}applyModelTextureRemap(e,t){let r=(t.getAttribute("string-3d-model-texture-base")||"").trim(),i=r?r.replace(/\/?$/,"/"):"",n=t.getAttribute("string-3d-model-textures"),o=null;if(n)try{o=JSON.parse(n)}catch(a){console.warn("[String3D] Invalid model texture mapping JSON:",a)}let s=e?.manager;if(!s||typeof s.setURLModifier!="function"){(o||i)&&console.warn("[String3D] Model loader does not support URL remap.");return}s.setURLModifier(a=>{let c=o&&a in o?o[a]:a;return!i||/^(blob:|data:|https?:|file:|\/)/i.test(c)?c:i+c.replace(/^\.?\//,"")})}destroy(){this._objects.forEach(e=>e.destroy()),this._objects.clear(),this._rootObjects=[]}};var H=class{sync(e,t,r,i){let n=e.getBoundingClientRect(),o=n.left+n.width/2,s=n.top+n.height/2,a=getComputedStyle(e),c=parseFloat(a.getPropertyValue("--translate-z")||"0"),d=r.camera.screenToWorld(o,s,c);t.position=d;let h=parseFloat(a.getPropertyValue("--scale"))||1;t.scale=r.engine.createVector3(h,h,h);let u=-r.engine.degToRad(parseFloat(a.getPropertyValue("--rotate-x")||"0")),b=r.engine.degToRad(parseFloat(a.getPropertyValue("--rotate-y")||"0")),f=-r.engine.degToRad(parseFloat(a.getPropertyValue("--rotate-z")||"0"));return t.rotation=r.engine.createEuler(u,b,f,"XYZ"),t.object.updateMatrixWorld(!0),{scale:h}}};var C=class{sync(e,t,r,i){let n=e.getBoundingClientRect(),o=n.left+n.width/2,s=n.top+n.height/2,a=parseFloat(getComputedStyle(e).getPropertyValue("--translate-z")||"0"),c=r.camera.screenToWorld(o,s,a);return t.position=c,null}};var y=class{sync(e,t,r,i){let n=getComputedStyle(e),o=e.offsetWidth,s=e.offsetHeight,a=e.getBoundingClientRect(),c=parseFloat(n.getPropertyValue("--translate-z")||"0"),d=parseFloat(n.getPropertyValue("--scale")||"1"),h=a.left+a.width/2,u=a.top+a.height/2,b=r.camera.screenToWorld(h,u,c);t.position=b;let f=-r.engine.degToRad(parseFloat(n.getPropertyValue("--rotate-x")||"0")),R=r.engine.degToRad(parseFloat(n.getPropertyValue("--rotate-y")||"0")),D=-r.engine.degToRad(parseFloat(n.getPropertyValue("--rotate-z")||"0"));t.rotation=r.engine.createEuler(f,R,D,"XYZ");let m=o*d,S=s*d,B=parseFloat(n.getPropertyValue("--scale-z")||"1"),p=i?.scale||1,Q=t.type,I,x,E;switch(Q){case"box":case"sphere":{let v=Math.min(m,S);I=v*p,x=v*p,E=v*B*p;break}case"model":{let z=t.getOriginalBoundingBox().getSize(r.engine.createVector3()),X=(e.getAttribute("string-3d-model-fit")||"contain").toLowerCase().trim(),W=parseFloat(e.getAttribute("string-3d-model-scale")||"1"),_=Number.isFinite(W)?W:1;if(z.x>0&&z.y>0){let L=m/z.x,Y=S/z.y,k=X==="cover"?Math.max(L,Y):Math.min(L,Y);I=k*_*p,x=k*_*p,E=k*_*B*p}else{let L=Math.min(m,S);I=L*_*p,x=L*_*p,E=L*_*B*p}break}case"cylinder":{let v=m;I=v*p,x=S*p,E=v*B*p;break}case"plane":default:I=m*p,x=S*p,E=Math.min(m,S)*.5*B*p;break}return t.scale=r.engine.createVector3(I,x,E),{scale:d*p}}};var j=class{constructor(e,t,r,i){this.camera=e;this.viewportWidth=t;this.viewportHeight=r;this.engine=i;this.strategies=new Map;this.strategies.set("box",new y),this.strategies.set("sphere",new y),this.strategies.set("plane",new y),this.strategies.set("cylinder",new y),this.strategies.set("model",new y),this.strategies.set("group",new H),this.strategies.set("pointLight",new C),this.strategies.set("ambientLight",new C),this.strategies.set("directionalLight",new C)}syncElement(e,t,r){let i=this.strategies.get(t.type);return i?i.sync(e,t,{camera:this.camera,viewportWidth:this.viewportWidth,viewportHeight:this.viewportHeight,engine:this.engine},r):(console.warn(`[String3D Sync] No strategy for type "${t.type}"`),null)}updateViewportSize(e,t){this.viewportWidth=e,this.viewportHeight=t}};var A=require("@fiddle-digital/string-tune"),M=class M extends Z.StringModule{constructor(t){super(t);this.renderer=null;this.camera=null;this.scene=null;this.synchronizer=null;this.engine=null;this.canvasContainer=null;this.isLoading=new Map;this.htmlKey="3d",this.options=this.buildOptionsFromSettings(),this.attributesToMap=[...this.attributesToMap,{key:"3d",type:"string",fallback:"box"},{key:"3d-material",type:"string",fallback:"basic[#ffffff]"},{key:"3d-color",type:"string",fallback:"#ffffff"},{key:"3d-opacity",type:"number",fallback:1},{key:"3d-intensity",type:"number",fallback:1},{key:"3d-distance",type:"number",fallback:1e3},{key:"3d-decay",type:"number",fallback:0},{key:"3d-model",type:"string",fallback:""},{key:"3d-segments",type:"number",fallback:32},{key:"3d-segments-width",type:"number",fallback:32},{key:"3d-segments-height",type:"number",fallback:32},{key:"3d-model-loader",type:"string",fallback:""},{key:"3d-model-scale",type:"number",fallback:1},{key:"3d-model-center",type:"boolean",fallback:!1},{key:"3d-model-fit",type:"string",fallback:"contain"},{key:"3d-metalness",type:"number",fallback:0},{key:"3d-roughness",type:"number",fallback:1},{key:"3d-texture-flipY",type:"boolean",fallback:!0},{key:"3d-colorSpace",type:"string",fallback:""}]}static setProvider(t){M.provider=t}canConnect(t){let r=super.canConnect(t);return console.log("[String3D] canConnect:",t.id,"keys:",t.keys,"htmlKey:",this.htmlKey,"result:",r),r}initializeObject(t,r,i,n){super.initializeObject(t,r,i,n),r.setProperty("parentId",null);let o=i.parentElement?.closest('[string-3d="group"]');if(o){let s=o.getAttribute("string-id");s&&(r.setProperty("parentId",s),r.setProperty("parent",o))}}onResize(){this.renderer&&this.camera&&this.synchronizer&&(this.renderer.resize(this.camera),this.synchronizer.updateViewportSize(this.renderer.width,this.renderer.height),this.camera.clearScaleCache())}onInit(){if(this.options=this.buildOptionsFromSettings(),!M.provider){console.error("[String3D] No provider set. Call String3D.setProvider() before use.");return}this.engine=M.provider.getEngine(),this.canvasContainer=this.createOrGetContainer(),this.injectCSS(),this.renderer=new w(this.canvasContainer,this.engine),this.renderer.attach(),this.camera=new O(this.engine,"orthographic"),this.camera.setPosition(0,0,1e3),this.camera.resize(this.renderer.width,this.renderer.height);let t=this.resolveModelLoader(),r=this.resolveModelLoaderFactory();this.scene=new T(this.engine,{modelLoader:t,modelLoaderFactory:r}),this.scene.getScene().add(this.camera.camera),this.synchronizer=new j(this.camera,this.renderer.width,this.renderer.height,this.engine),console.info(`[String3D] Initialized with: ${M.provider.getName()}`)}onSettingsChange(){this.options=this.buildOptionsFromSettings()}buildOptionsFromSettings(){return{hideHTML:this.getSettingValue("hideHTML",!1),container:this.getSettingValue("container",void 0),zIndex:this.getSettingValue("zIndex",1),modelLoaderType:this.getSettingValue("modelLoaderType",void 0),modelLoader:this.getSettingValue("modelLoader",void 0),modelLoaderFactory:this.getSettingValue("modelLoaderFactory",void 0)}}getSettingValue(t,r){return!this.settings||!(t in this.settings)?r:this.settings[t]}resolveModelLoader(){if(this.engine){if(this.options.modelLoader)return this.options.modelLoader;if(!this.options.modelLoaderFactory&&this.options.modelLoaderType)try{return this.engine.createModelLoader(this.options.modelLoaderType)}catch(t){console.warn("[String3D] Failed to create model loader:",t)}}}resolveModelLoaderFactory(){if(this.engine){if(this.options.modelLoaderFactory)return this.options.modelLoaderFactory;if(this.options.modelLoaderType)return(t,r)=>{let i=r||this.options.modelLoaderType;if(!i)throw new Error("[String3D] Model loader type not provided");return t.createModelLoader(i)}}}createOrGetContainer(){if(this.options.container instanceof HTMLElement)return this.applyContainerStyles(this.options.container),this.options.container;if(typeof this.options.container=="string"){let r=document.getElementById(this.options.container);if(r)return this.applyContainerStyles(r),r}let t=document.createElement("div");return t.id="string-3d-canvas",this.applyContainerStyles(t),document.body.insertBefore(t,document.body.firstChild),t}applyContainerStyles(t){Object.assign(t.style,{position:"fixed",left:"0",top:"0",width:"100vw",height:"100lvh",zIndex:String(this.options.zIndex),pointerEvents:"none"})}onObjectConnected(t){this.isLoading.has(t.id)||!this.scene||(this.isLoading.set(t.id,!0),this.scene.createFromElement(t),this.options.hideHTML&&t.htmlElement&&(t.htmlElement.style.opacity="0",t.htmlElement.style.pointerEvents="none"))}onFrame(t){!this.renderer||!this.scene||!this.camera||!this.synchronizer||(A.frameDOM.measure(()=>{this.scene.rootObjects.forEach(r=>{this.syncRecursive(r.el,r,{scale:1})})}),A.frameDOM.mutate(()=>{this.renderer.render(this.scene,this.camera)}))}syncRecursive(t,r,i){if(!this.synchronizer||!t)return;let n=this.synchronizer.syncElement(t,r,i);r.children.forEach(o=>this.syncRecursive(o.el,o,n))}injectCSS(){if(document.getElementById("string-3d-styles"))return;let t=document.createElement("style");t.id="string-3d-styles",t.textContent=`
|
|
2
2
|
@property --translate-x { syntax: "<number>"; inherits: false; initial-value: 0; }
|
|
3
3
|
@property --translate-y { syntax: "<number>"; inherits: false; initial-value: 0; }
|
|
4
4
|
@property --translate-z { syntax: "<number>"; inherits: false; initial-value: 0; }
|
|
@@ -25,5 +25,5 @@
|
|
|
25
25
|
rotateZ(calc(var(--rotate-z) * 1deg))
|
|
26
26
|
scale3d(calc(var(--scale) * var(--scale-x)), calc(var(--scale) * var(--scale-y)), calc(var(--scale) * var(--scale-z)));
|
|
27
27
|
}
|
|
28
|
-
`,document.head.appendChild(t)}destroy(){this.renderer?.destroy(),this.scene?.destroy(),this.isLoading.clear(),document.getElementById("string-3d-styles")?.remove(),this.canvasContainer?.id==="string-3d-canvas"&&this.canvasContainer.remove(),super.destroy()}};
|
|
28
|
+
`,document.head.appendChild(t)}destroy(){this.renderer?.destroy(),this.scene?.destroy(),this.isLoading.clear(),document.getElementById("string-3d-styles")?.remove(),this.canvasContainer?.id==="string-3d-canvas"&&this.canvasContainer.remove(),super.destroy()}};M.provider=null;var F=M;var P=class{constructor(e,t={}){this.THREE=e,this.loaders=t}createVector3(e=0,t=0,r=0){return new this.THREE.Vector3(e,t,r)}createVector2(e=0,t=0){return new this.THREE.Vector2(e,t)}createQuaternion(e=0,t=0,r=0,i=1){return new this.THREE.Quaternion(e,t,r,i)}createEuler(e=0,t=0,r=0,i="XYZ"){return new this.THREE.Euler(e,t,r,i)}createMatrix4(){return new this.THREE.Matrix4}createBox3(e,t){return new this.THREE.Box3(e,t)}createScene(){return new this.THREE.Scene}createRenderer(e){let t=new this.THREE.WebGLRenderer(e);return t.outputEncoding=this.THREE.sRGBEncoding,t}createPerspectiveCamera(e=45,t=1,r=.1,i=2e3){return new this.THREE.PerspectiveCamera(e,t,r,i)}createOrthographicCamera(e,t,r,i,n=.1,o=1e4){return new this.THREE.OrthographicCamera(e,t,r,i,n,o)}createGroup(){return new this.THREE.Group}createMesh(e,t){return new this.THREE.Mesh(e,t)}createBoxGeometry(e,t,r){return new this.THREE.BoxGeometry(e,t,r)}createSphereGeometry(e,t=32,r=32){return new this.THREE.SphereGeometry(e,t,r)}createPlaneGeometry(e,t){return new this.THREE.PlaneGeometry(e,t)}createCylinderGeometry(e,t,r,i=32){return new this.THREE.CylinderGeometry(e,t,r,i)}createMeshBasicMaterial(e){return new this.THREE.MeshBasicMaterial(e)}createMeshStandardMaterial(e){return new this.THREE.MeshStandardMaterial(e)}createPointLight(e,t=1,r=0,i=2){return new this.THREE.PointLight(e,t,r,i)}createAmbientLight(e,t=1){return new this.THREE.AmbientLight(e,t)}createDirectionalLight(e,t=1){return new this.THREE.DirectionalLight(e,t)}createTextureLoader(){return new this.THREE.TextureLoader}createModelLoader(e){let t=this.loaders[e];if(!t)throw new Error(`[ThreeJSEngine] Model loader "${e}" not registered`);return new t}degToRad(e){return this.THREE.MathUtils.degToRad(e)}radToDeg(e){return this.THREE.MathUtils.radToDeg(e)}computeBoundingBoxRecursively(e){let t=new this.THREE.Box3,r=!1;return e.traverse&&e.traverse(i=>{if(i.visible&&i.geometry){typeof i.geometry.computeBoundingBox=="function"&&i.geometry.computeBoundingBox();let n=i.geometry.boundingBox;if(n){let o=n.clone().applyMatrix4(i.matrixWorld);t.union(o),r=!0}}}),r?t:new this.THREE.Box3}},V=class{constructor(e,t={}){this.engine=new P(e,t)}getEngine(){return this.engine}getName(){return"Three.js"}};0&&(module.exports={String3D,String3DCamera,String3DObject,String3DRenderer,String3DScene,String3DSynchronizer,ThreeJSEngine,ThreeJSProvider});
|
|
29
29
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/modules/String3D.ts","../src/core/String3DCamera.ts","../src/core/String3DRenderer.ts","../src/core/String3DObject.ts","../src/core/String3DScene.ts","../src/core/synchronizer/GroupSynchronizer.ts","../src/core/synchronizer/LightSynchronizer.ts","../src/core/synchronizer/MeshSynchronizer.ts","../src/core/synchronizer/String3DSynchronizer.ts","../src/adapters/ThreeJSProvider.ts"],"sourcesContent":["export { String3D } from \"./modules/String3D\";\r\nexport type { String3DOptions } from \"./modules/String3D\";\r\n\r\nexport type {\r\n I3DEngine,\r\n I3DVector3,\r\n I3DVector2,\r\n I3DQuaternion,\r\n I3DEuler,\r\n I3DMatrix4,\r\n I3DBox3,\r\n I3DObject,\r\n I3DMesh,\r\n I3DGeometry,\r\n I3DMaterial,\r\n I3DLight,\r\n I3DCamera,\r\n I3DPerspectiveCamera,\r\n I3DOrthographicCamera,\r\n I3DScene,\r\n I3DRenderer,\r\n I3DTextureLoader,\r\n I3DModelLoader,\r\n} from \"./core/abstractions/I3DEngine\";\r\n\r\nexport type { CameraMode } from \"./core/String3DCamera\";\r\nexport type { I3DEngineProvider } from \"./core/abstractions/I3DEngineProvider\";\r\n\r\nexport { String3DCamera } from \"./core/String3DCamera\";\r\nexport { String3DRenderer } from \"./core/String3DRenderer\";\r\nexport { String3DScene } from \"./core/String3DScene\";\r\nexport { String3DObject } from \"./core/String3DObject\";\r\nexport { String3DSynchronizer } from \"./core/synchronizer/String3DSynchronizer\";\r\n\r\nexport { ThreeJSProvider, ThreeJSEngine } from \"./adapters/ThreeJSProvider\";\r\n","import { StringModule } from \"@fiddle-digital/string-tune\";\r\nimport { StringObject } from \"@fiddle-digital/string-tune\";\r\nimport { StringData } from \"@fiddle-digital/string-tune\";\r\nimport { StringContext } from \"@fiddle-digital/string-tune\";\r\nimport { String3DCamera } from \"../core/String3DCamera\";\r\nimport { String3DRenderer } from \"../core/String3DRenderer\";\r\nimport { String3DScene } from \"../core/String3DScene\";\r\nimport { String3DSynchronizer } from \"../core/synchronizer/String3DSynchronizer\";\r\nimport { I3DEngineProvider } from \"../core/abstractions/I3DEngineProvider\";\r\nimport { I3DEngine } from \"../core/abstractions/I3DEngine\";\r\nimport { frameDOM } from \"@fiddle-digital/string-tune\";\r\n\r\nexport interface String3DOptions {\r\n hideHTML?: boolean;\r\n container?: string | HTMLElement;\r\n zIndex?: number;\r\n}\r\n\r\nexport class String3D extends StringModule {\r\n private static provider: I3DEngineProvider | null = null;\r\n\r\n private renderer: String3DRenderer | null = null;\r\n private camera: String3DCamera | null = null;\r\n private scene: String3DScene | null = null;\r\n private synchronizer: String3DSynchronizer | null = null;\r\n private engine: I3DEngine | null = null;\r\n private canvasContainer: HTMLElement | null = null;\r\n private isLoading: Map<string, boolean> = new Map();\r\n private options: String3DOptions;\r\n\r\n public static setProvider(provider: I3DEngineProvider): void {\r\n String3D.provider = provider;\r\n }\r\n\r\n constructor(context: StringContext, options: String3DOptions = {}) {\r\n super(context);\r\n this.htmlKey = \"3d\";\r\n this.options = {\r\n hideHTML: options.hideHTML ?? false,\r\n container: options.container,\r\n zIndex: options.zIndex ?? 1,\r\n };\r\n\r\n this.attributesToMap = [\r\n ...this.attributesToMap,\r\n { key: \"3d\", type: \"string\", fallback: \"box\" },\r\n { key: \"3d-material\", type: \"string\", fallback: \"basic[#ffffff]\" },\r\n { key: \"3d-color\", type: \"string\", fallback: \"#ffffff\" },\r\n { key: \"3d-opacity\", type: \"number\", fallback: 1 },\r\n { key: \"3d-intensity\", type: \"number\", fallback: 1 },\r\n { key: \"3d-distance\", type: \"number\", fallback: 1000 },\r\n { key: \"3d-decay\", type: \"number\", fallback: 0 },\r\n { key: \"3d-model\", type: \"string\", fallback: \"\" },\r\n { key: \"3d-segments\", type: \"number\", fallback: 32 },\r\n { key: \"3d-segments-width\", type: \"number\", fallback: 32 },\r\n { key: \"3d-segments-height\", type: \"number\", fallback: 32 },\r\n ];\r\n }\r\n\r\n override canConnect(object: StringObject): boolean {\r\n const result = super.canConnect(object);\r\n console.log(\r\n \"[String3D] canConnect:\",\r\n object.id,\r\n \"keys:\",\r\n object.keys,\r\n \"htmlKey:\",\r\n this.htmlKey,\r\n \"result:\",\r\n result\r\n );\r\n return result;\r\n }\r\n\r\n override initializeObject(\r\n globalId: number,\r\n object: StringObject,\r\n element: HTMLElement,\r\n attributes: Record<string, any>\r\n ): void {\r\n super.initializeObject(globalId, object, element, attributes);\r\n\r\n object.setProperty(\"parentId\", null);\r\n const parentElement = element.parentElement?.closest(\r\n '[string-3d=\"group\"]'\r\n ) as HTMLElement | null;\r\n if (parentElement) {\r\n const parentId = parentElement.getAttribute(\"string-id\");\r\n if (parentId) {\r\n object.setProperty(\"parentId\", parentId);\r\n object.setProperty(\"parent\", parentElement);\r\n }\r\n }\r\n }\r\n\r\n override onResize(): void {\r\n if (this.renderer && this.camera && this.synchronizer) {\r\n this.renderer.resize(this.camera);\r\n this.synchronizer.updateViewportSize(this.renderer.width, this.renderer.height);\r\n this.camera.clearScaleCache();\r\n }\r\n }\r\n\r\n override onInit(): void {\r\n if (!String3D.provider) {\r\n console.error(\"[String3D] No provider set. Call String3D.setProvider() before use.\");\r\n return;\r\n }\r\n\r\n this.engine = String3D.provider.getEngine();\r\n this.canvasContainer = this.createOrGetContainer();\r\n this.injectCSS();\r\n\r\n this.renderer = new String3DRenderer(this.canvasContainer, this.engine);\r\n this.renderer.attach();\r\n\r\n this.camera = new String3DCamera(this.engine, \"orthographic\");\r\n this.camera.setPosition(0, 0, 1000);\r\n this.camera.resize(this.renderer.width, this.renderer.height);\r\n\r\n this.scene = new String3DScene(this.engine);\r\n this.scene.getScene().add(this.camera.camera);\r\n\r\n this.synchronizer = new String3DSynchronizer(\r\n this.camera,\r\n this.renderer.width,\r\n this.renderer.height,\r\n this.engine\r\n );\r\n\r\n console.info(`[String3D] Initialized with: ${String3D.provider.getName()}`);\r\n }\r\n\r\n private createOrGetContainer(): HTMLElement {\r\n if (this.options.container instanceof HTMLElement) {\r\n this.applyContainerStyles(this.options.container);\r\n return this.options.container;\r\n }\r\n\r\n if (typeof this.options.container === \"string\") {\r\n const existing = document.getElementById(this.options.container);\r\n if (existing) {\r\n this.applyContainerStyles(existing);\r\n return existing;\r\n }\r\n }\r\n\r\n const container = document.createElement(\"div\");\r\n container.id = \"string-3d-canvas\";\r\n this.applyContainerStyles(container);\r\n document.body.insertBefore(container, document.body.firstChild);\r\n return container;\r\n }\r\n\r\n private applyContainerStyles(el: HTMLElement): void {\r\n Object.assign(el.style, {\r\n position: \"fixed\",\r\n left: \"0\",\r\n top: \"0\",\r\n width: \"100vw\",\r\n height: \"100lvh\",\r\n zIndex: String(this.options.zIndex),\r\n pointerEvents: \"none\",\r\n });\r\n }\r\n\r\n override onObjectConnected(object: StringObject): void {\r\n if (this.isLoading.has(object.id) || !this.scene) return;\r\n this.isLoading.set(object.id, true);\r\n\r\n this.scene.createFromElement(object);\r\n\r\n if (this.options.hideHTML && object.htmlElement) {\r\n object.htmlElement.style.opacity = \"0\";\r\n object.htmlElement.style.pointerEvents = \"none\";\r\n }\r\n }\r\n\r\n override onFrame(data: StringData): void {\r\n if (!this.renderer || !this.scene || !this.camera || !this.synchronizer) return;\r\n\r\n frameDOM.measure(() => {\r\n this.scene!.rootObjects.forEach((obj) => {\r\n this.syncRecursive(obj.el, obj, { scale: 1 });\r\n });\r\n });\r\n\r\n frameDOM.mutate(() => {\r\n this.renderer!.render(this.scene!, this.camera!);\r\n });\r\n }\r\n\r\n private syncRecursive(el: HTMLElement | undefined, object: any, parentData: any): void {\r\n if (!this.synchronizer || !el) return;\r\n const data = this.synchronizer.syncElement(el, object, parentData);\r\n object.children.forEach((child: any) => this.syncRecursive(child.el, child, data));\r\n }\r\n\r\n private injectCSS(): void {\r\n if (document.getElementById(\"string-3d-styles\")) return;\r\n\r\n const style = document.createElement(\"style\");\r\n style.id = \"string-3d-styles\";\r\n style.textContent = `\r\n @property --translate-x { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --translate-y { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --translate-z { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --rotate-x { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --rotate-y { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --rotate-z { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --scale { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --scale-x { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --scale-y { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --scale-z { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n\r\n [string-3d] {\r\n --translate-x: 0; --translate-y: 0; --translate-z: 0;\r\n --rotate-x: 0; --rotate-y: 0; --rotate-z: 0;\r\n --scale: 1; --scale-x: 1; --scale-y: 1; --scale-z: 1;\r\n transform-style: preserve-3d;\r\n }\r\n\r\n [string-3d-visual=\"true\"] {\r\n transform:\r\n translate3d(calc(var(--translate-x) * 1px), calc(var(--translate-y) * 1px), calc(var(--translate-z) * 1px))\r\n rotateX(calc(var(--rotate-x) * 1deg))\r\n rotateY(calc(var(--rotate-y) * 1deg))\r\n rotateZ(calc(var(--rotate-z) * 1deg))\r\n scale3d(calc(var(--scale) * var(--scale-x)), calc(var(--scale) * var(--scale-y)), calc(var(--scale) * var(--scale-z)));\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n }\r\n\r\n override destroy(): void {\r\n this.renderer?.destroy();\r\n this.scene?.destroy();\r\n this.isLoading.clear();\r\n\r\n const styleEl = document.getElementById(\"string-3d-styles\");\r\n styleEl?.remove();\r\n\r\n if (this.canvasContainer?.id === \"string-3d-canvas\") {\r\n this.canvasContainer.remove();\r\n }\r\n\r\n super.destroy();\r\n }\r\n}\r\n","import { I3DEngine, I3DVector3, I3DCamera } from \"./abstractions/I3DEngine\";\r\n\r\nexport type CameraMode = \"orthographic\" | \"perspective\";\r\n\r\nexport class String3DCamera {\r\n private scaleCache = new Map<number, number>();\r\n private _camera: I3DCamera;\r\n private _position: I3DVector3;\r\n private _width = 1;\r\n private _height = 1;\r\n private engine: I3DEngine;\r\n private mode: CameraMode;\r\n private perspectiveFov: number;\r\n\r\n constructor(\r\n engine: I3DEngine,\r\n mode: CameraMode = \"orthographic\",\r\n fov = 50,\r\n near = 0.1,\r\n far = 10000\r\n ) {\r\n this.engine = engine;\r\n this.mode = mode;\r\n this.perspectiveFov = fov;\r\n\r\n if (mode === \"orthographic\") {\r\n this._camera = engine.createOrthographicCamera(-1, 1, 1, -1, near, far);\r\n } else {\r\n this._camera = engine.createPerspectiveCamera(fov, 1, near, far);\r\n }\r\n\r\n this._position = engine.createVector3(0, 0, 1000);\r\n this.update();\r\n }\r\n\r\n public get camera(): I3DCamera {\r\n return this._camera;\r\n }\r\n\r\n public resize(width: number, height: number): void {\r\n this._width = width;\r\n this._height = height;\r\n\r\n if (this.mode === \"orthographic\") {\r\n const ortho = this._camera as any;\r\n ortho.left = -width / 2;\r\n ortho.right = width / 2;\r\n ortho.top = height / 2;\r\n ortho.bottom = -height / 2;\r\n } else {\r\n this._camera.aspect = width / height;\r\n }\r\n\r\n this.update();\r\n }\r\n\r\n public setPosition(x: number, y: number, z: number): void {\r\n this._position.set(x, y, z);\r\n this._camera.position.copy(this._position);\r\n this.update();\r\n }\r\n\r\n public lookAt(x: number, y: number, z: number): void {\r\n this._camera.lookAt(x, y, z);\r\n this.update();\r\n }\r\n\r\n public update(): void {\r\n this._camera.updateProjectionMatrix();\r\n (this._camera as any).updateMatrixWorld?.();\r\n }\r\n\r\n public screenToWorld(screenX: number, screenY: number, z = 0): I3DVector3 {\r\n if (this.mode === \"orthographic\") {\r\n const x = screenX - this._width / 2;\r\n const y = -(screenY - this._height / 2);\r\n return this.engine.createVector3(x, y, z);\r\n } else {\r\n const { width, height } = this.getFrustumSizeAt(z);\r\n const normalizedX = screenX / this._width;\r\n const normalizedY = screenY / this._height;\r\n const x = (normalizedX - 0.5) * width;\r\n const y = -(normalizedY - 0.5) * height;\r\n return this.engine.createVector3(x, y, z);\r\n }\r\n }\r\n\r\n public getFrustumSizeAt(z: number): { width: number; height: number } {\r\n if (this.mode === \"orthographic\") {\r\n return { width: this._width, height: this._height };\r\n }\r\n\r\n const fov = this.engine.degToRad(this.perspectiveFov);\r\n const distance = Math.abs(z - this._camera.position.z);\r\n const height = 2 * Math.tan(fov / 2) * distance;\r\n const width = height * this._camera.aspect;\r\n return { width, height };\r\n }\r\n\r\n public getScaleAtZ(z: number, viewportHeight: number): number {\r\n if (this.mode === \"orthographic\") {\r\n return 1;\r\n }\r\n\r\n const roundedZ = Math.round(z * 1000) / 1000;\r\n if (this.scaleCache.has(roundedZ)) {\r\n return this.scaleCache.get(roundedZ)!;\r\n }\r\n\r\n const { height } = this.getFrustumSizeAt(z);\r\n const scale = height / viewportHeight;\r\n this.scaleCache.set(roundedZ, scale);\r\n return scale;\r\n }\r\n\r\n public clearScaleCache(): void {\r\n this.scaleCache.clear();\r\n }\r\n\r\n public getMode(): CameraMode {\r\n return this.mode;\r\n }\r\n}\r\n","import { I3DEngine, I3DRenderer } from \"./abstractions/I3DEngine\";\r\nimport { String3DCamera } from \"./String3DCamera\";\r\nimport { String3DScene } from \"./String3DScene\";\r\n\r\nexport class String3DRenderer {\r\n private _container: HTMLElement;\r\n private _renderer: I3DRenderer;\r\n private _width: number;\r\n private _height: number;\r\n private engine: I3DEngine;\r\n\r\n constructor(container: HTMLElement, engine: I3DEngine) {\r\n this.engine = engine;\r\n this._container = container;\r\n const { width, height } = container.getBoundingClientRect();\r\n this._width = width;\r\n this._height = height;\r\n\r\n this._renderer = engine.createRenderer({\r\n antialias: true,\r\n alpha: true,\r\n logarithmicDepthBuffer: true,\r\n });\r\n this._renderer.setPixelRatio(window.devicePixelRatio);\r\n this._renderer.setSize(width, height);\r\n }\r\n\r\n public attach(): void {\r\n this._container.appendChild(this._renderer.domElement);\r\n }\r\n\r\n public render(scene: String3DScene, camera: String3DCamera): void {\r\n this._renderer.render(scene.getScene(), camera.camera);\r\n }\r\n\r\n public resize(camera: String3DCamera): void {\r\n const { width, height } = this._container.getBoundingClientRect();\r\n this._width = width;\r\n this._height = height;\r\n this._renderer.setSize(width, height);\r\n camera.resize(width, height);\r\n }\r\n\r\n public get width(): number {\r\n return this._width;\r\n }\r\n\r\n public get height(): number {\r\n return this._height;\r\n }\r\n\r\n public get renderer(): I3DRenderer {\r\n return this._renderer;\r\n }\r\n\r\n public destroy(): void {\r\n this._renderer.dispose();\r\n }\r\n}\r\n","import {\r\n I3DEngine,\r\n I3DObject,\r\n I3DMaterial,\r\n I3DGeometry,\r\n I3DQuaternion,\r\n I3DVector3,\r\n I3DEuler,\r\n I3DMatrix4,\r\n I3DBox3,\r\n} from \"./abstractions/I3DEngine\";\r\n\r\nexport class String3DObject {\r\n public id: string;\r\n public type: string;\r\n private _object: I3DObject;\r\n private _material?: I3DMaterial;\r\n private _geometry?: I3DGeometry;\r\n private _texture?: any;\r\n private _uniforms: Record<string, { value: any }> = {};\r\n private _originalBoundingBox?: I3DBox3 | null;\r\n private _quaternion: I3DQuaternion;\r\n private _originalSize: I3DVector3;\r\n private _bbox: I3DBox3;\r\n public el: any;\r\n private _children: String3DObject[] = [];\r\n private engine: I3DEngine;\r\n\r\n public get children(): String3DObject[] {\r\n return this._children;\r\n }\r\n\r\n constructor(id: string, type: string, object: I3DObject, engine: I3DEngine) {\r\n this.id = id;\r\n this.type = type;\r\n this._object = object;\r\n this.engine = engine;\r\n this._quaternion = engine.createQuaternion();\r\n this._originalSize = engine.createVector3();\r\n this._bbox = engine.createBox3();\r\n this.updateBoundingBox();\r\n }\r\n\r\n public get object(): I3DObject {\r\n return this._object;\r\n }\r\n\r\n public get material(): I3DMaterial | undefined {\r\n return this._material;\r\n }\r\n\r\n public get originalSize(): I3DVector3 {\r\n return this._originalSize.clone();\r\n }\r\n\r\n public get boundingBox(): I3DBox3 {\r\n return this._bbox.clone();\r\n }\r\n\r\n public addChild(child: String3DObject): void {\r\n this._children.push(child);\r\n this.object.add(child.object);\r\n }\r\n\r\n public getWorldMatrix(): I3DMatrix4 {\r\n return this._object.matrixWorld.clone();\r\n }\r\n\r\n public getWorldPosition(): I3DVector3 {\r\n return this.engine.createVector3().setFromMatrixPosition(this._object.matrixWorld);\r\n }\r\n\r\n public getOriginalBoundingBox(): I3DBox3 {\r\n if (!this._originalBoundingBox) {\r\n const originalScale = this.object.scale.clone();\r\n this.object.scale.set(1, 1, 1);\r\n this.object.updateMatrixWorld(true);\r\n this._originalBoundingBox = this.engine.computeBoundingBoxRecursively(this.object);\r\n this.object.scale.copy(originalScale);\r\n this.object.updateMatrixWorld(true);\r\n }\r\n return this._originalBoundingBox!.clone();\r\n }\r\n\r\n public syncTransformFromMatrix(matrix: I3DMatrix4): void {\r\n const pos = this.engine.createVector3();\r\n const quat = this.engine.createQuaternion();\r\n const scale = this.engine.createVector3();\r\n matrix.decompose(pos, quat, scale);\r\n this._object.position.copy(pos);\r\n this._object.quaternion.copy(quat);\r\n this._object.scale.copy(scale);\r\n this._object.updateMatrix();\r\n this._object.updateMatrixWorld();\r\n }\r\n\r\n public applyWorldTransform(\r\n position: I3DVector3,\r\n quaternion: I3DQuaternion,\r\n scale: I3DVector3\r\n ): void {\r\n this._object.position.copy(position);\r\n this._object.quaternion.copy(quaternion);\r\n this._object.scale.copy(scale);\r\n this._object.updateMatrix();\r\n this._object.updateMatrixWorld();\r\n }\r\n\r\n public set quaternion(quaternion: I3DQuaternion) {\r\n this._quaternion.copy(quaternion);\r\n this._object.quaternion.copy(this._quaternion);\r\n this._object.updateMatrixWorld();\r\n }\r\n\r\n public set position(position: I3DVector3) {\r\n this._object.position.copy(position);\r\n }\r\n\r\n public set scale(scale: I3DVector3) {\r\n this._object.scale.copy(scale);\r\n }\r\n\r\n public set rotation(euler: I3DEuler) {\r\n this._object.rotation.copy(euler);\r\n }\r\n\r\n public set opacity(value: number) {\r\n const mat = this._object as any;\r\n if (mat.material && \"opacity\" in mat.material) {\r\n mat.material.opacity = value;\r\n }\r\n }\r\n\r\n public set metalness(value: number) {\r\n const mat = this._object as any;\r\n if (mat.material && \"metalness\" in mat.material) {\r\n mat.material.metalness = value;\r\n }\r\n }\r\n\r\n public set roughness(value: number) {\r\n const mat = this._object as any;\r\n if (mat.material && \"roughness\" in mat.material) {\r\n mat.material.roughness = value;\r\n }\r\n }\r\n\r\n public set texture(texture: any) {\r\n this._texture = texture;\r\n if ((this._object as any).isMesh && texture?.applyTexture) {\r\n texture.applyTexture(this._object);\r\n }\r\n }\r\n\r\n public updateBoundingBox(): void {\r\n this._bbox.setFromObject(this._object);\r\n this._bbox.getSize(this._originalSize);\r\n }\r\n\r\n public destroy(): void {\r\n this._texture?.dispose?.();\r\n this._material?.dispose();\r\n this._geometry?.dispose();\r\n }\r\n}\r\n","import { I3DEngine, I3DScene, I3DLight, I3DMaterial } from \"./abstractions/I3DEngine\";\r\nimport { String3DObject } from \"./String3DObject\";\r\nimport { StringObject } from \"@fiddle-digital/string-tune\";\r\n\r\nexport class String3DScene {\r\n private _scene: I3DScene;\r\n private _objects: Map<string, String3DObject> = new Map();\r\n private _rootObjects: String3DObject[] = [];\r\n private _elementMap: Map<string, HTMLElement> = new Map();\r\n private engine: I3DEngine;\r\n private _modelLoader: any;\r\n\r\n public get rootObjects(): String3DObject[] {\r\n return this._rootObjects;\r\n }\r\n\r\n constructor(engine: I3DEngine, modelLoader?: any) {\r\n this.engine = engine;\r\n this._modelLoader = modelLoader;\r\n this._scene = engine.createScene();\r\n }\r\n\r\n public getScene(): I3DScene {\r\n return this._scene;\r\n }\r\n\r\n public getObject(id: string): String3DObject | undefined {\r\n return this._objects.get(id);\r\n }\r\n\r\n public hasObject(id: string): boolean {\r\n return this._objects.has(id);\r\n }\r\n\r\n public deleteObject(id: string): boolean {\r\n const obj = this._objects.get(id);\r\n if (obj) {\r\n this._scene.remove(obj.object);\r\n this._objects.delete(id);\r\n obj.destroy();\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n public createFromElement(object: StringObject): void {\r\n const type = object.getProperty<string>(\"3d\");\r\n if (!type) return;\r\n\r\n const element = object.htmlElement;\r\n if (!element) return;\r\n\r\n const onAdd = (added3DObject: String3DObject) => {\r\n if (added3DObject) {\r\n const parentId = object.getProperty<string>(\"parentId\");\r\n if (parentId == null) {\r\n this._scene.add(added3DObject.object);\r\n this._rootObjects.push(added3DObject);\r\n } else {\r\n this._objects.get(parentId)?.addChild(added3DObject);\r\n }\r\n this._objects.set(object.id, added3DObject);\r\n this._elementMap.set(object.id, element);\r\n added3DObject.el = element;\r\n }\r\n };\r\n\r\n switch (type) {\r\n case \"group\":\r\n this.createGroup(object, onAdd);\r\n break;\r\n case \"pointLight\":\r\n this.createLight(object, \"point\", onAdd);\r\n break;\r\n case \"ambientLight\":\r\n this.createLight(object, \"ambient\", onAdd);\r\n break;\r\n case \"directionalLight\":\r\n this.createLight(object, \"directional\", onAdd);\r\n break;\r\n case \"model\":\r\n this.createModel(object, onAdd);\r\n break;\r\n case \"box\":\r\n this.createBox(object, onAdd);\r\n break;\r\n case \"sphere\":\r\n this.createSphere(object, onAdd);\r\n break;\r\n case \"plane\":\r\n this.createPlane(object, onAdd);\r\n break;\r\n case \"cylinder\":\r\n this.createCylinder(object, onAdd);\r\n break;\r\n }\r\n }\r\n\r\n private createGroup(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\r\n const group = this.engine.createGroup();\r\n const obj = new String3DObject(object.id, \"group\", group, this.engine);\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private createLight(\r\n object: StringObject,\r\n kind: \"point\" | \"ambient\" | \"directional\",\r\n onAdd: (obj: String3DObject) => void\r\n ): String3DObject {\r\n const color = object.getProperty<string>(\"3d-color\") || \"#ffffff\";\r\n const intensity = object.getProperty<number>(\"3d-intensity\") ?? 1;\r\n\r\n let light: I3DLight;\r\n if (kind === \"point\") {\r\n const distance = object.getProperty<number>(\"3d-distance\") ?? 1000;\r\n const decay = object.getProperty<number>(\"3d-decay\") ?? 0;\r\n light = this.engine.createPointLight(color, intensity, distance, decay);\r\n } else if (kind === \"directional\") {\r\n light = this.engine.createDirectionalLight(color, intensity);\r\n } else {\r\n light = this.engine.createAmbientLight(color, intensity);\r\n }\r\n\r\n const obj = new String3DObject(object.id, kind + \"Light\", light, this.engine);\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private createBox(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\r\n const geometry = this.engine.createBoxGeometry(1, 1, 1);\r\n const material = this.createMaterialFromObject(object);\r\n const mesh = this.engine.createMesh(geometry, material);\r\n const obj = new String3DObject(object.id, \"box\", mesh, this.engine);\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private createSphere(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\r\n const widthSegments = object.getProperty<number>(\"3d-segments-width\") ?? 32;\r\n const heightSegments = object.getProperty<number>(\"3d-segments-height\") ?? 32;\r\n const geometry = this.engine.createSphereGeometry(0.5, widthSegments, heightSegments);\r\n const material = this.createMaterialFromObject(object);\r\n const mesh = this.engine.createMesh(geometry, material);\r\n const obj = new String3DObject(object.id, \"sphere\", mesh, this.engine);\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private createPlane(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\r\n const geometry = this.engine.createPlaneGeometry(1, 1);\r\n const material = this.createMaterialFromObject(object);\r\n const mesh = this.engine.createMesh(geometry, material);\r\n const obj = new String3DObject(object.id, \"plane\", mesh, this.engine);\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private createCylinder(\r\n object: StringObject,\r\n onAdd: (obj: String3DObject) => void\r\n ): String3DObject {\r\n const segments = object.getProperty<number>(\"3d-segments\") ?? 32;\r\n const geometry = this.engine.createCylinderGeometry(0.5, 0.5, 1, segments);\r\n const material = this.createMaterialFromObject(object);\r\n const mesh = this.engine.createMesh(geometry, material);\r\n const obj = new String3DObject(object.id, \"cylinder\", mesh, this.engine);\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private createModel(object: StringObject, onAdd: (obj: String3DObject) => void): void {\r\n if (!this._modelLoader) {\r\n console.warn(\"[String3D] Model loader not configured\");\r\n return;\r\n }\r\n\r\n const modelPath = object.getProperty<string>(\"3d-model\");\r\n if (!modelPath) return;\r\n\r\n const material = this.createMaterialFromObject(object);\r\n\r\n const loader = this._modelLoader;\r\n loader.load(\r\n modelPath,\r\n (gltf: any) => {\r\n const gltfScene = gltf.scene;\r\n gltfScene.traverse((child: any) => {\r\n if (child.isMesh) {\r\n child.material = material;\r\n }\r\n });\r\n const obj = new String3DObject(object.id, \"model\", gltfScene, this.engine);\r\n onAdd(obj);\r\n },\r\n (xhr: any) => {\r\n console.log((xhr.loaded / xhr.total) * 100 + \"% loaded\");\r\n },\r\n (error: any) => {\r\n console.error(\"[String3D] Model loading error:\", error);\r\n }\r\n );\r\n }\r\n\r\n private createMaterialFromObject(object: StringObject): I3DMaterial {\r\n const attr = object.getProperty<string>(\"3d-material\") || \"basic[#ffffff]\";\r\n const [type, colorRaw] = attr.split(/\\[|\\]/);\r\n const color = colorRaw || \"#ffffff\";\r\n const opacity = object.getProperty<number>(\"3d-opacity\") ?? 1;\r\n const params: any = {\r\n color,\r\n transparent: opacity < 1,\r\n opacity: opacity,\r\n };\r\n\r\n const el = (object as any).el as HTMLElement;\r\n const mapSrc = el?.getAttribute(\"string-3d-map\");\r\n const normalMapSrc = el?.getAttribute(\"string-3d-normalMap\");\r\n const roughnessMapSrc = el?.getAttribute(\"string-3d-roughnessMap\");\r\n const aoMapSrc = el?.getAttribute(\"string-3d-aoMap\");\r\n\r\n if (type === \"standard\") {\r\n if (mapSrc) params.map = this.loadTexture(mapSrc);\r\n if (normalMapSrc) params.normalMap = this.loadTexture(normalMapSrc);\r\n if (roughnessMapSrc) params.roughnessMap = this.loadTexture(roughnessMapSrc);\r\n if (aoMapSrc) params.aoMap = this.loadTexture(aoMapSrc);\r\n return this.engine.createMeshStandardMaterial(params);\r\n }\r\n\r\n return this.engine.createMeshBasicMaterial(params);\r\n }\r\n\r\n private loadTexture(src: string): any {\r\n const textureLoader = this.engine.createTextureLoader();\r\n return textureLoader.load(src);\r\n }\r\n\r\n public destroy(): void {\r\n this._objects.forEach((obj) => obj.destroy());\r\n this._objects.clear();\r\n this._rootObjects = [];\r\n }\r\n}\r\n","import { String3DObject } from \"../String3DObject\";\r\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\r\nimport type { SyncContext } from \"./SyncContext\";\r\n\r\nexport class GroupSynchronizer implements String3DObjectSyncStrategy {\r\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\r\n const rect = el.getBoundingClientRect();\r\n const centerX = rect.left + rect.width / 2;\r\n const centerY = rect.top + rect.height / 2;\r\n\r\n const style = getComputedStyle(el);\r\n const translateZ = parseFloat(style.getPropertyValue(\"--translate-z\") || \"0\");\r\n const position = ctx.camera.screenToWorld(centerX, centerY, translateZ);\r\n object.position = position;\r\n\r\n const scale = parseFloat(style.getPropertyValue(\"--scale\")) || 1;\r\n object.scale = ctx.engine.createVector3(scale, scale, scale);\r\n\r\n const rotateX = -ctx.engine.degToRad(parseFloat(style.getPropertyValue(\"--rotate-x\") || \"0\"));\r\n const rotateY = ctx.engine.degToRad(parseFloat(style.getPropertyValue(\"--rotate-y\") || \"0\"));\r\n const rotateZ = -ctx.engine.degToRad(parseFloat(style.getPropertyValue(\"--rotate-z\") || \"0\"));\r\n object.rotation = ctx.engine.createEuler(rotateX, rotateY, rotateZ, \"XYZ\");\r\n\r\n object.object.updateMatrixWorld(true);\r\n\r\n return { scale };\r\n }\r\n}\r\n","import { String3DObject } from \"../String3DObject\";\r\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\r\nimport type { SyncContext } from \"./SyncContext\";\r\n\r\nexport class LightSynchronizer implements String3DObjectSyncStrategy {\r\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\r\n const rect = el.getBoundingClientRect();\r\n const centerX = rect.left + rect.width / 2;\r\n const centerY = rect.top + rect.height / 2;\r\n\r\n const translateZ = parseFloat(getComputedStyle(el).getPropertyValue(\"--translate-z\") || \"0\");\r\n const position = ctx.camera.screenToWorld(centerX, centerY, translateZ);\r\n object.position = position;\r\n\r\n return null;\r\n }\r\n}\r\n","import { String3DObject } from \"../String3DObject\";\r\nimport type { SyncContext } from \"./SyncContext\";\r\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\r\n\r\nexport class MeshSynchronizer implements String3DObjectSyncStrategy {\r\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\r\n const style = getComputedStyle(el);\r\n\r\n const originalWidth = el.offsetWidth;\r\n const originalHeight = el.offsetHeight;\r\n const rect = el.getBoundingClientRect();\r\n\r\n const translateZ = parseFloat(style.getPropertyValue(\"--translate-z\") || \"0\");\r\n const cssScale = parseFloat(style.getPropertyValue(\"--scale\") || \"1\");\r\n\r\n const centerX = rect.left + rect.width / 2;\r\n const centerY = rect.top + rect.height / 2;\r\n\r\n const worldPos = ctx.camera.screenToWorld(centerX, centerY, translateZ);\r\n object.position = worldPos;\r\n\r\n const rotateX = -ctx.engine.degToRad(parseFloat(style.getPropertyValue(\"--rotate-x\") || \"0\"));\r\n const rotateY = ctx.engine.degToRad(parseFloat(style.getPropertyValue(\"--rotate-y\") || \"0\"));\r\n const rotateZ = -ctx.engine.degToRad(parseFloat(style.getPropertyValue(\"--rotate-z\") || \"0\"));\r\n object.rotation = ctx.engine.createEuler(rotateX, rotateY, rotateZ, \"XYZ\");\r\n\r\n const targetWidth = originalWidth * cssScale;\r\n const targetHeight = originalHeight * cssScale;\r\n const cssScaleZ = parseFloat(style.getPropertyValue(\"--scale-z\") || \"1\");\r\n const parentScale = parentData?.scale || 1;\r\n\r\n const objectType = object.type;\r\n let scaleX: number, scaleY: number, scaleZ: number;\r\n\r\n switch (objectType) {\r\n case \"box\":\r\n case \"sphere\": {\r\n const uniformSize = Math.min(targetWidth, targetHeight);\r\n scaleX = uniformSize * parentScale;\r\n scaleY = uniformSize * parentScale;\r\n scaleZ = uniformSize * cssScaleZ * parentScale;\r\n break;\r\n }\r\n case \"cylinder\": {\r\n const cylRadius = targetWidth;\r\n scaleX = cylRadius * parentScale;\r\n scaleY = targetHeight * parentScale;\r\n scaleZ = cylRadius * cssScaleZ * parentScale;\r\n break;\r\n }\r\n case \"plane\":\r\n default:\r\n scaleX = targetWidth * parentScale;\r\n scaleY = targetHeight * parentScale;\r\n scaleZ = Math.min(targetWidth, targetHeight) * 0.5 * cssScaleZ * parentScale;\r\n break;\r\n }\r\n\r\n object.scale = ctx.engine.createVector3(scaleX, scaleY, scaleZ);\r\n\r\n return { scale: cssScale * parentScale };\r\n }\r\n}\r\n","import { String3DCamera } from \"../String3DCamera\";\r\nimport { String3DObject } from \"../String3DObject\";\r\nimport { I3DEngine } from \"../abstractions/I3DEngine\";\r\nimport { GroupSynchronizer } from \"./GroupSynchronizer\";\r\nimport { LightSynchronizer } from \"./LightSynchronizer\";\r\nimport { MeshSynchronizer } from \"./MeshSynchronizer\";\r\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\r\n\r\nexport class String3DSynchronizer {\r\n private strategies: Map<string, String3DObjectSyncStrategy> = new Map();\r\n\r\n constructor(\r\n public camera: String3DCamera,\r\n public viewportWidth: number,\r\n public viewportHeight: number,\r\n public engine: I3DEngine\r\n ) {\r\n this.strategies.set(\"box\", new MeshSynchronizer());\r\n this.strategies.set(\"sphere\", new MeshSynchronizer());\r\n this.strategies.set(\"plane\", new MeshSynchronizer());\r\n this.strategies.set(\"cylinder\", new MeshSynchronizer());\r\n this.strategies.set(\"model\", new MeshSynchronizer());\r\n this.strategies.set(\"group\", new GroupSynchronizer());\r\n this.strategies.set(\"pointLight\", new LightSynchronizer());\r\n this.strategies.set(\"ambientLight\", new LightSynchronizer());\r\n this.strategies.set(\"directionalLight\", new LightSynchronizer());\r\n }\r\n\r\n public syncElement(el: HTMLElement, object: String3DObject, parentData: any): any {\r\n const strategy = this.strategies.get(object.type);\r\n if (!strategy) {\r\n console.warn(`[String3D Sync] No strategy for type \"${object.type}\"`);\r\n return null;\r\n }\r\n\r\n return strategy.sync(\r\n el,\r\n object,\r\n {\r\n camera: this.camera,\r\n viewportWidth: this.viewportWidth,\r\n viewportHeight: this.viewportHeight,\r\n engine: this.engine,\r\n },\r\n parentData\r\n );\r\n }\r\n\r\n public updateViewportSize(width: number, height: number): void {\r\n this.viewportWidth = width;\r\n this.viewportHeight = height;\r\n }\r\n}\r\n","import {\r\n I3DEngine,\r\n I3DVector3,\r\n I3DVector2,\r\n I3DQuaternion,\r\n I3DEuler,\r\n I3DMatrix4,\r\n I3DBox3,\r\n I3DScene,\r\n I3DRenderer,\r\n I3DPerspectiveCamera,\r\n I3DOrthographicCamera,\r\n I3DObject,\r\n I3DMesh,\r\n I3DGeometry,\r\n I3DMaterial,\r\n I3DLight,\r\n I3DTextureLoader,\r\n I3DModelLoader,\r\n} from \"../core/abstractions/I3DEngine\";\r\nimport { I3DEngineProvider } from \"../core/abstractions/I3DEngineProvider\";\r\n\r\nexport class ThreeJSEngine implements I3DEngine {\r\n private THREE: any;\r\n private loaders: Record<string, any>;\r\n\r\n constructor(THREE: any, loaders: Record<string, any> = {}) {\r\n this.THREE = THREE;\r\n this.loaders = loaders;\r\n }\r\n\r\n createVector3(x = 0, y = 0, z = 0): I3DVector3 {\r\n return new this.THREE.Vector3(x, y, z);\r\n }\r\n\r\n createVector2(x = 0, y = 0): I3DVector2 {\r\n return new this.THREE.Vector2(x, y);\r\n }\r\n\r\n createQuaternion(x = 0, y = 0, z = 0, w = 1): I3DQuaternion {\r\n return new this.THREE.Quaternion(x, y, z, w);\r\n }\r\n\r\n createEuler(x = 0, y = 0, z = 0, order = \"XYZ\"): I3DEuler {\r\n return new this.THREE.Euler(x, y, z, order);\r\n }\r\n\r\n createMatrix4(): I3DMatrix4 {\r\n return new this.THREE.Matrix4();\r\n }\r\n\r\n createBox3(min?: I3DVector3, max?: I3DVector3): I3DBox3 {\r\n return new this.THREE.Box3(min, max);\r\n }\r\n\r\n createScene(): I3DScene {\r\n return new this.THREE.Scene();\r\n }\r\n\r\n createRenderer(options?: {\r\n antialias?: boolean;\r\n alpha?: boolean;\r\n logarithmicDepthBuffer?: boolean;\r\n }): I3DRenderer {\r\n const renderer = new this.THREE.WebGLRenderer(options);\r\n renderer.outputEncoding = this.THREE.sRGBEncoding;\r\n return renderer;\r\n }\r\n\r\n createPerspectiveCamera(fov = 45, aspect = 1, near = 0.1, far = 2000): I3DPerspectiveCamera {\r\n return new this.THREE.PerspectiveCamera(fov, aspect, near, far);\r\n }\r\n\r\n createOrthographicCamera(\r\n left: number,\r\n right: number,\r\n top: number,\r\n bottom: number,\r\n near = 0.1,\r\n far = 10000\r\n ): I3DOrthographicCamera {\r\n return new this.THREE.OrthographicCamera(left, right, top, bottom, near, far);\r\n }\r\n\r\n createGroup(): I3DObject {\r\n return new this.THREE.Group();\r\n }\r\n\r\n createMesh(geometry: I3DGeometry, material: I3DMaterial): I3DMesh {\r\n return new this.THREE.Mesh(geometry, material);\r\n }\r\n\r\n createBoxGeometry(width: number, height: number, depth: number): I3DGeometry {\r\n return new this.THREE.BoxGeometry(width, height, depth);\r\n }\r\n\r\n createSphereGeometry(radius: number, widthSegments = 32, heightSegments = 32): I3DGeometry {\r\n return new this.THREE.SphereGeometry(radius, widthSegments, heightSegments);\r\n }\r\n\r\n createPlaneGeometry(width: number, height: number): I3DGeometry {\r\n return new this.THREE.PlaneGeometry(width, height);\r\n }\r\n\r\n createCylinderGeometry(\r\n radiusTop: number,\r\n radiusBottom: number,\r\n height: number,\r\n segments = 32\r\n ): I3DGeometry {\r\n return new this.THREE.CylinderGeometry(radiusTop, radiusBottom, height, segments);\r\n }\r\n\r\n createMeshBasicMaterial(params?: any): I3DMaterial {\r\n return new this.THREE.MeshBasicMaterial(params);\r\n }\r\n\r\n createMeshStandardMaterial(params?: any): I3DMaterial {\r\n return new this.THREE.MeshStandardMaterial(params);\r\n }\r\n\r\n createPointLight(color?: string | number, intensity = 1, distance = 0, decay = 2): I3DLight {\r\n return new this.THREE.PointLight(color, intensity, distance, decay);\r\n }\r\n\r\n createAmbientLight(color?: string | number, intensity = 1): I3DLight {\r\n return new this.THREE.AmbientLight(color, intensity);\r\n }\r\n\r\n createDirectionalLight(color?: string | number, intensity = 1): I3DLight {\r\n return new this.THREE.DirectionalLight(color, intensity);\r\n }\r\n\r\n createTextureLoader(): I3DTextureLoader {\r\n return new this.THREE.TextureLoader();\r\n }\r\n\r\n createModelLoader(type: string): I3DModelLoader {\r\n const LoaderClass = this.loaders[type];\r\n if (!LoaderClass) {\r\n throw new Error(`[ThreeJSEngine] Model loader \"${type}\" not registered`);\r\n }\r\n return new LoaderClass();\r\n }\r\n\r\n degToRad(degrees: number): number {\r\n return this.THREE.MathUtils.degToRad(degrees);\r\n }\r\n\r\n radToDeg(radians: number): number {\r\n return this.THREE.MathUtils.radToDeg(radians);\r\n }\r\n\r\n computeBoundingBoxRecursively(object: I3DObject): I3DBox3 {\r\n const boundingBox = new this.THREE.Box3();\r\n let hasBox = false;\r\n\r\n if (object.traverse) {\r\n object.traverse((child: any) => {\r\n if (!child.visible) return;\r\n if (child.geometry) {\r\n if (typeof child.geometry.computeBoundingBox === \"function\") {\r\n child.geometry.computeBoundingBox();\r\n }\r\n const box = child.geometry.boundingBox;\r\n if (box) {\r\n const childBox = box.clone().applyMatrix4(child.matrixWorld);\r\n boundingBox.union(childBox);\r\n hasBox = true;\r\n }\r\n }\r\n });\r\n }\r\n\r\n return hasBox ? boundingBox : new this.THREE.Box3();\r\n }\r\n}\r\n\r\nexport class ThreeJSProvider implements I3DEngineProvider {\r\n private engine: ThreeJSEngine;\r\n\r\n constructor(THREE: any, loaders: Record<string, any> = {}) {\r\n this.engine = new ThreeJSEngine(THREE, loaders);\r\n }\r\n\r\n getEngine(): I3DEngine {\r\n return this.engine;\r\n }\r\n\r\n getName(): string {\r\n return \"Three.js\";\r\n }\r\n}\r\n"],"mappings":"yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,cAAAE,EAAA,mBAAAC,EAAA,mBAAAC,EAAA,qBAAAC,EAAA,kBAAAC,EAAA,yBAAAC,EAAA,kBAAAC,EAAA,oBAAAC,IAAA,eAAAC,EAAAV,GCAA,IAAAW,EAA6B,uCCItB,IAAMC,EAAN,KAAqB,CAU1B,YACEC,EACAC,EAAmB,eACnBC,EAAM,GACNC,EAAO,GACPC,EAAM,IACN,CAfF,KAAQ,WAAa,IAAI,IAGzB,KAAQ,OAAS,EACjB,KAAQ,QAAU,EAYhB,KAAK,OAASJ,EACd,KAAK,KAAOC,EACZ,KAAK,eAAiBC,EAElBD,IAAS,eACX,KAAK,QAAUD,EAAO,yBAAyB,GAAI,EAAG,EAAG,GAAIG,EAAMC,CAAG,EAEtE,KAAK,QAAUJ,EAAO,wBAAwBE,EAAK,EAAGC,EAAMC,CAAG,EAGjE,KAAK,UAAYJ,EAAO,cAAc,EAAG,EAAG,GAAI,EAChD,KAAK,OAAO,CACd,CAEA,IAAW,QAAoB,CAC7B,OAAO,KAAK,OACd,CAEO,OAAOK,EAAeC,EAAsB,CAIjD,GAHA,KAAK,OAASD,EACd,KAAK,QAAUC,EAEX,KAAK,OAAS,eAAgB,CAChC,IAAMC,EAAQ,KAAK,QACnBA,EAAM,KAAO,CAACF,EAAQ,EACtBE,EAAM,MAAQF,EAAQ,EACtBE,EAAM,IAAMD,EAAS,EACrBC,EAAM,OAAS,CAACD,EAAS,CAC3B,MACE,KAAK,QAAQ,OAASD,EAAQC,EAGhC,KAAK,OAAO,CACd,CAEO,YAAYE,EAAWC,EAAWC,EAAiB,CACxD,KAAK,UAAU,IAAIF,EAAGC,EAAGC,CAAC,EAC1B,KAAK,QAAQ,SAAS,KAAK,KAAK,SAAS,EACzC,KAAK,OAAO,CACd,CAEO,OAAOF,EAAWC,EAAWC,EAAiB,CACnD,KAAK,QAAQ,OAAOF,EAAGC,EAAGC,CAAC,EAC3B,KAAK,OAAO,CACd,CAEO,QAAe,CACpB,KAAK,QAAQ,uBAAuB,EACnC,KAAK,QAAgB,oBAAoB,CAC5C,CAEO,cAAcC,EAAiBC,EAAiBF,EAAI,EAAe,CACxE,GAAI,KAAK,OAAS,eAAgB,CAChC,IAAMF,EAAIG,EAAU,KAAK,OAAS,EAC5BF,EAAI,EAAEG,EAAU,KAAK,QAAU,GACrC,OAAO,KAAK,OAAO,cAAcJ,EAAGC,EAAGC,CAAC,CAC1C,KAAO,CACL,GAAM,CAAE,MAAAL,EAAO,OAAAC,CAAO,EAAI,KAAK,iBAAiBI,CAAC,EAC3CG,EAAcF,EAAU,KAAK,OAC7BG,EAAcF,EAAU,KAAK,QAC7BJ,GAAKK,EAAc,IAAOR,EAC1BI,EAAI,EAAEK,EAAc,IAAOR,EACjC,OAAO,KAAK,OAAO,cAAcE,EAAGC,EAAGC,CAAC,CAC1C,CACF,CAEO,iBAAiBA,EAA8C,CACpE,GAAI,KAAK,OAAS,eAChB,MAAO,CAAE,MAAO,KAAK,OAAQ,OAAQ,KAAK,OAAQ,EAGpD,IAAMR,EAAM,KAAK,OAAO,SAAS,KAAK,cAAc,EAC9Ca,EAAW,KAAK,IAAIL,EAAI,KAAK,QAAQ,SAAS,CAAC,EAC/CJ,EAAS,EAAI,KAAK,IAAIJ,EAAM,CAAC,EAAIa,EAEvC,MAAO,CAAE,MADKT,EAAS,KAAK,QAAQ,OACpB,OAAAA,CAAO,CACzB,CAEO,YAAYI,EAAWM,EAAgC,CAC5D,GAAI,KAAK,OAAS,eAChB,MAAO,GAGT,IAAMC,EAAW,KAAK,MAAMP,EAAI,GAAI,EAAI,IACxC,GAAI,KAAK,WAAW,IAAIO,CAAQ,EAC9B,OAAO,KAAK,WAAW,IAAIA,CAAQ,EAGrC,GAAM,CAAE,OAAAX,CAAO,EAAI,KAAK,iBAAiBI,CAAC,EACpCQ,EAAQZ,EAASU,EACvB,YAAK,WAAW,IAAIC,EAAUC,CAAK,EAC5BA,CACT,CAEO,iBAAwB,CAC7B,KAAK,WAAW,MAAM,CACxB,CAEO,SAAsB,CAC3B,OAAO,KAAK,IACd,CACF,ECtHO,IAAMC,EAAN,KAAuB,CAO5B,YAAYC,EAAwBC,EAAmB,CACrD,KAAK,OAASA,EACd,KAAK,WAAaD,EAClB,GAAM,CAAE,MAAAE,EAAO,OAAAC,CAAO,EAAIH,EAAU,sBAAsB,EAC1D,KAAK,OAASE,EACd,KAAK,QAAUC,EAEf,KAAK,UAAYF,EAAO,eAAe,CACrC,UAAW,GACX,MAAO,GACP,uBAAwB,EAC1B,CAAC,EACD,KAAK,UAAU,cAAc,OAAO,gBAAgB,EACpD,KAAK,UAAU,QAAQC,EAAOC,CAAM,CACtC,CAEO,QAAe,CACpB,KAAK,WAAW,YAAY,KAAK,UAAU,UAAU,CACvD,CAEO,OAAOC,EAAsBC,EAA8B,CAChE,KAAK,UAAU,OAAOD,EAAM,SAAS,EAAGC,EAAO,MAAM,CACvD,CAEO,OAAOA,EAA8B,CAC1C,GAAM,CAAE,MAAAH,EAAO,OAAAC,CAAO,EAAI,KAAK,WAAW,sBAAsB,EAChE,KAAK,OAASD,EACd,KAAK,QAAUC,EACf,KAAK,UAAU,QAAQD,EAAOC,CAAM,EACpCE,EAAO,OAAOH,EAAOC,CAAM,CAC7B,CAEA,IAAW,OAAgB,CACzB,OAAO,KAAK,MACd,CAEA,IAAW,QAAiB,CAC1B,OAAO,KAAK,OACd,CAEA,IAAW,UAAwB,CACjC,OAAO,KAAK,SACd,CAEO,SAAgB,CACrB,KAAK,UAAU,QAAQ,CACzB,CACF,EC9CO,IAAMG,EAAN,KAAqB,CAoB1B,YAAYC,EAAYC,EAAcC,EAAmBC,EAAmB,CAb5E,KAAQ,UAA4C,CAAC,EAMrD,KAAQ,UAA8B,CAAC,EAQrC,KAAK,GAAKH,EACV,KAAK,KAAOC,EACZ,KAAK,QAAUC,EACf,KAAK,OAASC,EACd,KAAK,YAAcA,EAAO,iBAAiB,EAC3C,KAAK,cAAgBA,EAAO,cAAc,EAC1C,KAAK,MAAQA,EAAO,WAAW,EAC/B,KAAK,kBAAkB,CACzB,CAbA,IAAW,UAA6B,CACtC,OAAO,KAAK,SACd,CAaA,IAAW,QAAoB,CAC7B,OAAO,KAAK,OACd,CAEA,IAAW,UAAoC,CAC7C,OAAO,KAAK,SACd,CAEA,IAAW,cAA2B,CACpC,OAAO,KAAK,cAAc,MAAM,CAClC,CAEA,IAAW,aAAuB,CAChC,OAAO,KAAK,MAAM,MAAM,CAC1B,CAEO,SAASC,EAA6B,CAC3C,KAAK,UAAU,KAAKA,CAAK,EACzB,KAAK,OAAO,IAAIA,EAAM,MAAM,CAC9B,CAEO,gBAA6B,CAClC,OAAO,KAAK,QAAQ,YAAY,MAAM,CACxC,CAEO,kBAA+B,CACpC,OAAO,KAAK,OAAO,cAAc,EAAE,sBAAsB,KAAK,QAAQ,WAAW,CACnF,CAEO,wBAAkC,CACvC,GAAI,CAAC,KAAK,qBAAsB,CAC9B,IAAMC,EAAgB,KAAK,OAAO,MAAM,MAAM,EAC9C,KAAK,OAAO,MAAM,IAAI,EAAG,EAAG,CAAC,EAC7B,KAAK,OAAO,kBAAkB,EAAI,EAClC,KAAK,qBAAuB,KAAK,OAAO,8BAA8B,KAAK,MAAM,EACjF,KAAK,OAAO,MAAM,KAAKA,CAAa,EACpC,KAAK,OAAO,kBAAkB,EAAI,CACpC,CACA,OAAO,KAAK,qBAAsB,MAAM,CAC1C,CAEO,wBAAwBC,EAA0B,CACvD,IAAMC,EAAM,KAAK,OAAO,cAAc,EAChCC,EAAO,KAAK,OAAO,iBAAiB,EACpCC,EAAQ,KAAK,OAAO,cAAc,EACxCH,EAAO,UAAUC,EAAKC,EAAMC,CAAK,EACjC,KAAK,QAAQ,SAAS,KAAKF,CAAG,EAC9B,KAAK,QAAQ,WAAW,KAAKC,CAAI,EACjC,KAAK,QAAQ,MAAM,KAAKC,CAAK,EAC7B,KAAK,QAAQ,aAAa,EAC1B,KAAK,QAAQ,kBAAkB,CACjC,CAEO,oBACLC,EACAC,EACAF,EACM,CACN,KAAK,QAAQ,SAAS,KAAKC,CAAQ,EACnC,KAAK,QAAQ,WAAW,KAAKC,CAAU,EACvC,KAAK,QAAQ,MAAM,KAAKF,CAAK,EAC7B,KAAK,QAAQ,aAAa,EAC1B,KAAK,QAAQ,kBAAkB,CACjC,CAEA,IAAW,WAAWE,EAA2B,CAC/C,KAAK,YAAY,KAAKA,CAAU,EAChC,KAAK,QAAQ,WAAW,KAAK,KAAK,WAAW,EAC7C,KAAK,QAAQ,kBAAkB,CACjC,CAEA,IAAW,SAASD,EAAsB,CACxC,KAAK,QAAQ,SAAS,KAAKA,CAAQ,CACrC,CAEA,IAAW,MAAMD,EAAmB,CAClC,KAAK,QAAQ,MAAM,KAAKA,CAAK,CAC/B,CAEA,IAAW,SAASG,EAAiB,CACnC,KAAK,QAAQ,SAAS,KAAKA,CAAK,CAClC,CAEA,IAAW,QAAQC,EAAe,CAChC,IAAMC,EAAM,KAAK,QACbA,EAAI,UAAY,YAAaA,EAAI,WACnCA,EAAI,SAAS,QAAUD,EAE3B,CAEA,IAAW,UAAUA,EAAe,CAClC,IAAMC,EAAM,KAAK,QACbA,EAAI,UAAY,cAAeA,EAAI,WACrCA,EAAI,SAAS,UAAYD,EAE7B,CAEA,IAAW,UAAUA,EAAe,CAClC,IAAMC,EAAM,KAAK,QACbA,EAAI,UAAY,cAAeA,EAAI,WACrCA,EAAI,SAAS,UAAYD,EAE7B,CAEA,IAAW,QAAQE,EAAc,CAC/B,KAAK,SAAWA,EACX,KAAK,QAAgB,QAAUA,GAAS,cAC3CA,EAAQ,aAAa,KAAK,OAAO,CAErC,CAEO,mBAA0B,CAC/B,KAAK,MAAM,cAAc,KAAK,OAAO,EACrC,KAAK,MAAM,QAAQ,KAAK,aAAa,CACvC,CAEO,SAAgB,CACrB,KAAK,UAAU,UAAU,EACzB,KAAK,WAAW,QAAQ,EACxB,KAAK,WAAW,QAAQ,CAC1B,CACF,EChKO,IAAMC,EAAN,KAAoB,CAYzB,YAAYC,EAAmBC,EAAmB,CAVlD,KAAQ,SAAwC,IAAI,IACpD,KAAQ,aAAiC,CAAC,EAC1C,KAAQ,YAAwC,IAAI,IASlD,KAAK,OAASD,EACd,KAAK,aAAeC,EACpB,KAAK,OAASD,EAAO,YAAY,CACnC,CARA,IAAW,aAAgC,CACzC,OAAO,KAAK,YACd,CAQO,UAAqB,CAC1B,OAAO,KAAK,MACd,CAEO,UAAUE,EAAwC,CACvD,OAAO,KAAK,SAAS,IAAIA,CAAE,CAC7B,CAEO,UAAUA,EAAqB,CACpC,OAAO,KAAK,SAAS,IAAIA,CAAE,CAC7B,CAEO,aAAaA,EAAqB,CACvC,IAAMC,EAAM,KAAK,SAAS,IAAID,CAAE,EAChC,OAAIC,GACF,KAAK,OAAO,OAAOA,EAAI,MAAM,EAC7B,KAAK,SAAS,OAAOD,CAAE,EACvBC,EAAI,QAAQ,EACL,IAEF,EACT,CAEO,kBAAkBC,EAA4B,CACnD,IAAMC,EAAOD,EAAO,YAAoB,IAAI,EAC5C,GAAI,CAACC,EAAM,OAEX,IAAMC,EAAUF,EAAO,YACvB,GAAI,CAACE,EAAS,OAEd,IAAMC,EAASC,GAAkC,CAC/C,GAAIA,EAAe,CACjB,IAAMC,EAAWL,EAAO,YAAoB,UAAU,EAClDK,GAAY,MACd,KAAK,OAAO,IAAID,EAAc,MAAM,EACpC,KAAK,aAAa,KAAKA,CAAa,GAEpC,KAAK,SAAS,IAAIC,CAAQ,GAAG,SAASD,CAAa,EAErD,KAAK,SAAS,IAAIJ,EAAO,GAAII,CAAa,EAC1C,KAAK,YAAY,IAAIJ,EAAO,GAAIE,CAAO,EACvCE,EAAc,GAAKF,CACrB,CACF,EAEA,OAAQD,EAAM,CACZ,IAAK,QACH,KAAK,YAAYD,EAAQG,CAAK,EAC9B,MACF,IAAK,aACH,KAAK,YAAYH,EAAQ,QAASG,CAAK,EACvC,MACF,IAAK,eACH,KAAK,YAAYH,EAAQ,UAAWG,CAAK,EACzC,MACF,IAAK,mBACH,KAAK,YAAYH,EAAQ,cAAeG,CAAK,EAC7C,MACF,IAAK,QACH,KAAK,YAAYH,EAAQG,CAAK,EAC9B,MACF,IAAK,MACH,KAAK,UAAUH,EAAQG,CAAK,EAC5B,MACF,IAAK,SACH,KAAK,aAAaH,EAAQG,CAAK,EAC/B,MACF,IAAK,QACH,KAAK,YAAYH,EAAQG,CAAK,EAC9B,MACF,IAAK,WACH,KAAK,eAAeH,EAAQG,CAAK,EACjC,KACJ,CACF,CAEQ,YAAYH,EAAsBG,EAAsD,CAC9F,IAAMG,EAAQ,KAAK,OAAO,YAAY,EAChCP,EAAM,IAAIQ,EAAeP,EAAO,GAAI,QAASM,EAAO,KAAK,MAAM,EACrE,OAAAH,EAAMJ,CAAG,EACFA,CACT,CAEQ,YACNC,EACAQ,EACAL,EACgB,CAChB,IAAMM,EAAQT,EAAO,YAAoB,UAAU,GAAK,UAClDU,EAAYV,EAAO,YAAoB,cAAc,GAAK,EAE5DW,EACJ,GAAIH,IAAS,QAAS,CACpB,IAAMI,EAAWZ,EAAO,YAAoB,aAAa,GAAK,IACxDa,EAAQb,EAAO,YAAoB,UAAU,GAAK,EACxDW,EAAQ,KAAK,OAAO,iBAAiBF,EAAOC,EAAWE,EAAUC,CAAK,CACxE,MAAWL,IAAS,cAClBG,EAAQ,KAAK,OAAO,uBAAuBF,EAAOC,CAAS,EAE3DC,EAAQ,KAAK,OAAO,mBAAmBF,EAAOC,CAAS,EAGzD,IAAMX,EAAM,IAAIQ,EAAeP,EAAO,GAAIQ,EAAO,QAASG,EAAO,KAAK,MAAM,EAC5E,OAAAR,EAAMJ,CAAG,EACFA,CACT,CAEQ,UAAUC,EAAsBG,EAAsD,CAC5F,IAAMW,EAAW,KAAK,OAAO,kBAAkB,EAAG,EAAG,CAAC,EAChDC,EAAW,KAAK,yBAAyBf,CAAM,EAC/CgB,EAAO,KAAK,OAAO,WAAWF,EAAUC,CAAQ,EAChDhB,EAAM,IAAIQ,EAAeP,EAAO,GAAI,MAAOgB,EAAM,KAAK,MAAM,EAClE,OAAAb,EAAMJ,CAAG,EACFA,CACT,CAEQ,aAAaC,EAAsBG,EAAsD,CAC/F,IAAMc,EAAgBjB,EAAO,YAAoB,mBAAmB,GAAK,GACnEkB,EAAiBlB,EAAO,YAAoB,oBAAoB,GAAK,GACrEc,EAAW,KAAK,OAAO,qBAAqB,GAAKG,EAAeC,CAAc,EAC9EH,EAAW,KAAK,yBAAyBf,CAAM,EAC/CgB,EAAO,KAAK,OAAO,WAAWF,EAAUC,CAAQ,EAChDhB,EAAM,IAAIQ,EAAeP,EAAO,GAAI,SAAUgB,EAAM,KAAK,MAAM,EACrE,OAAAb,EAAMJ,CAAG,EACFA,CACT,CAEQ,YAAYC,EAAsBG,EAAsD,CAC9F,IAAMW,EAAW,KAAK,OAAO,oBAAoB,EAAG,CAAC,EAC/CC,EAAW,KAAK,yBAAyBf,CAAM,EAC/CgB,EAAO,KAAK,OAAO,WAAWF,EAAUC,CAAQ,EAChDhB,EAAM,IAAIQ,EAAeP,EAAO,GAAI,QAASgB,EAAM,KAAK,MAAM,EACpE,OAAAb,EAAMJ,CAAG,EACFA,CACT,CAEQ,eACNC,EACAG,EACgB,CAChB,IAAMgB,EAAWnB,EAAO,YAAoB,aAAa,GAAK,GACxDc,EAAW,KAAK,OAAO,uBAAuB,GAAK,GAAK,EAAGK,CAAQ,EACnEJ,EAAW,KAAK,yBAAyBf,CAAM,EAC/CgB,EAAO,KAAK,OAAO,WAAWF,EAAUC,CAAQ,EAChDhB,EAAM,IAAIQ,EAAeP,EAAO,GAAI,WAAYgB,EAAM,KAAK,MAAM,EACvE,OAAAb,EAAMJ,CAAG,EACFA,CACT,CAEQ,YAAYC,EAAsBG,EAA4C,CACpF,GAAI,CAAC,KAAK,aAAc,CACtB,QAAQ,KAAK,wCAAwC,EACrD,MACF,CAEA,IAAMiB,EAAYpB,EAAO,YAAoB,UAAU,EACvD,GAAI,CAACoB,EAAW,OAEhB,IAAML,EAAW,KAAK,yBAAyBf,CAAM,EAEtC,KAAK,aACb,KACLoB,EACCC,GAAc,CACb,IAAMC,EAAYD,EAAK,MACvBC,EAAU,SAAUC,GAAe,CAC7BA,EAAM,SACRA,EAAM,SAAWR,EAErB,CAAC,EACD,IAAMhB,EAAM,IAAIQ,EAAeP,EAAO,GAAI,QAASsB,EAAW,KAAK,MAAM,EACzEnB,EAAMJ,CAAG,CACX,EACCyB,GAAa,CACZ,QAAQ,IAAKA,EAAI,OAASA,EAAI,MAAS,IAAM,UAAU,CACzD,EACCC,GAAe,CACd,QAAQ,MAAM,kCAAmCA,CAAK,CACxD,CACF,CACF,CAEQ,yBAAyBzB,EAAmC,CAClE,IAAM0B,EAAO1B,EAAO,YAAoB,aAAa,GAAK,iBACpD,CAACC,EAAM0B,CAAQ,EAAID,EAAK,MAAM,OAAO,EACrCjB,EAAQkB,GAAY,UACpBC,EAAU5B,EAAO,YAAoB,YAAY,GAAK,EACtD6B,EAAc,CAClB,MAAApB,EACA,YAAamB,EAAU,EACvB,QAASA,CACX,EAEME,EAAM9B,EAAe,GACrB+B,EAASD,GAAI,aAAa,eAAe,EACzCE,EAAeF,GAAI,aAAa,qBAAqB,EACrDG,EAAkBH,GAAI,aAAa,wBAAwB,EAC3DI,EAAWJ,GAAI,aAAa,iBAAiB,EAEnD,OAAI7B,IAAS,YACP8B,IAAQF,EAAO,IAAM,KAAK,YAAYE,CAAM,GAC5CC,IAAcH,EAAO,UAAY,KAAK,YAAYG,CAAY,GAC9DC,IAAiBJ,EAAO,aAAe,KAAK,YAAYI,CAAe,GACvEC,IAAUL,EAAO,MAAQ,KAAK,YAAYK,CAAQ,GAC/C,KAAK,OAAO,2BAA2BL,CAAM,GAG/C,KAAK,OAAO,wBAAwBA,CAAM,CACnD,CAEQ,YAAYM,EAAkB,CAEpC,OADsB,KAAK,OAAO,oBAAoB,EACjC,KAAKA,CAAG,CAC/B,CAEO,SAAgB,CACrB,KAAK,SAAS,QAASpC,GAAQA,EAAI,QAAQ,CAAC,EAC5C,KAAK,SAAS,MAAM,EACpB,KAAK,aAAe,CAAC,CACvB,CACF,EC9OO,IAAMqC,EAAN,KAA8D,CACnE,KAAKC,EAAiBC,EAAwBC,EAAkBC,EAAsB,CACpF,IAAMC,EAAOJ,EAAG,sBAAsB,EAChCK,EAAUD,EAAK,KAAOA,EAAK,MAAQ,EACnCE,EAAUF,EAAK,IAAMA,EAAK,OAAS,EAEnCG,EAAQ,iBAAiBP,CAAE,EAC3BQ,EAAa,WAAWD,EAAM,iBAAiB,eAAe,GAAK,GAAG,EACtEE,EAAWP,EAAI,OAAO,cAAcG,EAASC,EAASE,CAAU,EACtEP,EAAO,SAAWQ,EAElB,IAAMC,EAAQ,WAAWH,EAAM,iBAAiB,SAAS,CAAC,GAAK,EAC/DN,EAAO,MAAQC,EAAI,OAAO,cAAcQ,EAAOA,EAAOA,CAAK,EAE3D,IAAMC,EAAU,CAACT,EAAI,OAAO,SAAS,WAAWK,EAAM,iBAAiB,YAAY,GAAK,GAAG,CAAC,EACtFK,EAAUV,EAAI,OAAO,SAAS,WAAWK,EAAM,iBAAiB,YAAY,GAAK,GAAG,CAAC,EACrFM,EAAU,CAACX,EAAI,OAAO,SAAS,WAAWK,EAAM,iBAAiB,YAAY,GAAK,GAAG,CAAC,EAC5F,OAAAN,EAAO,SAAWC,EAAI,OAAO,YAAYS,EAASC,EAASC,EAAS,KAAK,EAEzEZ,EAAO,OAAO,kBAAkB,EAAI,EAE7B,CAAE,MAAAS,CAAM,CACjB,CACF,ECvBO,IAAMI,EAAN,KAA8D,CACnE,KAAKC,EAAiBC,EAAwBC,EAAkBC,EAAsB,CACpF,IAAMC,EAAOJ,EAAG,sBAAsB,EAChCK,EAAUD,EAAK,KAAOA,EAAK,MAAQ,EACnCE,EAAUF,EAAK,IAAMA,EAAK,OAAS,EAEnCG,EAAa,WAAW,iBAAiBP,CAAE,EAAE,iBAAiB,eAAe,GAAK,GAAG,EACrFQ,EAAWN,EAAI,OAAO,cAAcG,EAASC,EAASC,CAAU,EACtE,OAAAN,EAAO,SAAWO,EAEX,IACT,CACF,ECZO,IAAMC,EAAN,KAA6D,CAClE,KAAKC,EAAiBC,EAAwBC,EAAkBC,EAAsB,CACpF,IAAMC,EAAQ,iBAAiBJ,CAAE,EAE3BK,EAAgBL,EAAG,YACnBM,EAAiBN,EAAG,aACpBO,EAAOP,EAAG,sBAAsB,EAEhCQ,EAAa,WAAWJ,EAAM,iBAAiB,eAAe,GAAK,GAAG,EACtEK,EAAW,WAAWL,EAAM,iBAAiB,SAAS,GAAK,GAAG,EAE9DM,EAAUH,EAAK,KAAOA,EAAK,MAAQ,EACnCI,EAAUJ,EAAK,IAAMA,EAAK,OAAS,EAEnCK,EAAWV,EAAI,OAAO,cAAcQ,EAASC,EAASH,CAAU,EACtEP,EAAO,SAAWW,EAElB,IAAMC,EAAU,CAACX,EAAI,OAAO,SAAS,WAAWE,EAAM,iBAAiB,YAAY,GAAK,GAAG,CAAC,EACtFU,EAAUZ,EAAI,OAAO,SAAS,WAAWE,EAAM,iBAAiB,YAAY,GAAK,GAAG,CAAC,EACrFW,EAAU,CAACb,EAAI,OAAO,SAAS,WAAWE,EAAM,iBAAiB,YAAY,GAAK,GAAG,CAAC,EAC5FH,EAAO,SAAWC,EAAI,OAAO,YAAYW,EAASC,EAASC,EAAS,KAAK,EAEzE,IAAMC,EAAcX,EAAgBI,EAC9BQ,EAAeX,EAAiBG,EAChCS,EAAY,WAAWd,EAAM,iBAAiB,WAAW,GAAK,GAAG,EACjEe,EAAchB,GAAY,OAAS,EAEnCiB,EAAanB,EAAO,KACtBoB,EAAgBC,EAAgBC,EAEpC,OAAQH,EAAY,CAClB,IAAK,MACL,IAAK,SAAU,CACb,IAAMI,EAAc,KAAK,IAAIR,EAAaC,CAAY,EACtDI,EAASG,EAAcL,EACvBG,EAASE,EAAcL,EACvBI,EAASC,EAAcN,EAAYC,EACnC,KACF,CACA,IAAK,WAAY,CACf,IAAMM,EAAYT,EAClBK,EAASI,EAAYN,EACrBG,EAASL,EAAeE,EACxBI,EAASE,EAAYP,EAAYC,EACjC,KACF,CACA,IAAK,QACL,QACEE,EAASL,EAAcG,EACvBG,EAASL,EAAeE,EACxBI,EAAS,KAAK,IAAIP,EAAaC,CAAY,EAAI,GAAMC,EAAYC,EACjE,KACJ,CAEA,OAAAlB,EAAO,MAAQC,EAAI,OAAO,cAAcmB,EAAQC,EAAQC,CAAM,EAEvD,CAAE,MAAOd,EAAWU,CAAY,CACzC,CACF,ECtDO,IAAMO,EAAN,KAA2B,CAGhC,YACSC,EACAC,EACAC,EACAC,EACP,CAJO,YAAAH,EACA,mBAAAC,EACA,oBAAAC,EACA,YAAAC,EANT,KAAQ,WAAsD,IAAI,IAQhE,KAAK,WAAW,IAAI,MAAO,IAAIC,CAAkB,EACjD,KAAK,WAAW,IAAI,SAAU,IAAIA,CAAkB,EACpD,KAAK,WAAW,IAAI,QAAS,IAAIA,CAAkB,EACnD,KAAK,WAAW,IAAI,WAAY,IAAIA,CAAkB,EACtD,KAAK,WAAW,IAAI,QAAS,IAAIA,CAAkB,EACnD,KAAK,WAAW,IAAI,QAAS,IAAIC,CAAmB,EACpD,KAAK,WAAW,IAAI,aAAc,IAAIC,CAAmB,EACzD,KAAK,WAAW,IAAI,eAAgB,IAAIA,CAAmB,EAC3D,KAAK,WAAW,IAAI,mBAAoB,IAAIA,CAAmB,CACjE,CAEO,YAAYC,EAAiBC,EAAwBC,EAAsB,CAChF,IAAMC,EAAW,KAAK,WAAW,IAAIF,EAAO,IAAI,EAChD,OAAKE,EAKEA,EAAS,KACdH,EACAC,EACA,CACE,OAAQ,KAAK,OACb,cAAe,KAAK,cACpB,eAAgB,KAAK,eACrB,OAAQ,KAAK,MACf,EACAC,CACF,GAdE,QAAQ,KAAK,yCAAyCD,EAAO,IAAI,GAAG,EAC7D,KAcX,CAEO,mBAAmBG,EAAeC,EAAsB,CAC7D,KAAK,cAAgBD,EACrB,KAAK,eAAiBC,CACxB,CACF,ER1CA,IAAAC,EAAyB,uCAQZC,EAAN,MAAMA,UAAiB,cAAa,CAgBzC,YAAYC,EAAwBC,EAA2B,CAAC,EAAG,CACjE,MAAMD,CAAO,EAdf,KAAQ,SAAoC,KAC5C,KAAQ,OAAgC,KACxC,KAAQ,MAA8B,KACtC,KAAQ,aAA4C,KACpD,KAAQ,OAA2B,KACnC,KAAQ,gBAAsC,KAC9C,KAAQ,UAAkC,IAAI,IAS5C,KAAK,QAAU,KACf,KAAK,QAAU,CACb,SAAUC,EAAQ,UAAY,GAC9B,UAAWA,EAAQ,UACnB,OAAQA,EAAQ,QAAU,CAC5B,EAEA,KAAK,gBAAkB,CACrB,GAAG,KAAK,gBACR,CAAE,IAAK,KAAM,KAAM,SAAU,SAAU,KAAM,EAC7C,CAAE,IAAK,cAAe,KAAM,SAAU,SAAU,gBAAiB,EACjE,CAAE,IAAK,WAAY,KAAM,SAAU,SAAU,SAAU,EACvD,CAAE,IAAK,aAAc,KAAM,SAAU,SAAU,CAAE,EACjD,CAAE,IAAK,eAAgB,KAAM,SAAU,SAAU,CAAE,EACnD,CAAE,IAAK,cAAe,KAAM,SAAU,SAAU,GAAK,EACrD,CAAE,IAAK,WAAY,KAAM,SAAU,SAAU,CAAE,EAC/C,CAAE,IAAK,WAAY,KAAM,SAAU,SAAU,EAAG,EAChD,CAAE,IAAK,cAAe,KAAM,SAAU,SAAU,EAAG,EACnD,CAAE,IAAK,oBAAqB,KAAM,SAAU,SAAU,EAAG,EACzD,CAAE,IAAK,qBAAsB,KAAM,SAAU,SAAU,EAAG,CAC5D,CACF,CA3BA,OAAc,YAAYC,EAAmC,CAC3DH,EAAS,SAAWG,CACtB,CA2BS,WAAWC,EAA+B,CACjD,IAAMC,EAAS,MAAM,WAAWD,CAAM,EACtC,eAAQ,IACN,yBACAA,EAAO,GACP,QACAA,EAAO,KACP,WACA,KAAK,QACL,UACAC,CACF,EACOA,CACT,CAES,iBACPC,EACAF,EACAG,EACAC,EACM,CACN,MAAM,iBAAiBF,EAAUF,EAAQG,EAASC,CAAU,EAE5DJ,EAAO,YAAY,WAAY,IAAI,EACnC,IAAMK,EAAgBF,EAAQ,eAAe,QAC3C,qBACF,EACA,GAAIE,EAAe,CACjB,IAAMC,EAAWD,EAAc,aAAa,WAAW,EACnDC,IACFN,EAAO,YAAY,WAAYM,CAAQ,EACvCN,EAAO,YAAY,SAAUK,CAAa,EAE9C,CACF,CAES,UAAiB,CACpB,KAAK,UAAY,KAAK,QAAU,KAAK,eACvC,KAAK,SAAS,OAAO,KAAK,MAAM,EAChC,KAAK,aAAa,mBAAmB,KAAK,SAAS,MAAO,KAAK,SAAS,MAAM,EAC9E,KAAK,OAAO,gBAAgB,EAEhC,CAES,QAAe,CACtB,GAAI,CAACT,EAAS,SAAU,CACtB,QAAQ,MAAM,qEAAqE,EACnF,MACF,CAEA,KAAK,OAASA,EAAS,SAAS,UAAU,EAC1C,KAAK,gBAAkB,KAAK,qBAAqB,EACjD,KAAK,UAAU,EAEf,KAAK,SAAW,IAAIW,EAAiB,KAAK,gBAAiB,KAAK,MAAM,EACtE,KAAK,SAAS,OAAO,EAErB,KAAK,OAAS,IAAIC,EAAe,KAAK,OAAQ,cAAc,EAC5D,KAAK,OAAO,YAAY,EAAG,EAAG,GAAI,EAClC,KAAK,OAAO,OAAO,KAAK,SAAS,MAAO,KAAK,SAAS,MAAM,EAE5D,KAAK,MAAQ,IAAIC,EAAc,KAAK,MAAM,EAC1C,KAAK,MAAM,SAAS,EAAE,IAAI,KAAK,OAAO,MAAM,EAE5C,KAAK,aAAe,IAAIC,EACtB,KAAK,OACL,KAAK,SAAS,MACd,KAAK,SAAS,OACd,KAAK,MACP,EAEA,QAAQ,KAAK,gCAAgCd,EAAS,SAAS,QAAQ,CAAC,EAAE,CAC5E,CAEQ,sBAAoC,CAC1C,GAAI,KAAK,QAAQ,qBAAqB,YACpC,YAAK,qBAAqB,KAAK,QAAQ,SAAS,EACzC,KAAK,QAAQ,UAGtB,GAAI,OAAO,KAAK,QAAQ,WAAc,SAAU,CAC9C,IAAMe,EAAW,SAAS,eAAe,KAAK,QAAQ,SAAS,EAC/D,GAAIA,EACF,YAAK,qBAAqBA,CAAQ,EAC3BA,CAEX,CAEA,IAAMC,EAAY,SAAS,cAAc,KAAK,EAC9C,OAAAA,EAAU,GAAK,mBACf,KAAK,qBAAqBA,CAAS,EACnC,SAAS,KAAK,aAAaA,EAAW,SAAS,KAAK,UAAU,EACvDA,CACT,CAEQ,qBAAqBC,EAAuB,CAClD,OAAO,OAAOA,EAAG,MAAO,CACtB,SAAU,QACV,KAAM,IACN,IAAK,IACL,MAAO,QACP,OAAQ,SACR,OAAQ,OAAO,KAAK,QAAQ,MAAM,EAClC,cAAe,MACjB,CAAC,CACH,CAES,kBAAkBb,EAA4B,CACjD,KAAK,UAAU,IAAIA,EAAO,EAAE,GAAK,CAAC,KAAK,QAC3C,KAAK,UAAU,IAAIA,EAAO,GAAI,EAAI,EAElC,KAAK,MAAM,kBAAkBA,CAAM,EAE/B,KAAK,QAAQ,UAAYA,EAAO,cAClCA,EAAO,YAAY,MAAM,QAAU,IACnCA,EAAO,YAAY,MAAM,cAAgB,QAE7C,CAES,QAAQc,EAAwB,CACnC,CAAC,KAAK,UAAY,CAAC,KAAK,OAAS,CAAC,KAAK,QAAU,CAAC,KAAK,eAE3D,WAAS,QAAQ,IAAM,CACrB,KAAK,MAAO,YAAY,QAASC,GAAQ,CACvC,KAAK,cAAcA,EAAI,GAAIA,EAAK,CAAE,MAAO,CAAE,CAAC,CAC9C,CAAC,CACH,CAAC,EAED,WAAS,OAAO,IAAM,CACpB,KAAK,SAAU,OAAO,KAAK,MAAQ,KAAK,MAAO,CACjD,CAAC,EACH,CAEQ,cAAcF,EAA6Bb,EAAagB,EAAuB,CACrF,GAAI,CAAC,KAAK,cAAgB,CAACH,EAAI,OAC/B,IAAMC,EAAO,KAAK,aAAa,YAAYD,EAAIb,EAAQgB,CAAU,EACjEhB,EAAO,SAAS,QAASiB,GAAe,KAAK,cAAcA,EAAM,GAAIA,EAAOH,CAAI,CAAC,CACnF,CAEQ,WAAkB,CACxB,GAAI,SAAS,eAAe,kBAAkB,EAAG,OAEjD,IAAMI,EAAQ,SAAS,cAAc,OAAO,EAC5CA,EAAM,GAAK,mBACXA,EAAM,YAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MA4BpB,SAAS,KAAK,YAAYA,CAAK,CACjC,CAES,SAAgB,CACvB,KAAK,UAAU,QAAQ,EACvB,KAAK,OAAO,QAAQ,EACpB,KAAK,UAAU,MAAM,EAEL,SAAS,eAAe,kBAAkB,GACjD,OAAO,EAEZ,KAAK,iBAAiB,KAAO,oBAC/B,KAAK,gBAAgB,OAAO,EAG9B,MAAM,QAAQ,CAChB,CACF,EAtOatB,EACI,SAAqC,KAD/C,IAAMuB,EAANvB,ESIA,IAAMwB,EAAN,KAAyC,CAI9C,YAAYC,EAAYC,EAA+B,CAAC,EAAG,CACzD,KAAK,MAAQD,EACb,KAAK,QAAUC,CACjB,CAEA,cAAcC,EAAI,EAAGC,EAAI,EAAGC,EAAI,EAAe,CAC7C,OAAO,IAAI,KAAK,MAAM,QAAQF,EAAGC,EAAGC,CAAC,CACvC,CAEA,cAAcF,EAAI,EAAGC,EAAI,EAAe,CACtC,OAAO,IAAI,KAAK,MAAM,QAAQD,EAAGC,CAAC,CACpC,CAEA,iBAAiBD,EAAI,EAAGC,EAAI,EAAGC,EAAI,EAAGC,EAAI,EAAkB,CAC1D,OAAO,IAAI,KAAK,MAAM,WAAWH,EAAGC,EAAGC,EAAGC,CAAC,CAC7C,CAEA,YAAYH,EAAI,EAAGC,EAAI,EAAGC,EAAI,EAAGE,EAAQ,MAAiB,CACxD,OAAO,IAAI,KAAK,MAAM,MAAMJ,EAAGC,EAAGC,EAAGE,CAAK,CAC5C,CAEA,eAA4B,CAC1B,OAAO,IAAI,KAAK,MAAM,OACxB,CAEA,WAAWC,EAAkBC,EAA2B,CACtD,OAAO,IAAI,KAAK,MAAM,KAAKD,EAAKC,CAAG,CACrC,CAEA,aAAwB,CACtB,OAAO,IAAI,KAAK,MAAM,KACxB,CAEA,eAAeC,EAIC,CACd,IAAMC,EAAW,IAAI,KAAK,MAAM,cAAcD,CAAO,EACrD,OAAAC,EAAS,eAAiB,KAAK,MAAM,aAC9BA,CACT,CAEA,wBAAwBC,EAAM,GAAIC,EAAS,EAAGC,EAAO,GAAKC,EAAM,IAA4B,CAC1F,OAAO,IAAI,KAAK,MAAM,kBAAkBH,EAAKC,EAAQC,EAAMC,CAAG,CAChE,CAEA,yBACEC,EACAC,EACAC,EACAC,EACAL,EAAO,GACPC,EAAM,IACiB,CACvB,OAAO,IAAI,KAAK,MAAM,mBAAmBC,EAAMC,EAAOC,EAAKC,EAAQL,EAAMC,CAAG,CAC9E,CAEA,aAAyB,CACvB,OAAO,IAAI,KAAK,MAAM,KACxB,CAEA,WAAWK,EAAuBC,EAAgC,CAChE,OAAO,IAAI,KAAK,MAAM,KAAKD,EAAUC,CAAQ,CAC/C,CAEA,kBAAkBC,EAAeC,EAAgBC,EAA4B,CAC3E,OAAO,IAAI,KAAK,MAAM,YAAYF,EAAOC,EAAQC,CAAK,CACxD,CAEA,qBAAqBC,EAAgBC,EAAgB,GAAIC,EAAiB,GAAiB,CACzF,OAAO,IAAI,KAAK,MAAM,eAAeF,EAAQC,EAAeC,CAAc,CAC5E,CAEA,oBAAoBL,EAAeC,EAA6B,CAC9D,OAAO,IAAI,KAAK,MAAM,cAAcD,EAAOC,CAAM,CACnD,CAEA,uBACEK,EACAC,EACAN,EACAO,EAAW,GACE,CACb,OAAO,IAAI,KAAK,MAAM,iBAAiBF,EAAWC,EAAcN,EAAQO,CAAQ,CAClF,CAEA,wBAAwBC,EAA2B,CACjD,OAAO,IAAI,KAAK,MAAM,kBAAkBA,CAAM,CAChD,CAEA,2BAA2BA,EAA2B,CACpD,OAAO,IAAI,KAAK,MAAM,qBAAqBA,CAAM,CACnD,CAEA,iBAAiBC,EAAyBC,EAAY,EAAGC,EAAW,EAAGC,EAAQ,EAAa,CAC1F,OAAO,IAAI,KAAK,MAAM,WAAWH,EAAOC,EAAWC,EAAUC,CAAK,CACpE,CAEA,mBAAmBH,EAAyBC,EAAY,EAAa,CACnE,OAAO,IAAI,KAAK,MAAM,aAAaD,EAAOC,CAAS,CACrD,CAEA,uBAAuBD,EAAyBC,EAAY,EAAa,CACvE,OAAO,IAAI,KAAK,MAAM,iBAAiBD,EAAOC,CAAS,CACzD,CAEA,qBAAwC,CACtC,OAAO,IAAI,KAAK,MAAM,aACxB,CAEA,kBAAkBG,EAA8B,CAC9C,IAAMC,EAAc,KAAK,QAAQD,CAAI,EACrC,GAAI,CAACC,EACH,MAAM,IAAI,MAAM,iCAAiCD,CAAI,kBAAkB,EAEzE,OAAO,IAAIC,CACb,CAEA,SAASC,EAAyB,CAChC,OAAO,KAAK,MAAM,UAAU,SAASA,CAAO,CAC9C,CAEA,SAASC,EAAyB,CAChC,OAAO,KAAK,MAAM,UAAU,SAASA,CAAO,CAC9C,CAEA,8BAA8BC,EAA4B,CACxD,IAAMC,EAAc,IAAI,KAAK,MAAM,KAC/BC,EAAS,GAEb,OAAIF,EAAO,UACTA,EAAO,SAAUG,GAAe,CAC9B,GAAKA,EAAM,SACPA,EAAM,SAAU,CACd,OAAOA,EAAM,SAAS,oBAAuB,YAC/CA,EAAM,SAAS,mBAAmB,EAEpC,IAAMC,EAAMD,EAAM,SAAS,YAC3B,GAAIC,EAAK,CACP,IAAMC,EAAWD,EAAI,MAAM,EAAE,aAAaD,EAAM,WAAW,EAC3DF,EAAY,MAAMI,CAAQ,EAC1BH,EAAS,EACX,CACF,CACF,CAAC,EAGIA,EAASD,EAAc,IAAI,KAAK,MAAM,IAC/C,CACF,EAEaK,EAAN,KAAmD,CAGxD,YAAY7C,EAAYC,EAA+B,CAAC,EAAG,CACzD,KAAK,OAAS,IAAIF,EAAcC,EAAOC,CAAO,CAChD,CAEA,WAAuB,CACrB,OAAO,KAAK,MACd,CAEA,SAAkB,CAChB,MAAO,UACT,CACF","names":["index_exports","__export","String3D","String3DCamera","String3DObject","String3DRenderer","String3DScene","String3DSynchronizer","ThreeJSEngine","ThreeJSProvider","__toCommonJS","import_string_tune","String3DCamera","engine","mode","fov","near","far","width","height","ortho","x","y","z","screenX","screenY","normalizedX","normalizedY","distance","viewportHeight","roundedZ","scale","String3DRenderer","container","engine","width","height","scene","camera","String3DObject","id","type","object","engine","child","originalScale","matrix","pos","quat","scale","position","quaternion","euler","value","mat","texture","String3DScene","engine","modelLoader","id","obj","object","type","element","onAdd","added3DObject","parentId","group","String3DObject","kind","color","intensity","light","distance","decay","geometry","material","mesh","widthSegments","heightSegments","segments","modelPath","gltf","gltfScene","child","xhr","error","attr","colorRaw","opacity","params","el","mapSrc","normalMapSrc","roughnessMapSrc","aoMapSrc","src","GroupSynchronizer","el","object","ctx","parentData","rect","centerX","centerY","style","translateZ","position","scale","rotateX","rotateY","rotateZ","LightSynchronizer","el","object","ctx","parentData","rect","centerX","centerY","translateZ","position","MeshSynchronizer","el","object","ctx","parentData","style","originalWidth","originalHeight","rect","translateZ","cssScale","centerX","centerY","worldPos","rotateX","rotateY","rotateZ","targetWidth","targetHeight","cssScaleZ","parentScale","objectType","scaleX","scaleY","scaleZ","uniformSize","cylRadius","String3DSynchronizer","camera","viewportWidth","viewportHeight","engine","MeshSynchronizer","GroupSynchronizer","LightSynchronizer","el","object","parentData","strategy","width","height","import_string_tune","_String3D","context","options","provider","object","result","globalId","element","attributes","parentElement","parentId","String3DRenderer","String3DCamera","String3DScene","String3DSynchronizer","existing","container","el","data","obj","parentData","child","style","String3D","ThreeJSEngine","THREE","loaders","x","y","z","w","order","min","max","options","renderer","fov","aspect","near","far","left","right","top","bottom","geometry","material","width","height","depth","radius","widthSegments","heightSegments","radiusTop","radiusBottom","segments","params","color","intensity","distance","decay","type","LoaderClass","degrees","radians","object","boundingBox","hasBox","child","box","childBox","ThreeJSProvider"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/modules/String3D.ts","../src/core/String3DCamera.ts","../src/core/String3DRenderer.ts","../src/core/String3DObject.ts","../src/core/String3DScene.ts","../src/core/synchronizer/GroupSynchronizer.ts","../src/core/synchronizer/LightSynchronizer.ts","../src/core/synchronizer/MeshSynchronizer.ts","../src/core/synchronizer/String3DSynchronizer.ts","../src/adapters/ThreeJSProvider.ts"],"sourcesContent":["export { String3D } from \"./modules/String3D\";\r\nexport type { String3DOptions } from \"./modules/String3D\";\r\n\r\nexport type {\r\n I3DEngine,\r\n I3DVector3,\r\n I3DVector2,\r\n I3DQuaternion,\r\n I3DEuler,\r\n I3DMatrix4,\r\n I3DBox3,\r\n I3DObject,\r\n I3DMesh,\r\n I3DGeometry,\r\n I3DMaterial,\r\n I3DLight,\r\n I3DCamera,\r\n I3DPerspectiveCamera,\r\n I3DOrthographicCamera,\r\n I3DScene,\r\n I3DRenderer,\r\n I3DTextureLoader,\r\n I3DModelLoader,\r\n} from \"./core/abstractions/I3DEngine\";\r\n\r\nexport type { CameraMode } from \"./core/String3DCamera\";\r\nexport type { I3DEngineProvider } from \"./core/abstractions/I3DEngineProvider\";\r\n\r\nexport { String3DCamera } from \"./core/String3DCamera\";\r\nexport { String3DRenderer } from \"./core/String3DRenderer\";\r\nexport { String3DScene } from \"./core/String3DScene\";\r\nexport { String3DObject } from \"./core/String3DObject\";\r\nexport { String3DSynchronizer } from \"./core/synchronizer/String3DSynchronizer\";\r\n\r\nexport { ThreeJSProvider, ThreeJSEngine } from \"./adapters/ThreeJSProvider\";\r\n","import { StringModule } from \"@fiddle-digital/string-tune\";\r\nimport { StringObject } from \"@fiddle-digital/string-tune\";\r\nimport { StringData } from \"@fiddle-digital/string-tune\";\r\nimport { StringContext } from \"@fiddle-digital/string-tune\";\r\nimport { String3DCamera } from \"../core/String3DCamera\";\r\nimport { String3DRenderer } from \"../core/String3DRenderer\";\r\nimport { String3DScene } from \"../core/String3DScene\";\r\nimport { String3DSynchronizer } from \"../core/synchronizer/String3DSynchronizer\";\r\nimport { I3DEngineProvider } from \"../core/abstractions/I3DEngineProvider\";\r\nimport { I3DEngine, I3DModelLoader } from \"../core/abstractions/I3DEngine\";\r\nimport { frameDOM } from \"@fiddle-digital/string-tune\";\r\n\r\nexport interface String3DOptions {\r\n hideHTML?: boolean;\r\n container?: string | HTMLElement;\r\n zIndex?: number;\r\n modelLoaderType?: string;\r\n modelLoader?: I3DModelLoader;\r\n modelLoaderFactory?: (engine: I3DEngine, type?: string) => I3DModelLoader;\r\n}\r\n\r\nexport class String3D extends StringModule {\r\n private static provider: I3DEngineProvider | null = null;\r\n\r\n private renderer: String3DRenderer | null = null;\r\n private camera: String3DCamera | null = null;\r\n private scene: String3DScene | null = null;\r\n private synchronizer: String3DSynchronizer | null = null;\r\n private engine: I3DEngine | null = null;\r\n private canvasContainer: HTMLElement | null = null;\r\n private isLoading: Map<string, boolean> = new Map();\r\n private options: String3DOptions;\r\n\r\n public static setProvider(provider: I3DEngineProvider): void {\r\n String3D.provider = provider;\r\n }\r\n\r\n constructor(context: StringContext) {\n super(context);\n this.htmlKey = \"3d\";\n this.options = this.buildOptionsFromSettings();\n\r\n this.attributesToMap = [\r\n ...this.attributesToMap,\r\n { key: \"3d\", type: \"string\", fallback: \"box\" },\r\n { key: \"3d-material\", type: \"string\", fallback: \"basic[#ffffff]\" },\r\n { key: \"3d-color\", type: \"string\", fallback: \"#ffffff\" },\r\n { key: \"3d-opacity\", type: \"number\", fallback: 1 },\r\n { key: \"3d-intensity\", type: \"number\", fallback: 1 },\r\n { key: \"3d-distance\", type: \"number\", fallback: 1000 },\r\n { key: \"3d-decay\", type: \"number\", fallback: 0 },\r\n { key: \"3d-model\", type: \"string\", fallback: \"\" },\r\n { key: \"3d-segments\", type: \"number\", fallback: 32 },\r\n { key: \"3d-segments-width\", type: \"number\", fallback: 32 },\r\n { key: \"3d-segments-height\", type: \"number\", fallback: 32 },\r\n { key: \"3d-model-loader\", type: \"string\", fallback: \"\" },\n { key: \"3d-model-scale\", type: \"number\", fallback: 1 },\n { key: \"3d-model-center\", type: \"boolean\", fallback: false },\n { key: \"3d-model-fit\", type: \"string\", fallback: \"contain\" },\n { key: \"3d-metalness\", type: \"number\", fallback: 0 },\n { key: \"3d-roughness\", type: \"number\", fallback: 1 },\n { key: \"3d-texture-flipY\", type: \"boolean\", fallback: true },\n { key: \"3d-colorSpace\", type: \"string\", fallback: \"\" },\n ];\n }\n\r\n override canConnect(object: StringObject): boolean {\r\n const result = super.canConnect(object);\r\n console.log(\r\n \"[String3D] canConnect:\",\r\n object.id,\r\n \"keys:\",\r\n object.keys,\r\n \"htmlKey:\",\r\n this.htmlKey,\r\n \"result:\",\r\n result\r\n );\r\n return result;\r\n }\r\n\r\n override initializeObject(\r\n globalId: number,\r\n object: StringObject,\r\n element: HTMLElement,\r\n attributes: Record<string, any>\r\n ): void {\r\n super.initializeObject(globalId, object, element, attributes);\r\n\r\n object.setProperty(\"parentId\", null);\r\n const parentElement = element.parentElement?.closest(\r\n '[string-3d=\"group\"]'\r\n ) as HTMLElement | null;\r\n if (parentElement) {\r\n const parentId = parentElement.getAttribute(\"string-id\");\r\n if (parentId) {\r\n object.setProperty(\"parentId\", parentId);\r\n object.setProperty(\"parent\", parentElement);\r\n }\r\n }\r\n }\r\n\r\n override onResize(): void {\r\n if (this.renderer && this.camera && this.synchronizer) {\r\n this.renderer.resize(this.camera);\r\n this.synchronizer.updateViewportSize(this.renderer.width, this.renderer.height);\r\n this.camera.clearScaleCache();\r\n }\r\n }\r\n\r\n override onInit(): void {\n this.options = this.buildOptionsFromSettings();\n if (!String3D.provider) {\n console.error(\"[String3D] No provider set. Call String3D.setProvider() before use.\");\n return;\n }\n\r\n this.engine = String3D.provider.getEngine();\r\n this.canvasContainer = this.createOrGetContainer();\r\n this.injectCSS();\r\n\r\n this.renderer = new String3DRenderer(this.canvasContainer, this.engine);\r\n this.renderer.attach();\r\n\r\n this.camera = new String3DCamera(this.engine, \"orthographic\");\r\n this.camera.setPosition(0, 0, 1000);\r\n this.camera.resize(this.renderer.width, this.renderer.height);\r\n\r\n const modelLoader = this.resolveModelLoader();\r\n const modelLoaderFactory = this.resolveModelLoaderFactory();\r\n this.scene = new String3DScene(this.engine, {\r\n modelLoader,\r\n modelLoaderFactory,\r\n });\r\n this.scene.getScene().add(this.camera.camera);\r\n\r\n this.synchronizer = new String3DSynchronizer(\r\n this.camera,\r\n this.renderer.width,\r\n this.renderer.height,\r\n this.engine\r\n );\r\n\r\n console.info(`[String3D] Initialized with: ${String3D.provider.getName()}`);\n }\n\n override onSettingsChange(): void {\n this.options = this.buildOptionsFromSettings();\n }\n\n private buildOptionsFromSettings(): String3DOptions {\n return {\n hideHTML: this.getSettingValue(\"hideHTML\", false),\n container: this.getSettingValue(\"container\", undefined),\n zIndex: this.getSettingValue(\"zIndex\", 1),\n modelLoaderType: this.getSettingValue(\"modelLoaderType\", undefined),\n modelLoader: this.getSettingValue(\"modelLoader\", undefined),\n modelLoaderFactory: this.getSettingValue(\"modelLoaderFactory\", undefined),\n };\n }\n\n private getSettingValue<T>(key: string, fallback: T): T {\n if (!this.settings || !(key in this.settings)) return fallback;\n return this.settings[key] as T;\n }\n\r\n private resolveModelLoader(): I3DModelLoader | undefined {\r\n if (!this.engine) return undefined;\r\n if (this.options.modelLoader) return this.options.modelLoader;\r\n if (this.options.modelLoaderFactory) return undefined;\r\n if (this.options.modelLoaderType) {\r\n try {\r\n return this.engine.createModelLoader(this.options.modelLoaderType);\r\n } catch (error) {\r\n console.warn(\"[String3D] Failed to create model loader:\", error);\r\n }\r\n }\r\n return undefined;\r\n }\r\n\r\n private resolveModelLoaderFactory():\r\n | ((engine: I3DEngine, type?: string) => I3DModelLoader)\r\n | undefined {\r\n if (!this.engine) return undefined;\r\n if (this.options.modelLoaderFactory) return this.options.modelLoaderFactory;\r\n if (this.options.modelLoaderType) {\r\n return (engine: I3DEngine, type?: string) => {\r\n const loaderType = type || this.options.modelLoaderType;\r\n if (!loaderType) {\r\n throw new Error(\"[String3D] Model loader type not provided\");\r\n }\r\n return engine.createModelLoader(loaderType);\r\n };\r\n }\r\n return undefined;\r\n }\r\n\r\n private createOrGetContainer(): HTMLElement {\r\n if (this.options.container instanceof HTMLElement) {\r\n this.applyContainerStyles(this.options.container);\r\n return this.options.container;\r\n }\r\n\r\n if (typeof this.options.container === \"string\") {\r\n const existing = document.getElementById(this.options.container);\r\n if (existing) {\r\n this.applyContainerStyles(existing);\r\n return existing;\r\n }\r\n }\r\n\r\n const container = document.createElement(\"div\");\r\n container.id = \"string-3d-canvas\";\r\n this.applyContainerStyles(container);\r\n document.body.insertBefore(container, document.body.firstChild);\r\n return container;\r\n }\r\n\r\n private applyContainerStyles(el: HTMLElement): void {\r\n Object.assign(el.style, {\r\n position: \"fixed\",\r\n left: \"0\",\r\n top: \"0\",\r\n width: \"100vw\",\r\n height: \"100lvh\",\r\n zIndex: String(this.options.zIndex),\r\n pointerEvents: \"none\",\r\n });\r\n }\r\n\r\n override onObjectConnected(object: StringObject): void {\r\n if (this.isLoading.has(object.id) || !this.scene) return;\r\n this.isLoading.set(object.id, true);\r\n\r\n this.scene.createFromElement(object);\r\n\r\n if (this.options.hideHTML && object.htmlElement) {\r\n object.htmlElement.style.opacity = \"0\";\r\n object.htmlElement.style.pointerEvents = \"none\";\r\n }\r\n }\r\n\r\n override onFrame(data: StringData): void {\r\n if (!this.renderer || !this.scene || !this.camera || !this.synchronizer) return;\r\n\r\n frameDOM.measure(() => {\r\n this.scene!.rootObjects.forEach((obj) => {\r\n this.syncRecursive(obj.el, obj, { scale: 1 });\r\n });\r\n });\r\n\r\n frameDOM.mutate(() => {\r\n this.renderer!.render(this.scene!, this.camera!);\r\n });\r\n }\r\n\r\n private syncRecursive(el: HTMLElement | undefined, object: any, parentData: any): void {\r\n if (!this.synchronizer || !el) return;\r\n const data = this.synchronizer.syncElement(el, object, parentData);\r\n object.children.forEach((child: any) => this.syncRecursive(child.el, child, data));\r\n }\r\n\r\n private injectCSS(): void {\r\n if (document.getElementById(\"string-3d-styles\")) return;\r\n\r\n const style = document.createElement(\"style\");\r\n style.id = \"string-3d-styles\";\r\n style.textContent = `\r\n @property --translate-x { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --translate-y { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --translate-z { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --rotate-x { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --rotate-y { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --rotate-z { syntax: \"<number>\"; inherits: false; initial-value: 0; }\r\n @property --scale { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --scale-x { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --scale-y { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n @property --scale-z { syntax: \"<number>\"; inherits: false; initial-value: 1; }\r\n\r\n [string-3d] {\r\n --translate-x: 0; --translate-y: 0; --translate-z: 0;\r\n --rotate-x: 0; --rotate-y: 0; --rotate-z: 0;\r\n --scale: 1; --scale-x: 1; --scale-y: 1; --scale-z: 1;\r\n transform-style: preserve-3d;\r\n }\r\n\r\n [string-3d-visual=\"true\"] {\r\n transform:\r\n translate3d(calc(var(--translate-x) * 1px), calc(var(--translate-y) * 1px), calc(var(--translate-z) * 1px))\r\n rotateX(calc(var(--rotate-x) * 1deg))\r\n rotateY(calc(var(--rotate-y) * 1deg))\r\n rotateZ(calc(var(--rotate-z) * 1deg))\r\n scale3d(calc(var(--scale) * var(--scale-x)), calc(var(--scale) * var(--scale-y)), calc(var(--scale) * var(--scale-z)));\r\n }\r\n `;\r\n document.head.appendChild(style);\r\n }\r\n\r\n override destroy(): void {\r\n this.renderer?.destroy();\r\n this.scene?.destroy();\r\n this.isLoading.clear();\r\n\r\n const styleEl = document.getElementById(\"string-3d-styles\");\r\n styleEl?.remove();\r\n\r\n if (this.canvasContainer?.id === \"string-3d-canvas\") {\r\n this.canvasContainer.remove();\r\n }\r\n\r\n super.destroy();\r\n }\r\n}\r\n","import { I3DEngine, I3DVector3, I3DCamera } from \"./abstractions/I3DEngine\";\r\n\r\nexport type CameraMode = \"orthographic\" | \"perspective\";\r\n\r\nexport class String3DCamera {\r\n private scaleCache = new Map<number, number>();\r\n private _camera: I3DCamera;\r\n private _position: I3DVector3;\r\n private _width = 1;\r\n private _height = 1;\r\n private engine: I3DEngine;\r\n private mode: CameraMode;\r\n private perspectiveFov: number;\r\n\r\n constructor(\r\n engine: I3DEngine,\r\n mode: CameraMode = \"orthographic\",\r\n fov = 50,\r\n near = 0.1,\r\n far = 10000\r\n ) {\r\n this.engine = engine;\r\n this.mode = mode;\r\n this.perspectiveFov = fov;\r\n\r\n if (mode === \"orthographic\") {\r\n this._camera = engine.createOrthographicCamera(-1, 1, 1, -1, near, far);\r\n } else {\r\n this._camera = engine.createPerspectiveCamera(fov, 1, near, far);\r\n }\r\n\r\n this._position = engine.createVector3(0, 0, 1000);\r\n this.update();\r\n }\r\n\r\n public get camera(): I3DCamera {\r\n return this._camera;\r\n }\r\n\r\n public resize(width: number, height: number): void {\r\n this._width = width;\r\n this._height = height;\r\n\r\n if (this.mode === \"orthographic\") {\r\n const ortho = this._camera as any;\r\n ortho.left = -width / 2;\r\n ortho.right = width / 2;\r\n ortho.top = height / 2;\r\n ortho.bottom = -height / 2;\r\n } else {\r\n this._camera.aspect = width / height;\r\n }\r\n\r\n this.update();\r\n }\r\n\r\n public setPosition(x: number, y: number, z: number): void {\r\n this._position.set(x, y, z);\r\n this._camera.position.copy(this._position);\r\n this.update();\r\n }\r\n\r\n public lookAt(x: number, y: number, z: number): void {\r\n this._camera.lookAt(x, y, z);\r\n this.update();\r\n }\r\n\r\n public update(): void {\r\n this._camera.updateProjectionMatrix();\r\n (this._camera as any).updateMatrixWorld?.();\r\n }\r\n\r\n public screenToWorld(screenX: number, screenY: number, z = 0): I3DVector3 {\r\n if (this.mode === \"orthographic\") {\r\n const x = screenX - this._width / 2;\r\n const y = -(screenY - this._height / 2);\r\n return this.engine.createVector3(x, y, z);\r\n } else {\r\n const { width, height } = this.getFrustumSizeAt(z);\r\n const normalizedX = screenX / this._width;\r\n const normalizedY = screenY / this._height;\r\n const x = (normalizedX - 0.5) * width;\r\n const y = -(normalizedY - 0.5) * height;\r\n return this.engine.createVector3(x, y, z);\r\n }\r\n }\r\n\r\n public getFrustumSizeAt(z: number): { width: number; height: number } {\r\n if (this.mode === \"orthographic\") {\r\n return { width: this._width, height: this._height };\r\n }\r\n\r\n const fov = this.engine.degToRad(this.perspectiveFov);\r\n const distance = Math.abs(z - this._camera.position.z);\r\n const height = 2 * Math.tan(fov / 2) * distance;\r\n const width = height * this._camera.aspect;\r\n return { width, height };\r\n }\r\n\r\n public getScaleAtZ(z: number, viewportHeight: number): number {\r\n if (this.mode === \"orthographic\") {\r\n return 1;\r\n }\r\n\r\n const roundedZ = Math.round(z * 1000) / 1000;\r\n if (this.scaleCache.has(roundedZ)) {\r\n return this.scaleCache.get(roundedZ)!;\r\n }\r\n\r\n const { height } = this.getFrustumSizeAt(z);\r\n const scale = height / viewportHeight;\r\n this.scaleCache.set(roundedZ, scale);\r\n return scale;\r\n }\r\n\r\n public clearScaleCache(): void {\r\n this.scaleCache.clear();\r\n }\r\n\r\n public getMode(): CameraMode {\r\n return this.mode;\r\n }\r\n}\r\n","import { I3DEngine, I3DRenderer } from \"./abstractions/I3DEngine\";\r\nimport { String3DCamera } from \"./String3DCamera\";\r\nimport { String3DScene } from \"./String3DScene\";\r\n\r\nexport class String3DRenderer {\r\n private _container: HTMLElement;\r\n private _renderer: I3DRenderer;\r\n private _width: number;\r\n private _height: number;\r\n private engine: I3DEngine;\r\n\r\n constructor(container: HTMLElement, engine: I3DEngine) {\r\n this.engine = engine;\r\n this._container = container;\r\n const { width, height } = container.getBoundingClientRect();\r\n this._width = width;\r\n this._height = height;\r\n\r\n this._renderer = engine.createRenderer({\r\n antialias: true,\r\n alpha: true,\r\n logarithmicDepthBuffer: true,\r\n });\r\n this._renderer.setPixelRatio(window.devicePixelRatio);\r\n this._renderer.setSize(width, height);\r\n }\r\n\r\n public attach(): void {\r\n this._container.appendChild(this._renderer.domElement);\r\n }\r\n\r\n public render(scene: String3DScene, camera: String3DCamera): void {\r\n this._renderer.render(scene.getScene(), camera.camera);\r\n }\r\n\r\n public resize(camera: String3DCamera): void {\r\n const { width, height } = this._container.getBoundingClientRect();\r\n this._width = width;\r\n this._height = height;\r\n this._renderer.setSize(width, height);\r\n camera.resize(width, height);\r\n }\r\n\r\n public get width(): number {\r\n return this._width;\r\n }\r\n\r\n public get height(): number {\r\n return this._height;\r\n }\r\n\r\n public get renderer(): I3DRenderer {\r\n return this._renderer;\r\n }\r\n\r\n public destroy(): void {\r\n this._renderer.dispose();\r\n }\r\n}\r\n","import {\r\n I3DEngine,\r\n I3DObject,\r\n I3DMaterial,\r\n I3DGeometry,\r\n I3DQuaternion,\r\n I3DVector3,\r\n I3DEuler,\r\n I3DMatrix4,\r\n I3DBox3,\r\n} from \"./abstractions/I3DEngine\";\r\n\r\nexport class String3DObject {\n public id: string;\n public type: string;\n private _object: I3DObject;\n private _material?: I3DMaterial;\n private _geometry?: I3DGeometry;\n private _texture?: any;\n private _uniforms: Record<string, { value: any }> = {};\r\n private _originalBoundingBox?: I3DBox3 | null;\r\n private _quaternion: I3DQuaternion;\r\n private _originalSize: I3DVector3;\r\n private _bbox: I3DBox3;\r\n public el: any;\r\n private _children: String3DObject[] = [];\r\n private engine: I3DEngine;\r\n\r\n public get children(): String3DObject[] {\r\n return this._children;\r\n }\r\n\r\n constructor(\n id: string,\n type: string,\n object: I3DObject,\n engine: I3DEngine,\n options: { material?: I3DMaterial; geometry?: I3DGeometry; texture?: any } = {}\n ) {\n this.id = id;\n this.type = type;\n this._object = object;\n this.engine = engine;\n this._material = options.material;\n this._geometry = options.geometry;\n this._texture = options.texture;\n this._quaternion = engine.createQuaternion();\n this._originalSize = engine.createVector3();\n this._bbox = engine.createBox3();\n this.updateBoundingBox();\n }\n\r\n public get object(): I3DObject {\r\n return this._object;\r\n }\r\n\r\n public get material(): I3DMaterial | undefined {\r\n return this._material;\r\n }\r\n\r\n public get originalSize(): I3DVector3 {\r\n return this._originalSize.clone();\r\n }\r\n\r\n public get boundingBox(): I3DBox3 {\r\n return this._bbox.clone();\r\n }\r\n\r\n public addChild(child: String3DObject): void {\r\n this._children.push(child);\r\n this.object.add(child.object);\r\n }\r\n\r\n public getWorldMatrix(): I3DMatrix4 {\r\n return this._object.matrixWorld.clone();\r\n }\r\n\r\n public getWorldPosition(): I3DVector3 {\r\n return this.engine.createVector3().setFromMatrixPosition(this._object.matrixWorld);\r\n }\r\n\r\n public getOriginalBoundingBox(): I3DBox3 {\r\n if (!this._originalBoundingBox) {\r\n const originalScale = this.object.scale.clone();\r\n this.object.scale.set(1, 1, 1);\r\n this.object.updateMatrixWorld(true);\r\n this._originalBoundingBox = this.engine.computeBoundingBoxRecursively(this.object);\r\n this.object.scale.copy(originalScale);\r\n this.object.updateMatrixWorld(true);\r\n }\r\n return this._originalBoundingBox!.clone();\r\n }\r\n\r\n public syncTransformFromMatrix(matrix: I3DMatrix4): void {\r\n const pos = this.engine.createVector3();\r\n const quat = this.engine.createQuaternion();\r\n const scale = this.engine.createVector3();\r\n matrix.decompose(pos, quat, scale);\r\n this._object.position.copy(pos);\r\n this._object.quaternion.copy(quat);\r\n this._object.scale.copy(scale);\r\n this._object.updateMatrix();\r\n this._object.updateMatrixWorld();\r\n }\r\n\r\n public applyWorldTransform(\r\n position: I3DVector3,\r\n quaternion: I3DQuaternion,\r\n scale: I3DVector3\r\n ): void {\r\n this._object.position.copy(position);\r\n this._object.quaternion.copy(quaternion);\r\n this._object.scale.copy(scale);\r\n this._object.updateMatrix();\r\n this._object.updateMatrixWorld();\r\n }\r\n\r\n public set quaternion(quaternion: I3DQuaternion) {\r\n this._quaternion.copy(quaternion);\r\n this._object.quaternion.copy(this._quaternion);\r\n this._object.updateMatrixWorld();\r\n }\r\n\r\n public set position(position: I3DVector3) {\r\n this._object.position.copy(position);\r\n }\r\n\r\n public set scale(scale: I3DVector3) {\r\n this._object.scale.copy(scale);\r\n }\r\n\r\n public set rotation(euler: I3DEuler) {\r\n this._object.rotation.copy(euler);\r\n }\r\n\r\n public set opacity(value: number) {\r\n const mat = this._object as any;\r\n if (mat.material && \"opacity\" in mat.material) {\r\n mat.material.opacity = value;\r\n }\r\n }\r\n\r\n public set metalness(value: number) {\r\n const mat = this._object as any;\r\n if (mat.material && \"metalness\" in mat.material) {\r\n mat.material.metalness = value;\r\n }\r\n }\r\n\r\n public set roughness(value: number) {\r\n const mat = this._object as any;\r\n if (mat.material && \"roughness\" in mat.material) {\r\n mat.material.roughness = value;\r\n }\r\n }\r\n\r\n public set texture(texture: any) {\n this._texture = texture;\n if ((this._object as any).isMesh && texture?.applyTexture) {\n texture.applyTexture(this._object);\n }\n }\n\n public set material(material: I3DMaterial | undefined) {\n this._material = material;\n }\n\n public set geometry(geometry: I3DGeometry | undefined) {\n this._geometry = geometry;\n }\n\n public updateBoundingBox(): void {\n this._bbox.setFromObject(this._object);\n this._bbox.getSize(this._originalSize);\n }\n\n public destroy(): void {\n this.disposeObjectResources(this._object);\n this._texture?.dispose?.();\n this._material?.dispose();\n this._geometry?.dispose();\n }\n\n private disposeObjectResources(object: I3DObject): void {\n const anyObj = object as any;\n if (anyObj?.geometry?.dispose) {\n anyObj.geometry.dispose();\n }\n const material = anyObj?.material;\n if (Array.isArray(material)) {\n material.forEach((mat) => mat?.dispose?.());\n } else if (material?.dispose) {\n material.dispose();\n }\n if (typeof anyObj?.traverse === \"function\") {\n anyObj.traverse((child: any) => {\n if (child?.geometry?.dispose) {\n child.geometry.dispose();\n }\n const childMat = child?.material;\n if (Array.isArray(childMat)) {\n childMat.forEach((mat: any) => mat?.dispose?.());\n } else if (childMat?.dispose) {\n childMat.dispose();\n }\n });\n }\n }\n}\n","import {\n I3DEngine,\n I3DScene,\n I3DLight,\n I3DMaterial,\n I3DModelLoader,\n I3DVector3,\n} from \"./abstractions/I3DEngine\";\nimport { String3DObject } from \"./String3DObject\";\nimport { StringObject } from \"@fiddle-digital/string-tune\";\n\nexport interface String3DSceneOptions {\n modelLoader?: I3DModelLoader;\n modelLoaderFactory?: (engine: I3DEngine, type?: string) => I3DModelLoader;\n}\n\nexport class String3DScene {\n private _scene: I3DScene;\n private _objects: Map<string, String3DObject> = new Map();\n private _rootObjects: String3DObject[] = [];\n private _elementMap: Map<string, HTMLElement> = new Map();\n private engine: I3DEngine;\n private _modelLoader?: I3DModelLoader;\n private _modelLoaderFactory?: (engine: I3DEngine, type?: string) => I3DModelLoader;\n private _modelLoaderCache: Map<string, I3DModelLoader> = new Map();\n\n public get rootObjects(): String3DObject[] {\n return this._rootObjects;\n }\n\n constructor(engine: I3DEngine, options: String3DSceneOptions = {}) {\n this.engine = engine;\n this._modelLoader = options.modelLoader;\n this._modelLoaderFactory = options.modelLoaderFactory;\n this._scene = engine.createScene();\n }\n\r\n public getScene(): I3DScene {\r\n return this._scene;\r\n }\r\n\r\n public getObject(id: string): String3DObject | undefined {\r\n return this._objects.get(id);\r\n }\r\n\r\n public hasObject(id: string): boolean {\r\n return this._objects.has(id);\r\n }\r\n\r\n public deleteObject(id: string): boolean {\r\n const obj = this._objects.get(id);\r\n if (obj) {\r\n this._scene.remove(obj.object);\r\n this._objects.delete(id);\r\n obj.destroy();\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n public createFromElement(object: StringObject): void {\r\n const type = object.getProperty<string>(\"3d\");\r\n if (!type) return;\r\n\r\n const element = object.htmlElement;\r\n if (!element) return;\r\n\r\n const onAdd = (added3DObject: String3DObject) => {\r\n if (added3DObject) {\r\n const parentId = object.getProperty<string>(\"parentId\");\r\n if (parentId == null) {\r\n this._scene.add(added3DObject.object);\r\n this._rootObjects.push(added3DObject);\r\n } else {\r\n this._objects.get(parentId)?.addChild(added3DObject);\r\n }\r\n this._objects.set(object.id, added3DObject);\r\n this._elementMap.set(object.id, element);\r\n added3DObject.el = element;\r\n }\r\n };\r\n\r\n switch (type) {\r\n case \"group\":\r\n this.createGroup(object, onAdd);\r\n break;\r\n case \"pointLight\":\r\n this.createLight(object, \"point\", onAdd);\r\n break;\r\n case \"ambientLight\":\r\n this.createLight(object, \"ambient\", onAdd);\r\n break;\r\n case \"directionalLight\":\r\n this.createLight(object, \"directional\", onAdd);\r\n break;\r\n case \"model\":\r\n this.createModel(object, onAdd);\r\n break;\r\n case \"box\":\r\n this.createBox(object, onAdd);\r\n break;\r\n case \"sphere\":\r\n this.createSphere(object, onAdd);\r\n break;\r\n case \"plane\":\r\n this.createPlane(object, onAdd);\r\n break;\r\n case \"cylinder\":\r\n this.createCylinder(object, onAdd);\r\n break;\r\n }\r\n }\r\n\r\n private createGroup(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\n const group = this.engine.createGroup();\n const obj = new String3DObject(object.id, \"group\", group, this.engine);\n onAdd(obj);\n return obj;\n }\r\n\r\n private createLight(\r\n object: StringObject,\r\n kind: \"point\" | \"ambient\" | \"directional\",\r\n onAdd: (obj: String3DObject) => void\r\n ): String3DObject {\r\n const color = object.getProperty<string>(\"3d-color\") || \"#ffffff\";\r\n const intensity = object.getProperty<number>(\"3d-intensity\") ?? 1;\r\n\r\n let light: I3DLight;\r\n if (kind === \"point\") {\r\n const distance = object.getProperty<number>(\"3d-distance\") ?? 1000;\r\n const decay = object.getProperty<number>(\"3d-decay\") ?? 0;\r\n light = this.engine.createPointLight(color, intensity, distance, decay);\r\n } else if (kind === \"directional\") {\r\n light = this.engine.createDirectionalLight(color, intensity);\r\n } else {\r\n light = this.engine.createAmbientLight(color, intensity);\r\n }\r\n\r\n const obj = new String3DObject(object.id, kind + \"Light\", light, this.engine);\r\n onAdd(obj);\r\n return obj;\r\n }\r\n\r\n private createBox(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\n const geometry = this.engine.createBoxGeometry(1, 1, 1);\n const material = this.createMaterialFromObject(object);\n const mesh = this.engine.createMesh(geometry, material);\n const obj = new String3DObject(object.id, \"box\", mesh, this.engine, {\n geometry,\n material,\n });\n onAdd(obj);\n return obj;\n }\n\r\n private createSphere(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\n const widthSegments = object.getProperty<number>(\"3d-segments-width\") ?? 32;\n const heightSegments = object.getProperty<number>(\"3d-segments-height\") ?? 32;\n const geometry = this.engine.createSphereGeometry(0.5, widthSegments, heightSegments);\n const material = this.createMaterialFromObject(object);\n const mesh = this.engine.createMesh(geometry, material);\n const obj = new String3DObject(object.id, \"sphere\", mesh, this.engine, {\n geometry,\n material,\n });\n onAdd(obj);\n return obj;\n }\n\r\n private createPlane(object: StringObject, onAdd: (obj: String3DObject) => void): String3DObject {\n const geometry = this.engine.createPlaneGeometry(1, 1);\n const material = this.createMaterialFromObject(object);\n const mesh = this.engine.createMesh(geometry, material);\n const obj = new String3DObject(object.id, \"plane\", mesh, this.engine, {\n geometry,\n material,\n });\n onAdd(obj);\n return obj;\n }\n\r\n private createCylinder(\r\n object: StringObject,\r\n onAdd: (obj: String3DObject) => void\r\n ): String3DObject {\r\n const segments = object.getProperty<number>(\"3d-segments\") ?? 32;\n const geometry = this.engine.createCylinderGeometry(0.5, 0.5, 1, segments);\n const material = this.createMaterialFromObject(object);\n const mesh = this.engine.createMesh(geometry, material);\n const obj = new String3DObject(object.id, \"cylinder\", mesh, this.engine, {\n geometry,\n material,\n });\n onAdd(obj);\n return obj;\n }\n\n private createModel(object: StringObject, onAdd: (obj: String3DObject) => void): void {\n const modelPath = object.getProperty<string>(\"3d-model\");\n if (!modelPath) return;\n\n const loaderType = object.getProperty<string>(\"3d-model-loader\") || undefined;\n const loader = this.resolveModelLoader(loaderType);\n if (!loader) {\n console.warn(\"[String3D] Model loader not configured\");\n return;\n }\n\n const element = object.htmlElement;\n if (element) {\n this.applyModelTextureRemap(loader, element);\n }\n const shouldCenter = object.getProperty<boolean>(\"3d-model-center\") ?? false;\n\n loader.load(\n modelPath,\n (gltf: any) => {\n const root = gltf?.scene || gltf?.object || gltf;\n if (!root) {\n console.warn(\"[String3D] Model loader returned empty result\");\n return;\n }\n if (element && this.shouldOverrideModelMaterial(element)) {\n const material = this.createMaterialFromElement(element, object);\n if (typeof root.traverse === \"function\") {\n root.traverse((child: any) => {\n if (child.isMesh) {\n child.material = material;\n }\n });\n }\n }\n if (shouldCenter) {\n this.centerObject(root);\n }\n const obj = new String3DObject(object.id, \"model\", root, this.engine);\n onAdd(obj);\n },\n (xhr: any) => {\r\n console.log((xhr.loaded / xhr.total) * 100 + \"% loaded\");\r\n },\r\n (error: any) => {\r\n console.error(\"[String3D] Model loading error:\", error);\r\n }\r\n );\r\n }\n\n private resolveModelLoader(type?: string): I3DModelLoader | undefined {\n if (type) {\n if (this._modelLoaderCache.has(type)) {\n return this._modelLoaderCache.get(type);\n }\n if (!this._modelLoaderFactory) {\n console.warn(`[String3D] No model loader factory for type \"${type}\"`);\n return undefined;\n }\n const loader = this._modelLoaderFactory(this.engine, type);\n this._modelLoaderCache.set(type, loader);\n return loader;\n }\n\n if (this._modelLoader) {\n return this._modelLoader;\n }\n\n if (this._modelLoaderFactory) {\n return this._modelLoaderFactory(this.engine);\n }\n\n return undefined;\n }\n\n private centerObject(object: any): void {\n if (!object) return;\n const bbox = this.engine.computeBoundingBoxRecursively(object);\n const center = this.getBoxCenter(bbox);\n if (object.position?.set) {\n object.position.set(-center.x, -center.y, -center.z);\n }\n object.updateMatrixWorld(true);\n }\n\n private getBoxCenter(box: any): I3DVector3 {\n const center = this.engine.createVector3();\n center.x = (box.min.x + box.max.x) / 2;\n center.y = (box.min.y + box.max.y) / 2;\n center.z = (box.min.z + box.max.z) / 2;\n return center;\n }\n\n private createMaterialFromObject(object: StringObject): I3DMaterial {\n return this.createMaterialFromElement(object.htmlElement, object);\n }\n\n private createMaterialFromElement(\n element: HTMLElement | null,\n object?: StringObject\n ): I3DMaterial {\n const attr = object?.getProperty<string>(\"3d-material\") || \"basic[#ffffff]\";\n let [type, colorRaw] = attr.split(/\\[|\\]/);\n const color = colorRaw || \"#ffffff\";\n const opacity = object?.getProperty<number>(\"3d-opacity\") ?? 1;\n const metalness = object?.getProperty<number>(\"3d-metalness\");\n const roughness = object?.getProperty<number>(\"3d-roughness\");\n const params: any = {\n color,\n transparent: opacity < 1,\n opacity: opacity,\n };\n\n const mapSrc = element?.getAttribute(\"string-3d-map\");\n const normalMapSrc = element?.getAttribute(\"string-3d-normalMap\");\n const roughnessMapSrc = element?.getAttribute(\"string-3d-roughnessMap\");\n const metalnessMapSrc = element?.getAttribute(\"string-3d-metalnessMap\");\n const aoMapSrc = element?.getAttribute(\"string-3d-aoMap\");\n const flipY = this.parseFlipY(object, element);\n const colorSpace =\n object?.getProperty<string>(\"3d-colorSpace\") ||\n element?.getAttribute(\"string-3d-colorSpace\") ||\n \"\";\n\n const hasMaps = !!(\n mapSrc ||\n normalMapSrc ||\n roughnessMapSrc ||\n metalnessMapSrc ||\n aoMapSrc\n );\n if (type !== \"standard\" && hasMaps) {\n type = \"standard\";\n }\n\n if (type === \"standard\") {\n if (mapSrc) {\n params.map = this.loadTexture(mapSrc, { flipY, colorSpace });\n }\n if (normalMapSrc) params.normalMap = this.loadTexture(normalMapSrc, { flipY });\n if (roughnessMapSrc) params.roughnessMap = this.loadTexture(roughnessMapSrc, { flipY });\n if (metalnessMapSrc) params.metalnessMap = this.loadTexture(metalnessMapSrc, { flipY });\n if (aoMapSrc) params.aoMap = this.loadTexture(aoMapSrc, { flipY });\n if (typeof metalness === \"number\") params.metalness = metalness;\n if (typeof roughness === \"number\") params.roughness = roughness;\n return this.engine.createMeshStandardMaterial(params);\n }\n\r\n return this.engine.createMeshBasicMaterial(params);\r\n }\r\n\r\n private loadTexture(\n src: string,\n options: { flipY?: boolean; colorSpace?: string } = {}\n ): any {\n const textureLoader = this.engine.createTextureLoader();\n const texture = textureLoader.load(src);\n if (typeof options.flipY === \"boolean\") {\n texture.flipY = options.flipY;\n }\n const colorSpace = (options.colorSpace || \"\").toLowerCase().trim();\n if (colorSpace && \"colorSpace\" in texture) {\n texture.colorSpace = colorSpace === \"srgb\" ? \"srgb\" : \"linear\";\n }\n texture.needsUpdate = true;\n return texture;\n }\n\n private parseFlipY(object?: StringObject, element?: HTMLElement | null): boolean | undefined {\n const value =\n object?.getProperty<boolean>(\"3d-texture-flipY\") ??\n element?.getAttribute(\"string-3d-texture-flipY\");\n if (value === undefined || value === null || value === \"\") return undefined;\n if (typeof value === \"boolean\") return value;\n const normalized = String(value).toLowerCase().trim();\n if (normalized === \"false\" || normalized === \"0\" || normalized === \"no\") return false;\n if (normalized === \"true\" || normalized === \"1\" || normalized === \"yes\") return true;\n return undefined;\n }\n\n private shouldOverrideModelMaterial(element: HTMLElement): boolean {\n const attrs = [\n \"string-3d-material\",\n \"string-3d-color\",\n \"string-3d-opacity\",\n \"string-3d-map\",\n \"string-3d-normalMap\",\n \"string-3d-roughnessMap\",\n \"string-3d-metalnessMap\",\n \"string-3d-aoMap\",\n \"string-3d-metalness\",\n \"string-3d-roughness\",\n ];\n return attrs.some((attr) => element.hasAttribute(attr));\n }\n\n private applyModelTextureRemap(loader: any, element: HTMLElement): void {\n const baseRaw = (element.getAttribute(\"string-3d-model-texture-base\") || \"\").trim();\n const base = baseRaw ? baseRaw.replace(/\\/?$/, \"/\") : \"\";\n const mappingRaw = element.getAttribute(\"string-3d-model-textures\");\n let mapping: Record<string, string> | null = null;\n\n if (mappingRaw) {\n try {\n mapping = JSON.parse(mappingRaw);\n } catch (error) {\n console.warn(\"[String3D] Invalid model texture mapping JSON:\", error);\n }\n }\n\n const manager = loader?.manager;\n if (!manager || typeof manager.setURLModifier !== \"function\") {\n if (mapping || base) {\n console.warn(\"[String3D] Model loader does not support URL remap.\");\n }\n return;\n }\n\n manager.setURLModifier((url: string) => {\n const mapped = mapping && url in mapping ? mapping[url] : url;\n if (!base) return mapped;\n if (/^(blob:|data:|https?:|file:|\\/)/i.test(mapped)) return mapped;\n return base + mapped.replace(/^\\.?\\//, \"\");\n });\n }\n\r\n public destroy(): void {\r\n this._objects.forEach((obj) => obj.destroy());\r\n this._objects.clear();\r\n this._rootObjects = [];\r\n }\r\n}\r\n","import { String3DObject } from \"../String3DObject\";\r\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\r\nimport type { SyncContext } from \"./SyncContext\";\r\n\r\nexport class GroupSynchronizer implements String3DObjectSyncStrategy {\r\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\r\n const rect = el.getBoundingClientRect();\r\n const centerX = rect.left + rect.width / 2;\r\n const centerY = rect.top + rect.height / 2;\r\n\r\n const style = getComputedStyle(el);\r\n const translateZ = parseFloat(style.getPropertyValue(\"--translate-z\") || \"0\");\r\n const position = ctx.camera.screenToWorld(centerX, centerY, translateZ);\r\n object.position = position;\r\n\r\n const scale = parseFloat(style.getPropertyValue(\"--scale\")) || 1;\r\n object.scale = ctx.engine.createVector3(scale, scale, scale);\r\n\r\n const rotateX = -ctx.engine.degToRad(parseFloat(style.getPropertyValue(\"--rotate-x\") || \"0\"));\r\n const rotateY = ctx.engine.degToRad(parseFloat(style.getPropertyValue(\"--rotate-y\") || \"0\"));\r\n const rotateZ = -ctx.engine.degToRad(parseFloat(style.getPropertyValue(\"--rotate-z\") || \"0\"));\r\n object.rotation = ctx.engine.createEuler(rotateX, rotateY, rotateZ, \"XYZ\");\r\n\r\n object.object.updateMatrixWorld(true);\r\n\r\n return { scale };\r\n }\r\n}\r\n","import { String3DObject } from \"../String3DObject\";\r\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\r\nimport type { SyncContext } from \"./SyncContext\";\r\n\r\nexport class LightSynchronizer implements String3DObjectSyncStrategy {\r\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\r\n const rect = el.getBoundingClientRect();\r\n const centerX = rect.left + rect.width / 2;\r\n const centerY = rect.top + rect.height / 2;\r\n\r\n const translateZ = parseFloat(getComputedStyle(el).getPropertyValue(\"--translate-z\") || \"0\");\r\n const position = ctx.camera.screenToWorld(centerX, centerY, translateZ);\r\n object.position = position;\r\n\r\n return null;\r\n }\r\n}\r\n","import { String3DObject } from \"../String3DObject\";\r\nimport type { SyncContext } from \"./SyncContext\";\r\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\r\n\r\nexport class MeshSynchronizer implements String3DObjectSyncStrategy {\r\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\r\n const style = getComputedStyle(el);\r\n\r\n const originalWidth = el.offsetWidth;\r\n const originalHeight = el.offsetHeight;\r\n const rect = el.getBoundingClientRect();\r\n\r\n const translateZ = parseFloat(style.getPropertyValue(\"--translate-z\") || \"0\");\r\n const cssScale = parseFloat(style.getPropertyValue(\"--scale\") || \"1\");\r\n\r\n const centerX = rect.left + rect.width / 2;\r\n const centerY = rect.top + rect.height / 2;\r\n\r\n const worldPos = ctx.camera.screenToWorld(centerX, centerY, translateZ);\r\n object.position = worldPos;\r\n\r\n const rotateX = -ctx.engine.degToRad(parseFloat(style.getPropertyValue(\"--rotate-x\") || \"0\"));\r\n const rotateY = ctx.engine.degToRad(parseFloat(style.getPropertyValue(\"--rotate-y\") || \"0\"));\r\n const rotateZ = -ctx.engine.degToRad(parseFloat(style.getPropertyValue(\"--rotate-z\") || \"0\"));\r\n object.rotation = ctx.engine.createEuler(rotateX, rotateY, rotateZ, \"XYZ\");\r\n\r\n const targetWidth = originalWidth * cssScale;\r\n const targetHeight = originalHeight * cssScale;\r\n const cssScaleZ = parseFloat(style.getPropertyValue(\"--scale-z\") || \"1\");\r\n const parentScale = parentData?.scale || 1;\r\n\r\n const objectType = object.type;\r\n let scaleX: number, scaleY: number, scaleZ: number;\r\n\r\n switch (objectType) {\n case \"box\":\n case \"sphere\": {\n const uniformSize = Math.min(targetWidth, targetHeight);\n scaleX = uniformSize * parentScale;\n scaleY = uniformSize * parentScale;\n scaleZ = uniformSize * cssScaleZ * parentScale;\n break;\n }\n case \"model\": {\n const bbox = object.getOriginalBoundingBox();\n const size = bbox.getSize(ctx.engine.createVector3());\n const fitMode = (el.getAttribute(\"string-3d-model-fit\") || \"contain\")\n .toLowerCase()\n .trim();\n const modelScaleAttr = parseFloat(\n el.getAttribute(\"string-3d-model-scale\") || \"1\"\n );\n const modelScale = Number.isFinite(modelScaleAttr) ? modelScaleAttr : 1;\n\n if (size.x > 0 && size.y > 0) {\n const scaleToWidth = targetWidth / size.x;\n const scaleToHeight = targetHeight / size.y;\n const uniformScale =\n fitMode === \"cover\"\n ? Math.max(scaleToWidth, scaleToHeight)\n : Math.min(scaleToWidth, scaleToHeight);\n\n scaleX = uniformScale * modelScale * parentScale;\n scaleY = uniformScale * modelScale * parentScale;\n scaleZ = uniformScale * modelScale * cssScaleZ * parentScale;\n } else {\n const fallbackSize = Math.min(targetWidth, targetHeight);\n scaleX = fallbackSize * modelScale * parentScale;\n scaleY = fallbackSize * modelScale * parentScale;\n scaleZ = fallbackSize * modelScale * cssScaleZ * parentScale;\n }\n break;\n }\n case \"cylinder\": {\n const cylRadius = targetWidth;\n scaleX = cylRadius * parentScale;\n scaleY = targetHeight * parentScale;\n scaleZ = cylRadius * cssScaleZ * parentScale;\n break;\r\n }\r\n case \"plane\":\r\n default:\r\n scaleX = targetWidth * parentScale;\r\n scaleY = targetHeight * parentScale;\r\n scaleZ = Math.min(targetWidth, targetHeight) * 0.5 * cssScaleZ * parentScale;\r\n break;\r\n }\r\n\r\n object.scale = ctx.engine.createVector3(scaleX, scaleY, scaleZ);\r\n\r\n return { scale: cssScale * parentScale };\r\n }\r\n}\r\n","import { String3DCamera } from \"../String3DCamera\";\r\nimport { String3DObject } from \"../String3DObject\";\r\nimport { I3DEngine } from \"../abstractions/I3DEngine\";\r\nimport { GroupSynchronizer } from \"./GroupSynchronizer\";\r\nimport { LightSynchronizer } from \"./LightSynchronizer\";\r\nimport { MeshSynchronizer } from \"./MeshSynchronizer\";\r\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\r\n\r\nexport class String3DSynchronizer {\r\n private strategies: Map<string, String3DObjectSyncStrategy> = new Map();\r\n\r\n constructor(\r\n public camera: String3DCamera,\r\n public viewportWidth: number,\r\n public viewportHeight: number,\r\n public engine: I3DEngine\r\n ) {\r\n this.strategies.set(\"box\", new MeshSynchronizer());\r\n this.strategies.set(\"sphere\", new MeshSynchronizer());\r\n this.strategies.set(\"plane\", new MeshSynchronizer());\r\n this.strategies.set(\"cylinder\", new MeshSynchronizer());\r\n this.strategies.set(\"model\", new MeshSynchronizer());\r\n this.strategies.set(\"group\", new GroupSynchronizer());\r\n this.strategies.set(\"pointLight\", new LightSynchronizer());\r\n this.strategies.set(\"ambientLight\", new LightSynchronizer());\r\n this.strategies.set(\"directionalLight\", new LightSynchronizer());\r\n }\r\n\r\n public syncElement(el: HTMLElement, object: String3DObject, parentData: any): any {\r\n const strategy = this.strategies.get(object.type);\r\n if (!strategy) {\r\n console.warn(`[String3D Sync] No strategy for type \"${object.type}\"`);\r\n return null;\r\n }\r\n\r\n return strategy.sync(\r\n el,\r\n object,\r\n {\r\n camera: this.camera,\r\n viewportWidth: this.viewportWidth,\r\n viewportHeight: this.viewportHeight,\r\n engine: this.engine,\r\n },\r\n parentData\r\n );\r\n }\r\n\r\n public updateViewportSize(width: number, height: number): void {\r\n this.viewportWidth = width;\r\n this.viewportHeight = height;\r\n }\r\n}\r\n","import {\r\n I3DEngine,\r\n I3DVector3,\r\n I3DVector2,\r\n I3DQuaternion,\r\n I3DEuler,\r\n I3DMatrix4,\r\n I3DBox3,\r\n I3DScene,\r\n I3DRenderer,\r\n I3DPerspectiveCamera,\r\n I3DOrthographicCamera,\r\n I3DObject,\r\n I3DMesh,\r\n I3DGeometry,\r\n I3DMaterial,\r\n I3DLight,\r\n I3DTextureLoader,\r\n I3DModelLoader,\r\n} from \"../core/abstractions/I3DEngine\";\r\nimport { I3DEngineProvider } from \"../core/abstractions/I3DEngineProvider\";\r\n\r\nexport class ThreeJSEngine implements I3DEngine {\r\n private THREE: any;\r\n private loaders: Record<string, any>;\r\n\r\n constructor(THREE: any, loaders: Record<string, any> = {}) {\r\n this.THREE = THREE;\r\n this.loaders = loaders;\r\n }\r\n\r\n createVector3(x = 0, y = 0, z = 0): I3DVector3 {\r\n return new this.THREE.Vector3(x, y, z);\r\n }\r\n\r\n createVector2(x = 0, y = 0): I3DVector2 {\r\n return new this.THREE.Vector2(x, y);\r\n }\r\n\r\n createQuaternion(x = 0, y = 0, z = 0, w = 1): I3DQuaternion {\r\n return new this.THREE.Quaternion(x, y, z, w);\r\n }\r\n\r\n createEuler(x = 0, y = 0, z = 0, order = \"XYZ\"): I3DEuler {\r\n return new this.THREE.Euler(x, y, z, order);\r\n }\r\n\r\n createMatrix4(): I3DMatrix4 {\r\n return new this.THREE.Matrix4();\r\n }\r\n\r\n createBox3(min?: I3DVector3, max?: I3DVector3): I3DBox3 {\r\n return new this.THREE.Box3(min, max);\r\n }\r\n\r\n createScene(): I3DScene {\r\n return new this.THREE.Scene();\r\n }\r\n\r\n createRenderer(options?: {\r\n antialias?: boolean;\r\n alpha?: boolean;\r\n logarithmicDepthBuffer?: boolean;\r\n }): I3DRenderer {\r\n const renderer = new this.THREE.WebGLRenderer(options);\r\n renderer.outputEncoding = this.THREE.sRGBEncoding;\r\n return renderer;\r\n }\r\n\r\n createPerspectiveCamera(fov = 45, aspect = 1, near = 0.1, far = 2000): I3DPerspectiveCamera {\r\n return new this.THREE.PerspectiveCamera(fov, aspect, near, far);\r\n }\r\n\r\n createOrthographicCamera(\r\n left: number,\r\n right: number,\r\n top: number,\r\n bottom: number,\r\n near = 0.1,\r\n far = 10000\r\n ): I3DOrthographicCamera {\r\n return new this.THREE.OrthographicCamera(left, right, top, bottom, near, far);\r\n }\r\n\r\n createGroup(): I3DObject {\r\n return new this.THREE.Group();\r\n }\r\n\r\n createMesh(geometry: I3DGeometry, material: I3DMaterial): I3DMesh {\r\n return new this.THREE.Mesh(geometry, material);\r\n }\r\n\r\n createBoxGeometry(width: number, height: number, depth: number): I3DGeometry {\r\n return new this.THREE.BoxGeometry(width, height, depth);\r\n }\r\n\r\n createSphereGeometry(radius: number, widthSegments = 32, heightSegments = 32): I3DGeometry {\r\n return new this.THREE.SphereGeometry(radius, widthSegments, heightSegments);\r\n }\r\n\r\n createPlaneGeometry(width: number, height: number): I3DGeometry {\r\n return new this.THREE.PlaneGeometry(width, height);\r\n }\r\n\r\n createCylinderGeometry(\r\n radiusTop: number,\r\n radiusBottom: number,\r\n height: number,\r\n segments = 32\r\n ): I3DGeometry {\r\n return new this.THREE.CylinderGeometry(radiusTop, radiusBottom, height, segments);\r\n }\r\n\r\n createMeshBasicMaterial(params?: any): I3DMaterial {\r\n return new this.THREE.MeshBasicMaterial(params);\r\n }\r\n\r\n createMeshStandardMaterial(params?: any): I3DMaterial {\r\n return new this.THREE.MeshStandardMaterial(params);\r\n }\r\n\r\n createPointLight(color?: string | number, intensity = 1, distance = 0, decay = 2): I3DLight {\r\n return new this.THREE.PointLight(color, intensity, distance, decay);\r\n }\r\n\r\n createAmbientLight(color?: string | number, intensity = 1): I3DLight {\r\n return new this.THREE.AmbientLight(color, intensity);\r\n }\r\n\r\n createDirectionalLight(color?: string | number, intensity = 1): I3DLight {\r\n return new this.THREE.DirectionalLight(color, intensity);\r\n }\r\n\r\n createTextureLoader(): I3DTextureLoader {\r\n return new this.THREE.TextureLoader();\r\n }\r\n\r\n createModelLoader(type: string): I3DModelLoader {\r\n const LoaderClass = this.loaders[type];\r\n if (!LoaderClass) {\r\n throw new Error(`[ThreeJSEngine] Model loader \"${type}\" not registered`);\r\n }\r\n return new LoaderClass();\r\n }\r\n\r\n degToRad(degrees: number): number {\r\n return this.THREE.MathUtils.degToRad(degrees);\r\n }\r\n\r\n radToDeg(radians: number): number {\r\n return this.THREE.MathUtils.radToDeg(radians);\r\n }\r\n\r\n computeBoundingBoxRecursively(object: I3DObject): I3DBox3 {\r\n const boundingBox = new this.THREE.Box3();\r\n let hasBox = false;\r\n\r\n if (object.traverse) {\r\n object.traverse((child: any) => {\r\n if (!child.visible) return;\r\n if (child.geometry) {\r\n if (typeof child.geometry.computeBoundingBox === \"function\") {\r\n child.geometry.computeBoundingBox();\r\n }\r\n const box = child.geometry.boundingBox;\r\n if (box) {\r\n const childBox = box.clone().applyMatrix4(child.matrixWorld);\r\n boundingBox.union(childBox);\r\n hasBox = true;\r\n }\r\n }\r\n });\r\n }\r\n\r\n return hasBox ? boundingBox : new this.THREE.Box3();\r\n }\r\n}\r\n\r\nexport class ThreeJSProvider implements I3DEngineProvider {\r\n private engine: ThreeJSEngine;\r\n\r\n constructor(THREE: any, loaders: Record<string, any> = {}) {\r\n this.engine = new ThreeJSEngine(THREE, loaders);\r\n }\r\n\r\n getEngine(): I3DEngine {\r\n return this.engine;\r\n }\r\n\r\n getName(): string {\r\n return \"Three.js\";\r\n }\r\n}\r\n"],"mappings":"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","names":["index_exports","__export","String3D","String3DCamera","String3DObject","String3DRenderer","String3DScene","String3DSynchronizer","ThreeJSEngine","ThreeJSProvider","__toCommonJS","import_string_tune","String3DCamera","engine","mode","fov","near","far","width","height","ortho","x","y","z","screenX","screenY","normalizedX","normalizedY","distance","viewportHeight","roundedZ","scale","String3DRenderer","container","engine","width","height","scene","camera","String3DObject","id","type","object","engine","options","child","originalScale","matrix","pos","quat","scale","position","quaternion","euler","value","mat","texture","material","geometry","anyObj","childMat","String3DScene","engine","options","id","obj","object","type","element","onAdd","added3DObject","parentId","group","String3DObject","kind","color","intensity","light","distance","decay","geometry","material","mesh","widthSegments","heightSegments","segments","modelPath","loaderType","loader","shouldCenter","gltf","root","child","xhr","error","bbox","center","box","attr","colorRaw","opacity","metalness","roughness","params","mapSrc","normalMapSrc","roughnessMapSrc","metalnessMapSrc","aoMapSrc","flipY","colorSpace","src","texture","value","normalized","baseRaw","base","mappingRaw","mapping","manager","url","mapped","GroupSynchronizer","el","object","ctx","parentData","rect","centerX","centerY","style","translateZ","position","scale","rotateX","rotateY","rotateZ","LightSynchronizer","el","object","ctx","parentData","rect","centerX","centerY","translateZ","position","MeshSynchronizer","el","object","ctx","parentData","style","originalWidth","originalHeight","rect","translateZ","cssScale","centerX","centerY","worldPos","rotateX","rotateY","rotateZ","targetWidth","targetHeight","cssScaleZ","parentScale","objectType","scaleX","scaleY","scaleZ","uniformSize","size","fitMode","modelScaleAttr","modelScale","scaleToWidth","scaleToHeight","uniformScale","fallbackSize","cylRadius","String3DSynchronizer","camera","viewportWidth","viewportHeight","engine","MeshSynchronizer","GroupSynchronizer","LightSynchronizer","el","object","parentData","strategy","width","height","import_string_tune","_String3D","context","provider","object","result","globalId","element","attributes","parentElement","parentId","String3DRenderer","String3DCamera","modelLoader","modelLoaderFactory","String3DScene","String3DSynchronizer","key","fallback","error","engine","type","loaderType","existing","container","el","data","obj","parentData","child","style","String3D","ThreeJSEngine","THREE","loaders","x","y","z","w","order","min","max","options","renderer","fov","aspect","near","far","left","right","top","bottom","geometry","material","width","height","depth","radius","widthSegments","heightSegments","radiusTop","radiusBottom","segments","params","color","intensity","distance","decay","type","LoaderClass","degrees","radians","object","boundingBox","hasBox","child","box","childBox","ThreeJSProvider"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -152,6 +152,9 @@ interface String3DOptions {
|
|
|
152
152
|
hideHTML?: boolean;
|
|
153
153
|
container?: string | HTMLElement;
|
|
154
154
|
zIndex?: number;
|
|
155
|
+
modelLoaderType?: string;
|
|
156
|
+
modelLoader?: I3DModelLoader;
|
|
157
|
+
modelLoaderFactory?: (engine: I3DEngine, type?: string) => I3DModelLoader;
|
|
155
158
|
}
|
|
156
159
|
declare class String3D extends StringModule {
|
|
157
160
|
private static provider;
|
|
@@ -164,11 +167,16 @@ declare class String3D extends StringModule {
|
|
|
164
167
|
private isLoading;
|
|
165
168
|
private options;
|
|
166
169
|
static setProvider(provider: I3DEngineProvider): void;
|
|
167
|
-
constructor(context: StringContext
|
|
170
|
+
constructor(context: StringContext);
|
|
168
171
|
canConnect(object: StringObject): boolean;
|
|
169
172
|
initializeObject(globalId: number, object: StringObject, element: HTMLElement, attributes: Record<string, any>): void;
|
|
170
173
|
onResize(): void;
|
|
171
174
|
onInit(): void;
|
|
175
|
+
onSettingsChange(): void;
|
|
176
|
+
private buildOptionsFromSettings;
|
|
177
|
+
private getSettingValue;
|
|
178
|
+
private resolveModelLoader;
|
|
179
|
+
private resolveModelLoaderFactory;
|
|
172
180
|
private createOrGetContainer;
|
|
173
181
|
private applyContainerStyles;
|
|
174
182
|
onObjectConnected(object: StringObject): void;
|
|
@@ -220,7 +228,11 @@ declare class String3DObject {
|
|
|
220
228
|
private _children;
|
|
221
229
|
private engine;
|
|
222
230
|
get children(): String3DObject[];
|
|
223
|
-
constructor(id: string, type: string, object: I3DObject, engine: I3DEngine
|
|
231
|
+
constructor(id: string, type: string, object: I3DObject, engine: I3DEngine, options?: {
|
|
232
|
+
material?: I3DMaterial;
|
|
233
|
+
geometry?: I3DGeometry;
|
|
234
|
+
texture?: any;
|
|
235
|
+
});
|
|
224
236
|
get object(): I3DObject;
|
|
225
237
|
get material(): I3DMaterial | undefined;
|
|
226
238
|
get originalSize(): I3DVector3;
|
|
@@ -239,19 +251,28 @@ declare class String3DObject {
|
|
|
239
251
|
set metalness(value: number);
|
|
240
252
|
set roughness(value: number);
|
|
241
253
|
set texture(texture: any);
|
|
254
|
+
set material(material: I3DMaterial | undefined);
|
|
255
|
+
set geometry(geometry: I3DGeometry | undefined);
|
|
242
256
|
updateBoundingBox(): void;
|
|
243
257
|
destroy(): void;
|
|
258
|
+
private disposeObjectResources;
|
|
244
259
|
}
|
|
245
260
|
|
|
261
|
+
interface String3DSceneOptions {
|
|
262
|
+
modelLoader?: I3DModelLoader;
|
|
263
|
+
modelLoaderFactory?: (engine: I3DEngine, type?: string) => I3DModelLoader;
|
|
264
|
+
}
|
|
246
265
|
declare class String3DScene {
|
|
247
266
|
private _scene;
|
|
248
267
|
private _objects;
|
|
249
268
|
private _rootObjects;
|
|
250
269
|
private _elementMap;
|
|
251
270
|
private engine;
|
|
252
|
-
private _modelLoader
|
|
271
|
+
private _modelLoader?;
|
|
272
|
+
private _modelLoaderFactory?;
|
|
273
|
+
private _modelLoaderCache;
|
|
253
274
|
get rootObjects(): String3DObject[];
|
|
254
|
-
constructor(engine: I3DEngine,
|
|
275
|
+
constructor(engine: I3DEngine, options?: String3DSceneOptions);
|
|
255
276
|
getScene(): I3DScene;
|
|
256
277
|
getObject(id: string): String3DObject | undefined;
|
|
257
278
|
hasObject(id: string): boolean;
|
|
@@ -264,8 +285,15 @@ declare class String3DScene {
|
|
|
264
285
|
private createPlane;
|
|
265
286
|
private createCylinder;
|
|
266
287
|
private createModel;
|
|
288
|
+
private resolveModelLoader;
|
|
289
|
+
private centerObject;
|
|
290
|
+
private getBoxCenter;
|
|
267
291
|
private createMaterialFromObject;
|
|
292
|
+
private createMaterialFromElement;
|
|
268
293
|
private loadTexture;
|
|
294
|
+
private parseFlipY;
|
|
295
|
+
private shouldOverrideModelMaterial;
|
|
296
|
+
private applyModelTextureRemap;
|
|
269
297
|
destroy(): void;
|
|
270
298
|
}
|
|
271
299
|
|