string-tune-3d 0.0.4 → 0.0.5
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 +137 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +51 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.js +137 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +137 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/readme.md +50 -50
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../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":["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":["StringModule","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","frameDOM","_String3D","StringModule","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"]}
|
|
1
|
+
{"version":3,"sources":["../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/core/transform/TransformWorkerClient.ts","../src/adapters/ThreeJSProvider.ts"],"sourcesContent":["import { StringModule } from \"@fiddle-digital/string-tune\";\nimport { StringObject } from \"@fiddle-digital/string-tune\";\nimport { StringData } from \"@fiddle-digital/string-tune\";\nimport { StringContext } from \"@fiddle-digital/string-tune\";\nimport { String3DCamera } from \"../core/String3DCamera\";\nimport { String3DRenderer } from \"../core/String3DRenderer\";\nimport { String3DScene } from \"../core/String3DScene\";\nimport { String3DSynchronizer } from \"../core/synchronizer/String3DSynchronizer\";\nimport { I3DEngineProvider } from \"../core/abstractions/I3DEngineProvider\";\nimport { I3DEngine, I3DModelLoader } from \"../core/abstractions/I3DEngine\";\nimport { frameDOM } from \"@fiddle-digital/string-tune\";\nimport { MeshSynchronizer } from \"../core/synchronizer/MeshSynchronizer\";\nimport { String3DObject } from \"../core/String3DObject\";\nimport {\n TransformWorkerClient,\n TransformWorkerInput,\n TransformWorkerCamera,\n TransformWorkerResult,\n} from \"../core/transform/TransformWorkerClient\";\n\nexport interface String3DOptions {\n hideHTML?: boolean;\n container?: string | HTMLElement;\n zIndex?: number;\n modelLoaderType?: string;\n modelLoader?: I3DModelLoader;\n modelLoaderFactory?: (engine: I3DEngine, type?: string) => I3DModelLoader;\n useDirtySync?: boolean;\n useTransformWorker?: boolean;\n transformWorkerWasmUrl?: string;\n}\n\nexport class String3D extends StringModule {\n private static provider: I3DEngineProvider | null = null;\n\n private renderer: String3DRenderer | null = null;\n private camera: String3DCamera | null = null;\n private scene: String3DScene | null = null;\n private synchronizer: String3DSynchronizer | null = null;\n private engine: I3DEngine | null = null;\n private canvasContainer: HTMLElement | null = null;\n private isLoading: Map<string, boolean> = new Map();\n private options: String3DOptions;\n private useDirtySync = false;\n private dirtyElements: Set<HTMLElement> = new Set();\n private observedElements: Set<HTMLElement> = new Set();\n private resizeObserver: ResizeObserver | null = null;\n private mutationObserver: MutationObserver | null = null;\n private lastSyncData: WeakMap<String3DObject, { scale: number }> = new WeakMap();\n private transformWorker: TransformWorkerClient | null = null;\n private workerHasResult = false;\n private workerObjectMap: Map<string, { object: String3DObject; el: HTMLElement }> = new Map();\n private domVersion = 0;\n private lastSubmittedVersion = 0;\n private scrollTicking = false;\n private onScrollBound = () => this.handleScroll();\n\n public static setProvider(provider: I3DEngineProvider): void {\n String3D.provider = provider;\n }\n\n constructor(context: StringContext) {\n super(context);\n this.htmlKey = \"3d\";\n this.options = this.buildOptionsFromSettings();\n\n this.attributesToMap = [\n ...this.attributesToMap,\n { key: \"3d\", type: \"string\", fallback: \"box\" },\n { key: \"3d-material\", type: \"string\", fallback: \"basic[#ffffff]\" },\n { key: \"3d-color\", type: \"string\", fallback: \"#ffffff\" },\n { key: \"3d-opacity\", type: \"number\", fallback: 1 },\n { key: \"3d-intensity\", type: \"number\", fallback: 1 },\n { key: \"3d-distance\", type: \"number\", fallback: 1000 },\n { key: \"3d-decay\", type: \"number\", fallback: 0 },\n { key: \"3d-model\", type: \"string\", fallback: \"\" },\n { key: \"3d-segments\", type: \"number\", fallback: 32 },\n { key: \"3d-segments-width\", type: \"number\", fallback: 32 },\n { key: \"3d-segments-height\", type: \"number\", fallback: 32 },\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 { key: \"3d-cast-shadow\", type: \"boolean\", fallback: false },\n { key: \"3d-receive-shadow\", type: \"boolean\", fallback: false },\n { key: \"3d-shadow-bias\", type: \"number\", fallback: 0 },\n { key: \"3d-shadow-map-size\", type: \"number\", fallback: 512 },\n { key: \"3d-angle\", type: \"number\", fallback: Math.PI / 3 },\n { key: \"3d-penumbra\", type: \"number\", fallback: 0 },\n { key: \"3d-ground-color\", type: \"string\", fallback: \"#ffffff\" },\n { key: \"3d-target\", type: \"string\", fallback: \"\" },\n ];\n }\n\n override canConnect(object: StringObject): boolean {\n const result = super.canConnect(object);\n console.log(\n \"[String3D] canConnect:\",\n object.id,\n \"keys:\",\n object.keys,\n \"htmlKey:\",\n this.htmlKey,\n \"result:\",\n result\n );\n return result;\n }\n\n override initializeObject(\n globalId: number,\n object: StringObject,\n element: HTMLElement,\n attributes: Record<string, any>\n ): void {\n super.initializeObject(globalId, object, element, attributes);\n\n object.setProperty(\"parentId\", null);\n const parentElement = element.parentElement?.closest(\n '[string-3d=\"group\"]'\n ) as HTMLElement | null;\n if (parentElement) {\n const parentId = parentElement.getAttribute(\"string-id\");\n if (parentId) {\n object.setProperty(\"parentId\", parentId);\n object.setProperty(\"parent\", parentElement);\n }\n }\n }\n\n override onResize(): void {\n if (this.renderer && this.camera && this.synchronizer) {\n this.renderer.resize(this.camera);\n this.synchronizer.updateViewportSize(this.renderer.width, this.renderer.height);\n this.camera.clearScaleCache();\n if (this.useDirtySync) {\n this.markAllDirty();\n }\n }\n }\n\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\n this.engine = String3D.provider.getEngine();\n this.canvasContainer = this.createOrGetContainer();\n this.registerTypedProperties();\n this.injectCSS();\n this.useDirtySync = !!this.options.useDirtySync;\n if (this.useDirtySync) {\n this.setupObservers();\n this.setupScrollListeners();\n }\n\n this.renderer = new String3DRenderer(this.canvasContainer, this.engine);\n this.renderer.attach();\n\n this.camera = new String3DCamera(this.engine, \"orthographic\");\n this.camera.setPosition(0, 0, 1000);\n this.camera.resize(this.renderer.width, this.renderer.height);\n\n const modelLoader = this.resolveModelLoader();\n const modelLoaderFactory = this.resolveModelLoaderFactory();\n this.scene = new String3DScene(this.engine, {\n modelLoader,\n modelLoaderFactory,\n });\n this.scene.getScene().add(this.camera.camera);\n\n this.synchronizer = new String3DSynchronizer(\n this.camera,\n this.renderer.width,\n this.renderer.height,\n this.engine\n );\n\n if (this.options.useTransformWorker) {\n this.transformWorker = new TransformWorkerClient({\n wasmUrl: this.options.transformWorkerWasmUrl,\n });\n }\n\n console.info(`[String3D] Initialized with: ${String3D.provider.getName()}`);\n }\n\n override onSettingsChange(): void {\n this.options = this.buildOptionsFromSettings();\n const shouldUseDirtySync = !!this.options.useDirtySync;\n if (shouldUseDirtySync && !this.useDirtySync) {\n this.useDirtySync = true;\n this.setupObservers();\n this.setupScrollListeners();\n this.observeSceneElements();\n this.markAllDirty();\n } else if (!shouldUseDirtySync && this.useDirtySync) {\n this.useDirtySync = false;\n this.removeScrollListeners();\n this.resizeObserver?.disconnect();\n this.mutationObserver?.disconnect();\n this.dirtyElements.clear();\n }\n\n const shouldUseWorker = !!this.options.useTransformWorker;\n if (shouldUseWorker && !this.transformWorker) {\n this.transformWorker = new TransformWorkerClient({\n wasmUrl: this.options.transformWorkerWasmUrl,\n });\n this.workerHasResult = false;\n } else if (!shouldUseWorker && this.transformWorker) {\n this.transformWorker.destroy();\n this.transformWorker = null;\n this.workerHasResult = false;\n }\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 useDirtySync: this.getSettingValue(\"useDirtySync\", false),\n useTransformWorker: this.getSettingValue(\"useTransformWorker\", false),\n transformWorkerWasmUrl: this.getSettingValue(\"transformWorkerWasmUrl\", 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\n private resolveModelLoader(): I3DModelLoader | undefined {\n if (!this.engine) return undefined;\n if (this.options.modelLoader) return this.options.modelLoader;\n if (this.options.modelLoaderFactory) return undefined;\n if (this.options.modelLoaderType) {\n try {\n return this.engine.createModelLoader(this.options.modelLoaderType);\n } catch (error) {\n console.warn(\"[String3D] Failed to create model loader:\", error);\n }\n }\n return undefined;\n }\n\n private resolveModelLoaderFactory():\n | ((engine: I3DEngine, type?: string) => I3DModelLoader)\n | undefined {\n if (!this.engine) return undefined;\n if (this.options.modelLoaderFactory) return this.options.modelLoaderFactory;\n if (this.options.modelLoaderType) {\n return (engine: I3DEngine, type?: string) => {\n const loaderType = type || this.options.modelLoaderType;\n if (!loaderType) {\n throw new Error(\"[String3D] Model loader type not provided\");\n }\n return engine.createModelLoader(loaderType);\n };\n }\n return undefined;\n }\n\n private createOrGetContainer(): HTMLElement {\n if (this.options.container instanceof HTMLElement) {\n this.applyContainerStyles(this.options.container);\n return this.options.container;\n }\n\n if (typeof this.options.container === \"string\") {\n const existing = document.getElementById(this.options.container);\n if (existing) {\n this.applyContainerStyles(existing);\n return existing;\n }\n }\n\n const container = document.createElement(\"div\");\n container.id = \"string-3d-canvas\";\n this.applyContainerStyles(container);\n document.body.insertBefore(container, document.body.firstChild);\n return container;\n }\n\n private applyContainerStyles(el: HTMLElement): void {\n Object.assign(el.style, {\n position: \"fixed\",\n left: \"0\",\n top: \"0\",\n width: \"100vw\",\n height: \"100lvh\",\n zIndex: String(this.options.zIndex),\n pointerEvents: \"none\",\n });\n }\n\n override onObjectConnected(object: StringObject): void {\n if (this.isLoading.has(object.id) || !this.scene) return;\n this.isLoading.set(object.id, true);\n\n this.scene.createFromElement(object);\n\n if (this.useDirtySync && object.htmlElement) {\n this.observeElement(object.htmlElement);\n this.markDirty(object.htmlElement);\n }\n\n if (this.options.hideHTML && object.htmlElement) {\n object.htmlElement.style.opacity = \"0\";\n object.htmlElement.style.pointerEvents = \"none\";\n }\n }\n\n override onFrame(data: StringData): void {\n if (!this.renderer || !this.scene || !this.camera || !this.synchronizer) return;\n\n const workerResults = this.transformWorker?.takeLastResult();\n if (\n workerResults &&\n workerResults.frameId === this.lastSubmittedVersion &&\n workerResults.frameId >= this.domVersion\n ) {\n this.workerHasResult = true;\n this.applyWorkerResults(workerResults.results);\n }\n\n const dirtySet = this.useDirtySync ? this.dirtyElements : null;\n // If dirty sync is enabled but nothing is marked dirty, we still sync everything to keep CSS-driven effects (hover/animations) fluid.\n const forceSync = !dirtySet || dirtySet.size === 0;\n const worker = this.transformWorker;\n\n // Collect and submit worker inputs only when the worker is free\n if (worker?.isReady() && !worker.isPending()) {\n const inputs: TransformWorkerInput[] = [];\n this.workerObjectMap.clear();\n this.scene!.rootObjects.forEach((obj) => {\n this.collectWorkerInputs(obj, { scale: 1 }, forceSync, dirtySet, inputs);\n });\n if (inputs.length > 0) {\n const frameId = this.domVersion;\n this.lastSubmittedVersion = frameId;\n worker.submit(inputs, this.buildWorkerCameraData(), frameId);\n }\n }\n\n // Always do immediate CPU sync to avoid frame lag while worker is pending\n this.scene!.rootObjects.forEach((obj) => {\n this.syncRecursive(obj.el, obj, { scale: 1 }, forceSync, dirtySet);\n });\n\n if (this.useDirtySync) {\n this.dirtyElements.clear();\n }\n\n this.renderer!.render(this.scene!, this.camera!);\n }\n\n private syncRecursive(\n el: HTMLElement | undefined,\n object: String3DObject,\n parentData: any,\n forceSync: boolean,\n dirtySet: Set<HTMLElement> | null\n ): void {\n if (!this.synchronizer || !el) return;\n const shouldSync = forceSync || !dirtySet || dirtySet.has(el);\n let nextParentData = parentData;\n\n if (shouldSync) {\n const data = this.synchronizer.syncElement(el, object, parentData);\n if (data && typeof data.scale === \"number\") {\n this.lastSyncData.set(object, data);\n nextParentData = data;\n }\n } else {\n const cached = this.lastSyncData.get(object);\n if (cached) {\n nextParentData = cached;\n }\n }\n\n const forceChildren = forceSync || shouldSync;\n object.children.forEach((child) =>\n this.syncRecursive(child.el, child, nextParentData, forceChildren, dirtySet)\n );\n }\n\n private injectCSS(): void {\n if (document.getElementById(\"string-3d-styles\")) return;\n\n const style = document.createElement(\"style\");\n style.id = \"string-3d-styles\";\n style.textContent = `\n @property --translate-x { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --translate-y { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --translate-z { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --rotate-x { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --rotate-y { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --rotate-z { syntax: \"<number>\"; inherits: false; initial-value: 0; }\n @property --scale { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n @property --scale-x { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n @property --scale-y { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n @property --scale-z { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n @property --opacity { syntax: \"<number>\"; inherits: false; initial-value: 1; }\n\n [string-3d] {\n --translate-x: 0; --translate-y: 0; --translate-z: 0;\n --rotate-x: 0; --rotate-y: 0; --rotate-z: 0;\n --scale: 1; --scale-x: 1; --scale-y: 1; --scale-z: 1;--opacity: 1;\n transform-style: preserve-3d;\n }\n\n [string-3d-visual=\"true\"] {\n transform:\n translate3d(calc(var(--translate-x) * 1px), calc(var(--translate-y) * 1px), calc(var(--translate-z) * 1px))\n rotateX(calc(var(--rotate-x) * 1deg))\n rotateY(calc(var(--rotate-y) * 1deg))\n rotateZ(calc(var(--rotate-z) * 1deg))\n scale3d(calc(var(--scale) * var(--scale-x)), calc(var(--scale) * var(--scale-y)), calc(var(--scale) * var(--scale-z)));\n }\n `;\n document.head.appendChild(style);\n }\n\n private registerTypedProperties(): void {\n const css = (globalThis as any).CSS;\n if (!css?.registerProperty) return;\n\n const props: Array<{ name: string; initialValue: string }> = [\n { name: \"--translate-x\", initialValue: \"0\" },\n { name: \"--translate-y\", initialValue: \"0\" },\n { name: \"--translate-z\", initialValue: \"0\" },\n { name: \"--rotate-x\", initialValue: \"0\" },\n { name: \"--rotate-y\", initialValue: \"0\" },\n { name: \"--rotate-z\", initialValue: \"0\" },\n { name: \"--scale\", initialValue: \"1\" },\n { name: \"--scale-x\", initialValue: \"1\" },\n { name: \"--scale-y\", initialValue: \"1\" },\n { name: \"--scale-z\", initialValue: \"1\" },\n { name: \"--opacity\", initialValue: \"1\" },\n ];\n\n props.forEach(({ name, initialValue }) => {\n try {\n css.registerProperty({\n name,\n syntax: \"<number>\",\n inherits: false,\n initialValue,\n });\n } catch {\n // Property may already be registered; ignore.\n }\n });\n }\n\n private setupObservers(): void {\n if (typeof ResizeObserver !== \"undefined\") {\n this.resizeObserver = new ResizeObserver((entries) => {\n entries.forEach((entry) => {\n if (entry.target instanceof HTMLElement) {\n this.markDirty(entry.target);\n }\n });\n });\n }\n\n if (typeof MutationObserver !== \"undefined\") {\n this.mutationObserver = new MutationObserver((mutations) => {\n mutations.forEach((mutation) => {\n if (mutation.target instanceof HTMLElement) {\n this.markDirty(mutation.target);\n }\n });\n });\n }\n }\n\n private setupScrollListeners(): void {\n window.addEventListener(\"scroll\", this.onScrollBound, { passive: true });\n window.addEventListener(\"resize\", this.onScrollBound, { passive: true });\n if (window.visualViewport) {\n window.visualViewport.addEventListener(\"scroll\", this.onScrollBound, { passive: true });\n window.visualViewport.addEventListener(\"resize\", this.onScrollBound, { passive: true });\n }\n }\n\n private removeScrollListeners(): void {\n window.removeEventListener(\"scroll\", this.onScrollBound);\n window.removeEventListener(\"resize\", this.onScrollBound);\n if (window.visualViewport) {\n window.visualViewport.removeEventListener(\"scroll\", this.onScrollBound);\n window.visualViewport.removeEventListener(\"resize\", this.onScrollBound);\n }\n }\n\n private handleScroll(): void {\n if (!this.useDirtySync) return;\n this.markAllDirty();\n }\n\n private observeElement(el: HTMLElement): void {\n if (this.observedElements.has(el)) return;\n this.observedElements.add(el);\n\n this.resizeObserver?.observe(el);\n this.mutationObserver?.observe(el, {\n attributes: true,\n attributeFilter: [\n \"style\",\n \"class\",\n \"string-3d\",\n \"string-3d-model-fit\",\n \"string-3d-model-scale\",\n \"string-3d-cast-shadow\",\n \"string-3d-receive-shadow\",\n \"string-3d-opacity\",\n \"string-3d-target\",\n ],\n });\n }\n\n private observeSceneElements(): void {\n if (!this.scene) return;\n this.scene.rootObjects.forEach((obj) => {\n this.observeRecursive(obj);\n });\n }\n\n private observeRecursive(object: String3DObject): void {\n if (object.el instanceof HTMLElement) {\n this.observeElement(object.el);\n }\n object.children.forEach((child) => this.observeRecursive(child));\n }\n\n private markDirty(el: HTMLElement): void {\n this.dirtyElements.add(el);\n this.domVersion += 1;\n }\n\n private markAllDirty(): void {\n this.observedElements.forEach((el) => this.dirtyElements.add(el));\n this.domVersion += 1;\n }\n\n private readNumberStyle(el: HTMLElement, prop: string, fallback: number): number {\n const styleMap = (el as any).computedStyleMap?.();\n const mapValue = styleMap?.get?.(prop);\n if (mapValue !== undefined) {\n if (typeof mapValue === \"number\") return mapValue;\n if (typeof mapValue === \"string\") {\n const parsed = Number.parseFloat(mapValue);\n if (!Number.isNaN(parsed)) return parsed;\n }\n if (mapValue && typeof mapValue === \"object\") {\n const value = (mapValue as any).value;\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n if (!Number.isNaN(parsed)) return parsed;\n }\n }\n }\n\n const style = getComputedStyle(el);\n const raw = style.getPropertyValue(prop);\n const parsed = Number.parseFloat(raw);\n return Number.isNaN(parsed) ? fallback : parsed;\n }\n\n private buildWorkerCameraData(): TransformWorkerCamera {\n return {\n mode: this.camera!.getMode(),\n width: this.renderer!.width,\n height: this.renderer!.height,\n cameraZ: this.camera!.getPositionZ(),\n fov: this.camera!.getPerspectiveFov(),\n aspect: this.renderer!.width / this.renderer!.height,\n };\n }\n\n private collectWorkerInputs(\n object: String3DObject,\n parentData: { scale: number },\n forceSync: boolean,\n dirtySet: Set<HTMLElement> | null,\n inputs: TransformWorkerInput[]\n ): void {\n if (!this.synchronizer || !object.el) return;\n const el = object.el as HTMLElement;\n const shouldSync = forceSync || !dirtySet || dirtySet.has(el);\n let nextParentData = parentData;\n\n if (object.type.endsWith(\"Light\")) {\n if (shouldSync) {\n this.synchronizer.syncElement(el, object, parentData);\n }\n return;\n }\n\n if (shouldSync) {\n const rect = el.getBoundingClientRect();\n const layoutWidth = el.offsetWidth || rect.width;\n const layoutHeight = el.offsetHeight || rect.height;\n const translateZ = this.readNumberStyle(el, \"--translate-z\", 0);\n const scale = this.readNumberStyle(el, \"--scale\", 1);\n const scaleZ = this.readNumberStyle(el, \"--scale-z\", 1);\n const rotateX = this.readNumberStyle(el, \"--rotate-x\", 0);\n const rotateY = this.readNumberStyle(el, \"--rotate-y\", 0);\n const rotateZ = this.readNumberStyle(el, \"--rotate-z\", 0);\n const opacity = this.readNumberStyle(el, \"--opacity\", NaN);\n\n if (object.type !== \"group\") {\n MeshSynchronizer.applyVisualProps(el, object, opacity);\n }\n\n let modelSizeX: number | undefined;\n let modelSizeY: number | undefined;\n let modelScale: number | undefined;\n let fitMode: string | undefined;\n\n if (object.type === \"model\") {\n const bbox = object.getOriginalBoundingBox();\n const size = bbox.getSize(this.engine!.createVector3());\n modelSizeX = size.x;\n modelSizeY = size.y;\n const modelScaleAttr = parseFloat(el.getAttribute(\"string-3d-model-scale\") || \"1\");\n modelScale = Number.isFinite(modelScaleAttr) ? modelScaleAttr : 1;\n fitMode = (el.getAttribute(\"string-3d-model-fit\") || \"contain\").toLowerCase().trim();\n }\n\n const returnScale = object.type === \"group\" ? scale : scale * parentData.scale;\n this.lastSyncData.set(object, { scale: returnScale });\n nextParentData = { scale: returnScale };\n\n this.workerObjectMap.set(object.id, { object, el });\n inputs.push({\n id: object.id,\n type: object.type,\n rectLeft: rect.left,\n rectTop: rect.top,\n rectWidth: layoutWidth,\n rectHeight: layoutHeight,\n translateZ,\n scale,\n scaleZ,\n rotateX,\n rotateY,\n rotateZ,\n parentScale: parentData.scale,\n modelSizeX,\n modelSizeY,\n modelScale,\n fitMode,\n });\n } else {\n const cached = this.lastSyncData.get(object);\n if (cached) {\n nextParentData = cached;\n }\n }\n\n const forceChildren = forceSync || shouldSync;\n object.children.forEach((child) => {\n this.collectWorkerInputs(child, nextParentData, forceChildren, dirtySet, inputs);\n });\n }\n\n private applyWorkerResults(results: TransformWorkerResult[]): void {\n if (!this.engine) return;\n results.forEach((result) => {\n const entry = this.workerObjectMap.get(result.id);\n if (!entry) return;\n const object = entry.object;\n object.position = this.engine!.createVector3(result.posX, result.posY, result.posZ);\n object.rotation = this.engine!.createEuler(result.rotX, result.rotY, result.rotZ, \"XYZ\");\n object.scale = this.engine!.createVector3(result.scaleX, result.scaleY, result.scaleZ);\n if (object.type === \"group\") {\n object.object.updateMatrixWorld(true);\n }\n });\n }\n\n override destroy(): void {\n this.renderer?.destroy();\n this.scene?.destroy();\n this.isLoading.clear();\n this.transformWorker?.destroy();\n this.transformWorker = null;\n this.removeScrollListeners();\n this.resizeObserver?.disconnect();\n this.mutationObserver?.disconnect();\n this.observedElements.clear();\n this.dirtyElements.clear();\n this.workerObjectMap.clear();\n this.lastSyncData = new WeakMap();\n\n const styleEl = document.getElementById(\"string-3d-styles\");\n styleEl?.remove();\n\n if (this.canvasContainer?.id === \"string-3d-canvas\") {\n this.canvasContainer.remove();\n }\n\n super.destroy();\n }\n}\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 {\n return this.mode;\n }\n\n public getPerspectiveFov(): number {\n return this.perspectiveFov;\n }\n\n public getPositionZ(): number {\n return this._position.z;\n }\n}\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 if (this._renderer.shadowMap) {\r\n this._renderer.shadowMap.enabled = true;\r\n }\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\n public getScene(): I3DScene {\n return this._scene;\n }\n\n public getObject(id: string): String3DObject | undefined {\n return this._objects.get(id);\n }\n\n public hasObject(id: string): boolean {\n return this._objects.has(id);\n }\n\n public deleteObject(id: string): boolean {\n const obj = this._objects.get(id);\n if (obj) {\n this._scene.remove(obj.object);\n this._objects.delete(id);\n obj.destroy();\n return true;\n }\n return false;\n }\n\n public createFromElement(object: StringObject): void {\n const type = object.getProperty<string>(\"3d\");\n if (!type) return;\n\n const element = object.htmlElement;\n if (!element) return;\n\n const onAdd = (added3DObject: String3DObject) => {\n if (added3DObject) {\n const parentId = object.getProperty<string>(\"parentId\");\n if (parentId == null) {\n this._scene.add(added3DObject.object);\n this._rootObjects.push(added3DObject);\n } else {\n this._objects.get(parentId)?.addChild(added3DObject);\n }\n this._objects.set(object.id, added3DObject);\n this._elementMap.set(object.id, element);\n added3DObject.el = element;\n }\n };\n\n switch (type) {\n case \"group\":\n this.createGroup(object, onAdd);\n break;\n case \"pointLight\":\n this.createLight(object, \"point\", onAdd);\n break;\n case \"ambientLight\":\n this.createLight(object, \"ambient\", onAdd);\n break;\n case \"directionalLight\":\n this.createLight(object, \"directional\", onAdd);\n break;\n case \"spotLight\":\n this.createLight(object, \"spot\", onAdd);\n break;\n case \"hemisphereLight\":\n this.createLight(object, \"hemisphere\", onAdd);\n break;\n case \"model\":\n this.createModel(object, onAdd);\n break;\n case \"box\":\n this.createBox(object, onAdd);\n break;\n case \"sphere\":\n this.createSphere(object, onAdd);\n break;\n case \"plane\":\n this.createPlane(object, onAdd);\n break;\n case \"cylinder\":\n this.createCylinder(object, onAdd);\n break;\n }\n }\n\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 }\n\n private createLight(\n object: StringObject,\n kind: \"point\" | \"ambient\" | \"directional\" | \"spot\" | \"hemisphere\",\n onAdd: (obj: String3DObject) => void\n ): String3DObject {\n const color = object.getProperty<string>(\"3d-color\") || \"#ffffff\";\n const intensity = object.getProperty<number>(\"3d-intensity\") ?? 1;\n\n let light: I3DLight;\n if (kind === \"point\") {\n const distance = object.getProperty<number>(\"3d-distance\") ?? 1000;\n const decay = object.getProperty<number>(\"3d-decay\") ?? 0;\n light = this.engine.createPointLight(color, intensity, distance, decay);\n } else if (kind === \"directional\") {\n light = this.engine.createDirectionalLight(color, intensity);\n } else if (kind === \"spot\") {\n const distance = object.getProperty<number>(\"3d-distance\") ?? 0;\n const angle = object.getProperty<number>(\"3d-angle\") ?? Math.PI / 3;\n const penumbra = object.getProperty<number>(\"3d-penumbra\") ?? 0;\n const decay = object.getProperty<number>(\"3d-decay\") ?? 1;\n light = this.engine.createSpotLight(color, intensity, distance, angle, penumbra, decay);\n } else if (kind === \"hemisphere\") {\n const groundColor = object.getProperty<string>(\"3d-ground-color\") || \"#ffffff\";\n light = this.engine.createHemisphereLight(color, groundColor, intensity);\n } else {\n light = this.engine.createAmbientLight(color, intensity);\n }\n\n const castShadow = object.getProperty<boolean>(\"3d-cast-shadow\") ?? false;\n if (castShadow && light.shadow) {\n light.castShadow = true;\n const bias = object.getProperty<number>(\"3d-shadow-bias\") ?? 0;\n const mapSize = object.getProperty<number>(\"3d-shadow-map-size\") ?? 512;\n light.shadow.bias = bias;\n light.shadow.mapSize.width = mapSize;\n light.shadow.mapSize.height = mapSize;\n }\n\n const obj = new String3DObject(object.id, kind + \"Light\", light, this.engine);\n onAdd(obj);\n return obj;\n }\n\n private applyShadowProps(object: StringObject, mesh: any): void {\n const castShadow = object.getProperty<boolean>(\"3d-cast-shadow\") ?? false;\n const receiveShadow = object.getProperty<boolean>(\"3d-receive-shadow\") ?? false;\n mesh.castShadow = castShadow;\n mesh.receiveShadow = receiveShadow;\n }\n\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 this.applyShadowProps(object, mesh);\n const obj = new String3DObject(object.id, \"box\", mesh, this.engine, {\n geometry,\n material,\n });\n onAdd(obj);\n return obj;\n }\n\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 this.applyShadowProps(object, mesh);\n const obj = new String3DObject(object.id, \"sphere\", mesh, this.engine, {\n geometry,\n material,\n });\n onAdd(obj);\n return obj;\n }\n\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 this.applyShadowProps(object, mesh);\n const obj = new String3DObject(object.id, \"plane\", mesh, this.engine, {\n geometry,\n material,\n });\n onAdd(obj);\n return obj;\n }\n\n private createCylinder(\n object: StringObject,\n onAdd: (obj: String3DObject) => void\n ): String3DObject {\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 this.applyShadowProps(object, mesh);\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\n const overrideMaterial =\n element && this.shouldOverrideModelMaterial(element)\n ? this.createMaterialFromElement(element, object)\n : null;\n\n if (typeof root.traverse === \"function\") {\n root.traverse((child: any) => {\n if (child.isMesh) {\n if (overrideMaterial) {\n child.material = overrideMaterial;\n }\n this.applyShadowProps(object, child);\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) => {\n console.log((xhr.loaded / xhr.total) * 100 + \"% loaded\");\n },\n (error: any) => {\n console.error(\"[String3D] Model loading error:\", error);\n }\n );\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 = !!(mapSrc || normalMapSrc || roughnessMapSrc || metalnessMapSrc || aoMapSrc);\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\n return this.engine.createMeshBasicMaterial(params);\n }\n\n private loadTexture(src: string, options: { flipY?: boolean; colorSpace?: string } = {}): 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\n public destroy(): void {\n this._objects.forEach((obj) => obj.destroy());\n this._objects.clear();\n this._rootObjects = [];\n }\n}\n","import { String3DObject } from \"../String3DObject\";\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\nimport type { SyncContext } from \"./SyncContext\";\n\ntype StyleMap = {\n get?: (prop: string) => any;\n};\n\nexport class GroupSynchronizer implements String3DObjectSyncStrategy {\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\n const rect = el.getBoundingClientRect();\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n\n const styleMap = (el as any).computedStyleMap?.() as StyleMap | undefined;\n let style: CSSStyleDeclaration | null = null;\n const getStyle = () => {\n if (!style) style = getComputedStyle(el);\n return style;\n };\n\n const readNumberStyle = (prop: string, fallback: number): number => {\n const mapValue = styleMap?.get?.(prop);\n if (mapValue !== undefined) {\n if (typeof mapValue === \"number\") return mapValue;\n if (typeof mapValue === \"string\") {\n const parsed = Number.parseFloat(mapValue);\n if (!Number.isNaN(parsed)) return parsed;\n }\n if (mapValue && typeof mapValue === \"object\") {\n const value = (mapValue as any).value;\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n if (!Number.isNaN(parsed)) return parsed;\n }\n }\n }\n\n const raw = getStyle().getPropertyValue(prop);\n const parsed = Number.parseFloat(raw);\n return Number.isNaN(parsed) ? fallback : parsed;\n };\n\n const translateZ = readNumberStyle(\"--translate-z\", 0);\n const position = ctx.camera.screenToWorld(centerX, centerY, translateZ);\n object.position = position;\n\n const scale = readNumberStyle(\"--scale\", 1);\n object.scale = ctx.engine.createVector3(scale, scale, scale);\n\n const rotateX = -ctx.engine.degToRad(readNumberStyle(\"--rotate-x\", 0));\n const rotateY = ctx.engine.degToRad(readNumberStyle(\"--rotate-y\", 0));\n const rotateZ = -ctx.engine.degToRad(readNumberStyle(\"--rotate-z\", 0));\n object.rotation = ctx.engine.createEuler(rotateX, rotateY, rotateZ, \"XYZ\");\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\nimport { I3DLight } from \"../abstractions/I3DEngine\";\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 const light = object.object as I3DLight;\r\n\r\n // Color\r\n const color = el.getAttribute(\"string-3d-color\");\r\n if (color && light.color && typeof light.color.set === \"function\") {\r\n light.color.set(color);\r\n }\r\n\r\n // Intensity\r\n const intensity = el.getAttribute(\"string-3d-intensity\");\r\n if (intensity) {\r\n light.intensity = parseFloat(intensity);\r\n }\r\n\r\n // Distance & Decay\r\n const distance = el.getAttribute(\"string-3d-distance\");\r\n if (distance && typeof light.distance !== \"undefined\") {\r\n light.distance = parseFloat(distance);\r\n }\r\n const decay = el.getAttribute(\"string-3d-decay\");\r\n if (decay && typeof light.decay !== \"undefined\") {\r\n light.decay = parseFloat(decay);\r\n }\r\n\r\n // SpotLight specific\r\n const angle = el.getAttribute(\"string-3d-angle\");\r\n if (angle && typeof light.angle !== \"undefined\") {\r\n light.angle = parseFloat(angle);\r\n }\r\n const penumbra = el.getAttribute(\"string-3d-penumbra\");\r\n if (penumbra && typeof light.penumbra !== \"undefined\") {\r\n light.penumbra = parseFloat(penumbra);\r\n }\r\n\r\n // Hemisphere specific\r\n const groundColor = el.getAttribute(\"string-3d-ground-color\");\r\n if (\r\n groundColor &&\r\n (light as any).groundColor &&\r\n typeof (light as any).groundColor.set === \"function\"\r\n ) {\r\n (light as any).groundColor.set(groundColor);\r\n }\r\n\r\n // Shadows\r\n const castShadow = el.getAttribute(\"string-3d-cast-shadow\") === \"true\";\r\n if (light.castShadow !== castShadow) {\r\n light.castShadow = castShadow;\r\n }\r\n if (castShadow && light.shadow) {\r\n const bias = el.getAttribute(\"string-3d-shadow-bias\");\r\n if (bias) light.shadow.bias = parseFloat(bias);\r\n\r\n const mapSize = el.getAttribute(\"string-3d-shadow-map-size\");\r\n if (mapSize) {\r\n const size = parseFloat(mapSize);\r\n if (light.shadow.mapSize.width !== size) {\r\n light.shadow.mapSize.width = size;\r\n light.shadow.mapSize.height = size;\r\n }\r\n }\r\n }\r\n\r\n // Target (Directional, Spot)\r\n const targetId = el.getAttribute(\"string-3d-target\");\r\n if (targetId && light.target) {\r\n const targetEl = document.querySelector(`[string-id=\"${targetId}\"]`);\r\n if (targetEl) {\r\n const tRect = targetEl.getBoundingClientRect();\r\n const tCenterX = tRect.left + tRect.width / 2;\r\n const tCenterY = tRect.top + tRect.height / 2;\r\n const tTranslateZ = parseFloat(\r\n getComputedStyle(targetEl).getPropertyValue(\"--translate-z\") || \"0\"\r\n );\r\n const tPos = ctx.camera.screenToWorld(tCenterX, tCenterY, tTranslateZ);\r\n\r\n light.target.position.copy(tPos);\r\n light.target.updateMatrixWorld(true);\r\n }\r\n }\r\n\r\n return null;\r\n }\r\n}\r\n","import { String3DObject } from \"../String3DObject\";\nimport type { SyncContext } from \"./SyncContext\";\nimport type { String3DObjectSyncStrategy } from \"./String3DObjectSyncStrategy\";\n\ntype StyleMap = {\n get?: (prop: string) => any;\n};\n\nexport class MeshSynchronizer implements String3DObjectSyncStrategy {\n static applyVisualProps(el: HTMLElement, object: String3DObject, opacityValue?: number): void {\n const castShadow = el.getAttribute(\"string-3d-cast-shadow\") === \"true\";\n const receiveShadow = el.getAttribute(\"string-3d-receive-shadow\") === \"true\";\n\n const opacity = typeof opacityValue === \"number\" ? opacityValue : NaN;\n\n if (object.object.traverse) {\n object.object.traverse((child: any) => {\n if (child.isMesh) {\n if (child.castShadow !== castShadow) child.castShadow = castShadow;\n if (child.receiveShadow !== receiveShadow) child.receiveShadow = receiveShadow;\n\n if (!isNaN(opacity)) {\n const materials = Array.isArray(child.material) ? child.material : [child.material];\n materials.forEach((mat: any) => {\n if (mat) {\n mat.opacity = opacity;\n mat.transparent = opacity < 1;\n }\n });\n }\n }\n });\n } else if ((object.object as any).isMesh) {\n const mesh = object.object as any;\n if (mesh.castShadow !== castShadow) mesh.castShadow = castShadow;\n if (mesh.receiveShadow !== receiveShadow) mesh.receiveShadow = receiveShadow;\n\n if (!isNaN(opacity)) {\n const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];\n materials.forEach((mat: any) => {\n if (mat) {\n mat.opacity = opacity;\n mat.transparent = opacity < 1;\n }\n });\n }\n }\n }\n\n sync(el: HTMLElement, object: String3DObject, ctx: SyncContext, parentData: any): any {\n const styleMap = (el as any).computedStyleMap?.() as StyleMap | undefined;\n let style: CSSStyleDeclaration | null = null;\n const getStyle = () => {\n if (!style) style = getComputedStyle(el);\n return style;\n };\n\n const rect = el.getBoundingClientRect();\n const originalWidth = el.offsetWidth || rect.width;\n const originalHeight = el.offsetHeight || rect.height;\n\n const readNumberStyle = (prop: string, fallback: number): number => {\n const mapValue = styleMap?.get?.(prop);\n if (mapValue !== undefined) {\n if (typeof mapValue === \"number\") return mapValue;\n if (typeof mapValue === \"string\") {\n const parsed = Number.parseFloat(mapValue);\n if (!Number.isNaN(parsed)) return parsed;\n }\n if (mapValue && typeof mapValue === \"object\") {\n const value = (mapValue as any).value;\n if (typeof value === \"number\") return value;\n if (typeof value === \"string\") {\n const parsed = Number.parseFloat(value);\n if (!Number.isNaN(parsed)) return parsed;\n }\n }\n }\n\n const raw = getStyle().getPropertyValue(prop);\n const parsed = Number.parseFloat(raw);\n return Number.isNaN(parsed) ? fallback : parsed;\n };\n\n const translateZ = readNumberStyle(\"--translate-z\", 0);\n const cssScale = readNumberStyle(\"--scale\", 1);\n\n const centerX = rect.left + rect.width / 2;\n const centerY = rect.top + rect.height / 2;\n\n const worldPos = ctx.camera.screenToWorld(centerX, centerY, translateZ);\n object.position = worldPos;\n\n const rotateX = -ctx.engine.degToRad(readNumberStyle(\"--rotate-x\", 0));\n const rotateY = ctx.engine.degToRad(readNumberStyle(\"--rotate-y\", 0));\n const rotateZ = -ctx.engine.degToRad(readNumberStyle(\"--rotate-z\", 0));\n object.rotation = ctx.engine.createEuler(rotateX, rotateY, rotateZ, \"XYZ\");\n\n const targetWidth = originalWidth * cssScale;\n const targetHeight = originalHeight * cssScale;\n const cssScaleZ = readNumberStyle(\"--scale-z\", 1);\n const parentScale = parentData?.scale || 1;\n\n const objectType = object.type;\n let scaleX: number, scaleY: number, scaleZ: number;\n\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\").toLowerCase().trim();\n const modelScaleAttr = parseFloat(el.getAttribute(\"string-3d-model-scale\") || \"1\");\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;\n }\n case \"plane\":\n default:\n scaleX = targetWidth * parentScale;\n scaleY = targetHeight * parentScale;\n scaleZ = Math.min(targetWidth, targetHeight) * 0.5 * cssScaleZ * parentScale;\n break;\n }\n\n object.scale = ctx.engine.createVector3(scaleX, scaleY, scaleZ);\n\n const opacity = readNumberStyle(\"--opacity\", NaN);\n MeshSynchronizer.applyVisualProps(el, object, opacity);\n\n return { scale: cssScale * parentScale };\n }\n}\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 this.strategies.set(\"spotLight\", new LightSynchronizer());\r\n this.strategies.set(\"hemisphereLight\", 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","export type TransformWorkerInput = {\n id: string;\n type: string;\n rectLeft: number;\n rectTop: number;\n rectWidth: number;\n rectHeight: number;\n translateZ: number;\n scale: number;\n scaleZ: number;\n rotateX: number;\n rotateY: number;\n rotateZ: number;\n parentScale: number;\n modelSizeX?: number;\n modelSizeY?: number;\n modelScale?: number;\n fitMode?: string;\n};\n\nexport type TransformWorkerCamera = {\n mode: \"orthographic\" | \"perspective\";\n width: number;\n height: number;\n cameraZ: number;\n fov: number;\n aspect: number;\n};\n\nexport type TransformWorkerResult = {\n id: string;\n posX: number;\n posY: number;\n posZ: number;\n rotX: number;\n rotY: number;\n rotZ: number;\n scaleX: number;\n scaleY: number;\n scaleZ: number;\n};\n\nexport type TransformWorkerJobResult = {\n frameId: number;\n results: TransformWorkerResult[];\n};\n\nexport type TransformWorkerOptions = {\n wasmUrl?: string;\n};\n\nconst WORKER_SOURCE = `\nlet wasm = null;\nlet wasmReady = false;\n\nfunction degToRad(deg) {\n return (deg * Math.PI) / 180;\n}\n\nfunction computeTransform(item, camera) {\n const centerX = item.rectLeft + item.rectWidth / 2;\n const centerY = item.rectTop + item.rectHeight / 2;\n\n let posX = 0;\n let posY = 0;\n let posZ = item.translateZ;\n\n if (camera.mode === \"orthographic\") {\n posX = centerX - camera.width / 2;\n posY = -(centerY - camera.height / 2);\n } else {\n const fov = degToRad(camera.fov);\n const distance = Math.abs(item.translateZ - camera.cameraZ);\n const height = 2 * Math.tan(fov / 2) * distance;\n const width = height * camera.aspect;\n const normalizedX = centerX / camera.width;\n const normalizedY = centerY / camera.height;\n posX = (normalizedX - 0.5) * width;\n posY = -(normalizedY - 0.5) * height;\n }\n\n const rotX = -degToRad(item.rotateX);\n const rotY = degToRad(item.rotateY);\n const rotZ = -degToRad(item.rotateZ);\n\n let scaleX = 1;\n let scaleY = 1;\n let scaleZ = 1;\n\n if (item.type === \"group\") {\n scaleX = item.scale;\n scaleY = item.scale;\n scaleZ = item.scale;\n } else {\n const targetWidth = item.rectWidth * item.scale;\n const targetHeight = item.rectHeight * item.scale;\n const parentScale = item.parentScale || 1;\n const cssScaleZ = item.scaleZ || 1;\n\n if (item.type === \"box\" || item.type === \"sphere\") {\n const uniformSize = Math.min(targetWidth, targetHeight);\n scaleX = uniformSize * parentScale;\n scaleY = uniformSize * parentScale;\n scaleZ = uniformSize * cssScaleZ * parentScale;\n } else if (item.type === \"model\") {\n const sizeX = item.modelSizeX || 0;\n const sizeY = item.modelSizeY || 0;\n const fitMode = (item.fitMode || \"contain\").toLowerCase().trim();\n const modelScale = Number.isFinite(item.modelScale) ? item.modelScale : 1;\n\n if (sizeX > 0 && sizeY > 0) {\n const scaleToWidth = targetWidth / sizeX;\n const scaleToHeight = targetHeight / sizeY;\n const uniformScale = fitMode === \"cover\"\n ? Math.max(scaleToWidth, scaleToHeight)\n : Math.min(scaleToWidth, scaleToHeight);\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 } else if (item.type === \"cylinder\") {\n const cylRadius = targetWidth;\n scaleX = cylRadius * parentScale;\n scaleY = targetHeight * parentScale;\n scaleZ = cylRadius * cssScaleZ * parentScale;\n } else {\n scaleX = targetWidth * parentScale;\n scaleY = targetHeight * parentScale;\n scaleZ = Math.min(targetWidth, targetHeight) * 0.5 * cssScaleZ * parentScale;\n }\n }\n\n return {\n id: item.id,\n posX,\n posY,\n posZ,\n rotX,\n rotY,\n rotZ,\n scaleX,\n scaleY,\n scaleZ,\n };\n}\n\nasync function initWasm(url) {\n try {\n const res = await fetch(url);\n const bytes = await res.arrayBuffer();\n const mod = await WebAssembly.instantiate(bytes, {});\n wasm = mod.instance;\n wasmReady = true;\n } catch (error) {\n wasm = null;\n wasmReady = false;\n }\n}\n\nself.onmessage = async (event) => {\n const data = event.data || {};\n if (data.type === \"init\") {\n if (data.wasmUrl) {\n await initWasm(data.wasmUrl);\n }\n self.postMessage({ type: \"ready\", wasmReady });\n return;\n }\n\n if (data.type === \"compute\") {\n const items = data.items || [];\n const camera = data.camera || {};\n const results = new Array(items.length);\n for (let i = 0; i < items.length; i += 1) {\n results[i] = computeTransform(items[i], camera);\n }\n self.postMessage({ type: \"result\", frameId: data.frameId, results });\n }\n};\n`;\n\nexport class TransformWorkerClient {\n private worker: Worker | null = null;\n private ready = false;\n private lastResult: TransformWorkerJobResult | null = null;\n private pending = false;\n\n constructor(options: TransformWorkerOptions = {}) {\n if (typeof Worker === \"undefined\") return;\n const blob = new Blob([WORKER_SOURCE], { type: \"text/javascript\" });\n this.worker = new Worker(URL.createObjectURL(blob));\n this.worker.onmessage = (event) => {\n const data = event.data || {};\n if (data.type === \"ready\") {\n this.ready = true;\n return;\n }\n if (data.type === \"result\") {\n this.lastResult = {\n frameId: typeof data.frameId === \"number\" ? data.frameId : 0,\n results: data.results || [],\n };\n this.pending = false;\n }\n };\n this.worker.postMessage({ type: \"init\", wasmUrl: options.wasmUrl });\n }\n\n public isReady(): boolean {\n return this.ready;\n }\n\n public isPending(): boolean {\n return this.pending;\n }\n\n public submit(\n items: TransformWorkerInput[],\n camera: TransformWorkerCamera,\n frameId: number\n ): void {\n if (!this.worker || !this.ready || this.pending) return;\n this.pending = true;\n this.worker.postMessage({\n type: \"compute\",\n frameId,\n items,\n camera,\n });\n }\n\n public takeLastResult(): TransformWorkerJobResult | null {\n const result = this.lastResult;\n this.lastResult = null;\n return result;\n }\n\n public destroy(): void {\n this.worker?.terminate();\n this.worker = null;\n this.ready = false;\n this.pending = false;\n this.lastResult = null;\n }\n}\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 createSpotLight(\r\n color?: string | number,\r\n intensity = 1,\r\n distance = 0,\r\n angle = Math.PI / 3,\r\n penumbra = 0,\r\n decay = 1\r\n ): I3DLight {\r\n return new this.THREE.SpotLight(color, intensity, distance, angle, penumbra, decay);\r\n }\r\n\r\n createHemisphereLight(\r\n skyColor?: string | number,\r\n groundColor?: string | number,\r\n intensity = 1\r\n ): I3DLight {\r\n return new this.THREE.HemisphereLight(skyColor, groundColor, intensity);\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":["StringModule","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","angle","penumbra","groundColor","bias","mapSize","mesh","castShadow","receiveShadow","geometry","material","widthSegments","heightSegments","segments","modelPath","loaderType","loader","shouldCenter","gltf","root","overrideMaterial","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","styleMap","style","getStyle","readNumberStyle","prop","fallback","mapValue","parsed","value","raw","translateZ","position","scale","rotateX","rotateY","rotateZ","LightSynchronizer","el","object","ctx","parentData","rect","centerX","centerY","translateZ","position","light","color","intensity","distance","decay","angle","penumbra","groundColor","castShadow","bias","mapSize","size","targetId","targetEl","tRect","tCenterX","tCenterY","tTranslateZ","tPos","MeshSynchronizer","_MeshSynchronizer","el","object","opacityValue","castShadow","receiveShadow","opacity","child","mat","mesh","ctx","parentData","styleMap","style","getStyle","rect","originalWidth","originalHeight","readNumberStyle","prop","fallback","mapValue","parsed","value","raw","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","WORKER_SOURCE","TransformWorkerClient","options","blob","event","data","items","camera","frameId","result","_String3D","StringModule","context","provider","object","result","globalId","element","attributes","parentElement","parentId","String3DRenderer","String3DCamera","modelLoader","modelLoaderFactory","String3DScene","String3DSynchronizer","TransformWorkerClient","shouldUseDirtySync","shouldUseWorker","key","fallback","error","engine","type","loaderType","existing","container","el","data","workerResults","dirtySet","forceSync","worker","inputs","obj","frameId","parentData","shouldSync","nextParentData","cached","forceChildren","child","style","css","name","initialValue","entries","entry","mutations","mutation","prop","mapValue","parsed","value","raw","rect","layoutWidth","layoutHeight","translateZ","scale","scaleZ","rotateX","rotateY","rotateZ","opacity","MeshSynchronizer","modelSizeX","modelSizeY","modelScale","fitMode","size","modelScaleAttr","returnScale","results","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","angle","penumbra","skyColor","groundColor","type","LoaderClass","degrees","radians","object","boundingBox","hasBox","child","box","childBox","ThreeJSProvider"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "string-tune-3d",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"description": "StringTune-3D is a powerful 3D graphics adapter library that provides a unified interface for working with different 3D engines like Three.js. Part of the StringTune ecosystem, it enables seamless integration and synchronization of 3D objects, scenes, cameras, and lights across various rendering engines.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"3d",
|