string-tune-3d 0.0.5 → 0.0.6
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 +118 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +127 -2
- package/dist/index.d.ts +127 -2
- package/dist/index.js +118 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +118 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,117 @@
|
|
|
1
|
-
"use strict";var StringTune3D=(()=>{var Q=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var se=Object.getOwnPropertyNames;var ne=Object.prototype.hasOwnProperty;var oe=(a,e)=>{for(var t in e)Q(a,t,{get:e[t],enumerable:!0})},ae=(a,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of se(e))!ne.call(a,i)&&i!==t&&Q(a,i,{get:()=>e[i],enumerable:!(r=ie(e,i))||r.enumerable});return a};var le=a=>ae(Q({},"__esModule",{value:!0}),a);var ge={};oe(ge,{String3D:()=>G,String3DCamera:()=>N,String3DObject:()=>P,String3DRenderer:()=>z,String3DScene:()=>_,String3DSynchronizer:()=>W,ThreeJSEngine:()=>B,ThreeJSProvider:()=>Z});var ce=class{constructor(){this.desktop={rebuild:{width:!0,height:!0,scrollHeight:!0}},this.mobile={rebuild:{width:!0,height:!0,scrollHeight:!0}}}},U=class{constructor(a){this.objectMapOnPage=new Map,this.objectsOnPage=[],this.objectMap=new Map,this.objects=[],this.htmlKey="",this._type=1,this.permissions=new ce,this.tools=a.tools,this.data=a.data,this.settings=a.settings,this.events=a.events,this.centers=a.centers,this.hover=a.hover,this.attributesToMap=[{key:"active",type:"boolean",fallback:this.settings.active},{key:"fixed",type:"boolean",fallback:this.settings.fixed},{key:"outside-container",type:"boolean",fallback:this.settings["outside-container"]},{key:"repeat",type:"boolean",fallback:this.settings.repeat},{key:"self-disable",type:"boolean",fallback:this.settings["self-disable"]},{key:"abs",type:"boolean",fallback:this.settings.abs},{key:"key",type:"string",fallback:this.settings.key},{key:"offset-top",type:"dimension",fallback:this.settings["offset-top"]},{key:"offset-bottom",type:"dimension",fallback:this.settings["offset-bottom"]},{key:"inview-top",type:"dimension",fallback:this.settings["inview-top"]},{key:"inview-bottom",type:"dimension",fallback:this.settings["inview-bottom"]},{key:"start",type:"number",fallback:(e,t,r)=>{let i=r.top;return Math.floor(i)+this.data.scroll.container.scrollTop*this.data.viewport.transformScale}},{key:"end",type:"number",fallback:(e,t,r)=>{let i=r.top,s=r.height;return i+s-this.data.scroll.transformedCurrent}},{key:"size",type:"number",fallback:(e,t,r)=>r.height},{key:"half-width",type:"number",fallback:(e,t,r)=>r.width/2},{key:"half-height",type:"number",fallback:(e,t,r)=>r.height/2},{key:"enter-el",type:"string",fallback:this.settings["enter-el"]},{key:"enter-vp",type:"string",fallback:this.settings["enter-vp"]},{key:"exit-el",type:"string",fallback:this.settings["exit-el"]},{key:"exit-vp",type:"string",fallback:this.settings["exit-vp"]}]}get type(){return this._type}initializeObject(a,e,t,r){let i=this.tools.boundingClientRect.process({element:t});for(let{key:s,type:n,fallback:o,transform:l}of this.attributesToMap){let h=typeof o=="function"?o(t,e,i):o,c=this.tools.domAttribute.process({element:t,key:s,fallback:r[s]??this.settings[s]??h}),d=this.parseAttribute(c,n,{element:t,boundingRect:i,viewportHeight:this.data.viewport.windowHeight,baseRem:this.data.viewport.baseRem});l&&(d=l(d)),e.setProperty(s,d)}}calculatePositions(a,e){let t=a.getProperty("start"),r=a.getProperty("size"),i=a.getProperty("offset-bottom"),s=a.getProperty("offset-top"),n=a.getProperty("enter-el"),o=a.getProperty("enter-vp"),l=a.getProperty("exit-el"),h=a.getProperty("exit-vp"),c=0,d=0,f=0,y=0;n==="top"&&o==="top"||n==="left"&&o==="left"?(f=-e+1,c=t-i):n==="top"&&o==="bottom"||n==="left"&&o==="right"?c=t-e-i:n==="bottom"&&o==="top"||n==="right"&&o==="left"?(f=-e-r+1,c=t+r-i):(n==="bottom"&&o==="bottom"||n==="right"&&o==="right")&&(f=-r+1,c=t-e+r-i),l==="top"&&h==="top"||l==="left"&&h==="left"?(y=-r+1,d=t+s):l==="top"&&h==="bottom"||l==="left"&&h==="right"?(y=-e-r+1,d=t-e+s):l==="bottom"&&h==="top"||l==="right"&&h==="left"?d=t+r+s:(l==="bottom"&&h==="bottom"||l==="right"&&h==="right")&&(y=-e+1,d=t-e+r+s),a.setProperty("start-bias",f),a.setProperty("end-bias",y),a.setProperty("start-position",c-this.data.scroll.topPosition),a.setProperty("end-position",d-this.data.scroll.topPosition),a.setProperty("difference-position",d-c);let v=a.getProperty("inview-top")??0,g=a.getProperty("inview-bottom")??0;a.setProperty("inview-start-position",a.getProperty("start-position")+v),a.setProperty("inview-end-position",a.getProperty("end-position")+g)}parseAttribute(a,e,t={}){if(a==null)return null;if(typeof e=="object"&&e.type==="enum")return e.values.includes(a)?a:e.values[0];switch(e){case"number":return parseFloat(a);case"boolean":return a===""||a==="true";case"json":try{return JSON.parse(a)}catch{return null}case"tuple":return a.trim().split(/\s+/);case"easing":return this.tools.easingFunction.process({easing:a});case"color":return this.tools.colorParser.process({value:a});case"dimension":return a=="0"?0:t.element!=null&&t.viewportHeight!=null&&t.baseRem!=null&&t.boundingRect!=null?this.tools.unitParser.process({value:a,element:t.element,viewportHeight:t.viewportHeight,boundingRect:t.boundingRect,baseRem:t.baseRem}):0;case"breakpoint-dimension":if(t.element!=null&&t.viewportHeight!=null&&t.baseRem!=null&&t.boundingRect!=null){let r=a.trim().split("|"),i=[];for(let s of r)if(s.includes(":")){let[n,o]=s.split(":");i.push({breakpoint:parseInt(n),value:this.tools.unitParser.process({value:`${o}|`,element:t.element,viewportHeight:t.viewportHeight,boundingRect:t.boundingRect,baseRem:t.baseRem})})}else i.push({breakpoint:0,value:this.tools.unitParser.process({value:s,element:t.element,viewportHeight:t.viewportHeight,boundingRect:t.boundingRect,baseRem:t.baseRem})});return i}default:return a}}canConnect(a){return a.keys.includes(this.htmlKey)}connectObject(a){a.connect(this),this.onObjectConnected(a)}enterObject(a,e){this.objectMap.has(a)||(this.objectMap.set(a,e),this.objects.push(e))}exitObject(a){let e=this.objectMap.get(a);if(!e)return;this.objectMap.delete(a);let t=this.objects.indexOf(e);t!==-1&&this.objects.splice(t,1)}addObject(a,e){this.objectMapOnPage.has(a)||(this.objectMapOnPage.set(a,e),this.objectsOnPage.push(e))}removeObject(a){let e=this.objectMapOnPage.get(a);if(!e)return;this.objectMapOnPage.delete(a);let t=this.objectsOnPage.indexOf(e);t!==-1&&this.objectsOnPage.splice(t,1),this.onObjectDisconnected(e)}onObjectConnected(a){}onObjectDisconnected(a){}applyToElementAndConnects(a,e,t=e){a.getProperty("self-disable")!==!0&&e(a.htmlElement),a.mirrorObjects.forEach(r=>t(r.htmlElement,r))}destroy(){this.objects=[],this.objectMap=new Map}onInit(){}onFrame(a){}onMutate(a){}onScrollMeasure(a){}onMouseMoveMeasure(a){}onResize(){}onResizeWidth(){}onScroll(a){}onDirectionChange(){}onScrollStart(){}onScrollStop(){}onScrollDirectionChange(){}onAxisChange(){}onDeviceChange(){}onScrollConfigChange(){}onSettingsChange(){}onDOMRebuild(){}onMouseMove(a){}onWheel(a){}onDOMMutate(a,e){}};var he=class{constructor(){this.pendingVars=new Map,this.pendingProps=new Map,this.isOpen=!1}begin(){this.isOpen||(this.isOpen=!0)}setVars(a,e){if(!this.isOpen){console.warn("StyleTxn: call begin() first to set custom properties.");return}let t=this.pendingVars.get(a)??{};for(let[r,i]of Object.entries(e))t[r]!==i&&(t[r]=i);this.pendingVars.set(a,t)}setProps(a,e){if(!this.isOpen){console.warn("StyleTxn: call begin() first to set standard properties.");return}let t=this.pendingProps.get(a)??{};for(let[r,i]of Object.entries(e))t[r]!==i&&(t[r]=i);this.pendingProps.set(a,t)}run(a){let e=this.isOpen;e||this.begin();try{a(),e||this.commit()}catch(t){throw e||this.cancel(),t}}commit(){if(this.isOpen){this.isOpen=!1;for(let[a,e]of this.pendingVars){let t=a.style;for(let[r,i]of Object.entries(e))t.setProperty(r,String(i))}this.pendingVars.clear();for(let[a,e]of this.pendingProps){let t=a.style;for(let[r,i]of Object.entries(e))t[r]=String(i)}this.pendingProps.clear()}}cancel(){this.pendingVars.clear(),this.pendingProps.clear(),this.isOpen=!1}},ee=new he;var be=1/240;var de=class{constructor(){this.measureQueue=[],this.mutateQueue=[],this.scheduled=!1}measure(a){this.measureQueue.push(a),this.schedule()}mutate(a){this.mutateQueue.push(a),this.schedule()}schedule(){this.scheduled||(this.scheduled=!0,requestAnimationFrame(()=>{let a=this.measureQueue;this.measureQueue=[];for(let t=0;t<a.length;t++)try{a[t]()}catch(r){console.error("Error in frameDOM measure task:",r)}let e=this.mutateQueue;this.mutateQueue=[];for(let t=0;t<e.length;t++)try{e[t]()}catch(r){console.error("Error in frameDOM mutate task:",r)}this.scheduled=!1}))}},fe=new de;var ve=Math.PI*2,Se=180/Math.PI;var te=(a=>(a.ACTIVE="-active",a.ENTERING="-entering",a.LEAVING="-leaving",a.DISABLED="-disabled",a))(te||{}),ue={PROGRESS:"--sequence-progress",DIRECTION:"--sequence-direction"},pe=class re extends U{constructor(e){super(e),this.activeStep=new Map,this.leavingStep=new Map,this.transitions=new Map,this.elementIndex=new Map,this.triggerElements=new Map,this.globalSettings=new Map,this.initialized=!1,this.onTriggerClick=t=>{let r=this.triggerElements.get(t.currentTarget);if(!r)return;let i=this.activeStep.get(r.slider)??0,s=this.getMaxStep(r.slider),n,o;if(r.step==="next"){if(n=i+1,o=1,!this.elementIndex.has(`${r.slider}[${n}]`))if(r.loop&&s>=0)n=0;else return}else if(r.step==="prev"){if(n=i-1,o=-1,n<0)if(r.loop&&s>=0)n=s;else return;if(!this.elementIndex.has(`${r.slider}[${n}]`))return}else{if(n=r.step,i===n)return;o=n>i?1:-1}this.startTransition(r.slider,n,o)},this.htmlKey="sequence",this.defaultDuration=this.settings["sequence-duration"]??600,this.attributesToMap=[...this.attributesToMap,{key:"sequence",type:"string",fallback:""},{key:"sequence-trigger",type:"string",fallback:""},{key:"entering-easing",type:"string",fallback:""},{key:"leaving-easing",type:"string",fallback:""},{key:"entering-duration",type:"string",fallback:""},{key:"leaving-duration",type:"string",fallback:""},{key:"sequence-duration",type:"string",fallback:""},{key:"active-step",type:"string",fallback:""}]}onInit(){super.onInit(),this.events.on("sequence",this.onSequenceEvent.bind(this)),this.scanStandaloneTriggers()}scanStandaloneTriggers(){let e=document.querySelectorAll("[string-sequence-trigger]:not([string-inited])");for(let t of e){let r=t.getAttribute("string-sequence-trigger"),i=r?this.parseTriggerKey(r):null;i&&(this.triggerElements.set(t,i),t.addEventListener("click",this.onTriggerClick))}}parseGlobalSettingsFromObject(e){let t=i=>e.getProperty(i),r=t("sequence-duration");this.tryParseGlobalSetting(r,"enteringDuration"),this.tryParseGlobalSetting(r,"leavingDuration"),this.tryParseGlobalSetting(t("entering-duration"),"enteringDuration"),this.tryParseGlobalSetting(t("leaving-duration"),"leavingDuration"),this.tryParseGlobalSetting(t("entering-easing"),"enteringEasing"),this.tryParseGlobalSetting(t("leaving-easing"),"leavingEasing"),this.tryParseGlobalSetting(t("active-step"),"activeStep")}tryParseGlobalSetting(e,t){if(!e)return;let r=e.match(/^(.+)\[(.+)\]$/);if(!r)return;let[,i,s]=r,n=this.globalSettings.get(i)??{};this.globalSettings.set(i,n),n[t]=t==="enteringEasing"||t==="leavingEasing"?s:parseFloat(s),this.applyGlobalSettingsToExistingObjects(i)}applyGlobalSettingsToExistingObjects(e){let t=this.globalSettings.get(e);if(t){for(let[r,i]of this.elementIndex)if(this.parseSequenceKey(r)?.slider===e){t.enteringDuration!==void 0&&(i.enteringDuration=t.enteringDuration),t.leavingDuration!==void 0&&(i.leavingDuration=t.leavingDuration);for(let s of i.objects)this.resolveEasings(s,r)}}}initializeSliders(){let e=new Set;for(let t of this.elementIndex.keys()){let r=this.parseSequenceKey(t);r&&e.add(r.slider)}for(let t of e){if(this.activeStep.has(t))continue;let r=this.globalSettings.get(t)?.activeStep??0;this.elementIndex.has(`${t}[${r}]`)||(r=0),this.switchInstant(t,r,1)}}tryApplyPendingActiveStep(e){if(this.activeStep.has(e))return;let t=this.globalSettings.get(e)?.activeStep;t!==void 0&&this.elementIndex.has(`${e}[${t}]`)&&this.switchInstant(e,t,1)}canConnect(e){return e.keys.includes("sequence")||e.keys.includes("sequence-trigger")}onObjectConnected(e){super.onObjectConnected(e),this.parseGlobalSettingsFromObject(e);let t=e.getProperty("sequence"),r=e.getProperty("sequence-trigger");if(!t&&r){let i=this.parseTriggerKey(r);i&&typeof i.step=="number"&&(t=`${i.slider}[${i.step}]`,e.setProperty("sequence",t))}if(t){let i=this.parseSequenceKey(t);if(i){let s=this.elementIndex.get(t);if(!s){let{enteringDuration:o,leavingDuration:l}=this.resolveDurations(e,t);s={objects:[],enteringDuration:o,leavingDuration:l},this.elementIndex.set(t,s)}s.objects.push(e),this.resolveEasings(e,t);let n=this.activeStep.get(i.slider);this.setState(e,n===i.step?"-active":"-disabled",n===i.step?1:0,1),this.tryApplyPendingActiveStep(i.slider)}}if(r){let i=this.parseTriggerKey(r);i&&(this.triggerElements.set(e.htmlElement,i),e.htmlElement.addEventListener("click",this.onTriggerClick))}}parseTriggerKey(e){let t=e.match(/^(.+)\[(next|prev|\d+)(\|loop)?\]$/);if(!t)return null;let r=t[2]==="next"||t[2]==="prev"?t[2]:parseInt(t[2],10);return{slider:t[1],step:r,loop:t[3]==="|loop"}}getMaxStep(e){let t=-1;for(let r of this.elementIndex.keys()){let i=this.parseSequenceKey(r);i?.slider===e&&i.step>t&&(t=i.step)}return t}resolveDuration(e,t,r,i){let s=e.getProperty(i),n=e.getProperty("sequence-duration"),o=this.globalSettings.get(t)?.[r];if(s&&!s.includes("[")){let l=parseFloat(s);if(!isNaN(l))return l}if(n&&!n.includes("[")){let l=parseFloat(n);if(!isNaN(l))return l}return o??this.defaultDuration}resolveDurations(e,t){let r=this.parseSequenceKey(t)?.slider??"";return{enteringDuration:this.resolveDuration(e,r,"enteringDuration","entering-duration"),leavingDuration:this.resolveDuration(e,r,"leavingDuration","leaving-duration")}}resolveEasing(e,t,r,i){let s=e.getProperty(i);(!s||typeof s=="string"&&s.includes("["))&&(s=this.globalSettings.get(t)?.[r]??this.settings.easing??"ease-out"),typeof s=="string"&&e.setProperty(i,this.tools.easingFunction.process({easing:s}))}resolveEasings(e,t){let r=this.parseSequenceKey(t)?.slider;r&&(this.resolveEasing(e,r,"enteringEasing","entering-easing"),this.resolveEasing(e,r,"leavingEasing","leaving-easing"))}onObjectDisconnected(e){super.onObjectDisconnected(e);let t=e.getProperty("sequence");if(t){let r=this.elementIndex.get(t);if(r){let i=r.objects.indexOf(e);i!==-1&&r.objects.splice(i,1),r.objects.length||this.elementIndex.delete(t)}}this.triggerElements.has(e.htmlElement)&&(e.htmlElement.removeEventListener("click",this.onTriggerClick),this.triggerElements.delete(e.htmlElement))}parseSequenceKey(e){let t=e.match(/^(.+)\[(\d+)\]$/);return t?{slider:t[1],step:parseInt(t[2],10)}:null}onSequenceEvent(e){let{slider:t,step:r,transitionProgress:i,direction:s=1,duration:n,instant:o}=e;this.activeStep.get(t)===r&&i===void 0||(i!==void 0?this.handleScrub(t,r,i,s):o?this.switchInstant(t,r,s):this.startTransition(t,r,s,n))}startTransition(e,t,r,i){let s=this.activeStep.get(e),n=this.leavingStep.get(e);n!==void 0&&n!==s&&this.setStepState(e,n,"-disabled",0,r);let o=this.elementIndex.get(`${e}[${t}]`),l=s!==void 0?this.elementIndex.get(`${e}[${s}]`):null;s!==void 0&&this.leavingStep.set(e,s),this.activeStep.set(e,t),this.transitions.set(e,{fromStep:s??t,toStep:t,direction:r,startTime:this.data.time.now,enteringDuration:i??o?.enteringDuration??this.defaultDuration,leavingDuration:i??l?.leavingDuration??this.defaultDuration})}handleScrub(e,t,r,i){this.transitions.delete(e);let s=this.activeStep.get(e);if(s!==t){let n=this.leavingStep.get(e);n!==void 0&&this.setStepState(e,n,"-disabled",0,i),s!==void 0&&this.leavingStep.set(e,s),this.activeStep.set(e,t)}this.applyProgress(e,r,r,i)}switchInstant(e,t,r){this.transitions.delete(e);let i=this.activeStep.get(e),s=this.leavingStep.get(e);s!==void 0&&this.setStepState(e,s,"-disabled",0,r),i!==void 0&&i!==t&&this.setStepState(e,i,"-disabled",0,r),this.activeStep.set(e,t),this.leavingStep.delete(e),this.setStepState(e,t,"-active",1,r)}applyProgress(e,t,r,i){let s=this.activeStep.get(e),n=this.leavingStep.get(e);this.setStepState(e,s,t>=1?"-active":"-entering",t,i),n!==void 0&&n!==s&&(r>=1?(this.setStepState(e,n,"-disabled",0,i),this.leavingStep.delete(e)):this.setStepState(e,n,"-leaving",r,i))}setStepState(e,t,r,i,s){let n=this.elementIndex.get(`${e}[${t}]`);if(n)for(let o of n.objects)this.setState(o,r,i,s)}setState(e,t,r,i){let s=e.htmlElement,n=e.getProperty("_state"),o=e.getProperty("_direction"),l=e.getProperty(t==="-leaving"?"leaving-easing":"entering-easing"),h=typeof l=="function"?l(r):r;n!==t&&(s.classList.remove(...re.ALL_STATES),s.classList.add(t),e.setProperty("_state",t)),o!==i&&(e.setProperty("_direction",i),ee.run(()=>ee.setVars(s,{[ue.DIRECTION]:i.toString()})))}onFrame(e){super.onFrame(e),this.initialized||(this.initialized=!0,this.initializeSliders());for(let[t,r]of this.transitions){let i=e.time.now-r.startTime,s=Math.min(1,i/r.enteringDuration),n=Math.min(1,i/r.leavingDuration);this.applyProgress(t,s,n,r.direction),s>=1&&n>=1&&this.transitions.delete(t)}}};pe.ALL_STATES=Object.values(te);var J=class q extends U{constructor(e){super(e),this.htmlKey="form"}initializeObject(e,t,r,i){super.initializeObject(e,t,r,i);let s=t.getProperty("form-events")??[];s.forEach(c=>{c.eventElement.removeEventListener(c.eventType,c.eventCallback)}),s.length=0,t.setProperty("form-events",s),super.onObjectConnected(t);let n=t.htmlElement,o=[],l={};this.getInteractiveFields(n).forEach((c,d)=>this.registerField(c,n,o,l,s,d));let h=c=>{c.preventDefault();let d=!0,f={},y=new Set;for(let v of o){let g=v.field;if(!g.isConnected||!this.shouldValidateField(g))continue;if(this.isRadioField(g)){if(y.has(v.key))continue;y.add(v.key)}let{key:m,rules:M,needsContext:u}=v,w=this.getFieldValue(g);f[m]=w,l[m]=w;let{valid:p,errors:b}=this.tools.validation.process({rules:M,value:w,context:this.buildContext(u,m,l)});this.applyValidationState(n,g,m,p,b,"submit"),p||(d=!1)}if(d)this.events.emit(`form:submit:${t.id}`,f);else{let v=new Set,g=o.find(m=>{let M=m.field;if(!M.isConnected||!this.shouldValidateField(M))return!1;if(this.isRadioField(M)){if(v.has(m.key))return!1;v.add(m.key)}let{key:u,rules:w,needsContext:p}=m,b=this.getFieldValue(M);l[u]=b;let{valid:E}=this.tools.validation.process({rules:w,value:b,context:this.buildContext(p,u,l)});return!E});g?.field&&typeof g.field.focus=="function"&&g.field.focus(),this.events.emit(`form:invalid:${t.id}`)}};n.addEventListener("submit",h),s.push({eventElement:n,eventType:"submit",eventCallback:h}),t.setProperty("form-field-entries",o),t.setProperty("form-field-values",l)}onObjectConnected(e){}onDOMMutate(e,t){this.objects.length!==0&&(e.length>0&&this.handleMutationAdditions(e),t.length>0&&this.handleMutationRemovals(t))}applyValidationState(e,t,r,i,s,n){let o=e.querySelector(`[string-input="error[${r}]"]`),l=e.querySelector(`[string-input="group[${r}]"]`);o&&(o.innerHTML="",s.forEach(c=>{let d=document.createElement("span");d.textContent=c,o.appendChild(d)})),n==="live"?(t.classList.toggle("-invalid",!i),t.classList.remove("-error")):(t.classList.remove("-invalid"),t.classList.toggle("-error",!i)),t.classList.toggle("-valid",i),l&&(n==="live"?(l.classList.toggle("-invalid",!i),l.classList.remove("-error")):(l.classList.remove("-invalid"),l.classList.toggle("-error",!i)),l.classList.toggle("-valid",i));let h=i?"valid":n==="live"?"invalid":"error";this.events.emit(`form:field:${h}:${r}`,{key:r,field:t,errors:s,phase:n,valid:i})}getInteractiveFields(e){return Array.from(e.querySelectorAll("[string-input]")).filter(t=>!this.isServiceFieldAttribute(t.getAttribute("string-input")||"")).filter(t=>this.isFormFieldElement(t)).map(t=>t)}getFieldRules(e){let t=this.tools.domAttribute.process({element:e,key:"input"})??"";return this.tools.ruleParser.process({value:t})}registerField(e,t,r,i,s,n){if(!this.isFormFieldElement(e)||e.closest("form")!==t||r.some(g=>g.field===e))return;let o=this.registerFieldIndex(e,n??r.length),l=this.getInputKey(e,o),h=this.getFieldRules(e),c=this.supportsBeforeInputValidation(h),d=this.requiresContext(h),f=this.getInputEventType(e),y={field:e,key:l,rules:h,supportsRealtime:c,needsContext:d,inputEventType:f,inputHandler:()=>{}},v=g=>{let m=g.currentTarget||g.target;if(!m||!m.isConnected||!this.shouldValidateField(m))return;let M=this.getFieldValue(m);i[y.key]=M;let u=this.buildContext(y.needsContext,y.key,i),{valid:w,errors:p}=this.tools.validation.process({rules:y.rules,value:M,context:u});this.applyValidationState(t,m,y.key,w,p,"live")};if(y.inputHandler=v,e.addEventListener(f,v),s.push({eventElement:e,eventType:f,eventCallback:v}),c&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement)){let g=m=>{let M=m;if(M.isComposing||M.inputType?.startsWith("insertComposition"))return;let u=m.currentTarget||m.target;if(!u||!(u instanceof HTMLInputElement||u instanceof HTMLTextAreaElement)||!u.isConnected)return;let w=u.selectionStart??0,p=u.selectionEnd??0,b=u.value;switch(M.inputType){case"deleteContentBackward":b=w===p&&w>0?u.value.slice(0,w-1)+u.value.slice(p):u.value.slice(0,w)+u.value.slice(p);break;case"deleteContentForward":b=w===p&&w<u.value.length?u.value.slice(0,w)+u.value.slice(w+1):u.value.slice(0,w)+u.value.slice(p);break;case"insertFromPaste":case"insertFromDrop":case"insertReplacementText":b=u.value.slice(0,w)+(M.data||"")+u.value.slice(p);break;default:typeof M.data=="string"&&(b=u.value.slice(0,w)+M.data+u.value.slice(p))}let{errors:E}=this.tools.validation.process({rules:y.rules,value:b,type:"beforeinput",context:this.buildContext(y.needsContext,y.key,i,{applied:!0,value:b})});E.length>0&&m.cancelable&&m.preventDefault()};y.beforeInputHandler=g,e.addEventListener("beforeinput",g),s.push({eventElement:e,eventType:"beforeinput",eventCallback:g})}e.classList.add("-inited"),r.push(y),i[l]=this.getFieldValue(e)}unregisterField(e,t,r,i){let s=t.findIndex(o=>o.field===e);if(s===-1)return;let n=t[s];n.inputHandler&&e.removeEventListener(n.inputEventType,n.inputHandler),n.beforeInputHandler&&e.removeEventListener("beforeinput",n.beforeInputHandler),delete r[n.key],t.splice(s,1);for(let o=i.length-1;o>=0;o--){let l=i[o];l.eventElement===e&&(l.eventCallback===n.inputHandler||n.beforeInputHandler&&l.eventCallback===n.beforeInputHandler)&&i.splice(o,1)}e.classList.remove("-inited")}collectInteractiveFieldsFromNode(e){let t=[];return e instanceof Element?(e.hasAttribute("string-input")&&t.push(e),t.push(...Array.from(e.querySelectorAll("[string-input]")))):e instanceof DocumentFragment&&t.push(...Array.from(e.querySelectorAll("[string-input]"))),t.filter(r=>!this.isServiceFieldAttribute(r.getAttribute("string-input")||"")).filter(r=>this.isFormFieldElement(r))}isRadioField(e){return e instanceof HTMLInputElement&&e.type==="radio"}handleMutationAdditions(e){e.forEach(t=>{this.collectInteractiveFieldsFromNode(t).forEach(r=>{let i=this.getFormStateByContainment(r);i&&this.registerField(r,i.form,i.entries,i.values,i.events)})})}handleMutationRemovals(e){e.forEach(t=>{this.collectInteractiveFieldsFromNode(t).forEach(r=>{let i=this.getFormStateByReference(r);i&&this.unregisterField(r,i.entries,i.values,i.events)})})}getFormStateByContainment(e){let t=this.objects.find(r=>r.htmlElement instanceof HTMLFormElement&&r.htmlElement.contains(e));return t?this.buildFormState(t):null}getFormStateByReference(e){for(let t of this.objects){let r=t.getProperty("form-field-entries");if(r&&r.some(i=>i.field===e))return this.buildFormState(t,r)}return null}buildFormState(e,t){let r=e.htmlElement;if(!(r instanceof HTMLFormElement))return null;let i=t??e.getProperty("form-field-entries"),s=e.getProperty("form-field-values"),n=e.getProperty("form-events");return!i||!s||!n?null:{object:e,form:r,entries:i,values:s,events:n}}registerFieldIndex(e,t){let r=e.getAttribute("data-string-form-index");return r!==null?Number(r):(e.setAttribute("data-string-form-index",String(t)),t)}getFieldIndex(e,t){let r=e.getAttribute("data-string-form-index");if(r!==null){let i=Number(r);return Number.isNaN(i)?t:i}return this.registerFieldIndex(e,t)}shouldValidateField(e){return!(e.disabled||e instanceof HTMLInputElement&&e.type==="hidden")}supportsBeforeInputValidation(e){return e.some(t=>q.beforeInputRuleKeys.has(t.key))}requiresContext(e){return e.some(t=>q.crossFieldRuleKeys.has(t.key))}buildContext(e,t,r,i){if(!e)return{fieldKey:t};let s=!!i?.applied,n=s?{...r,[t]:i.value}:r;return{fieldKey:t,values:n,getValue:o=>s&&o===t?i.value:n[o]}}getInputKey(e,t){return this.tools.domAttribute.process({element:e,key:"id"})||e.getAttribute("name")||e.getAttribute("id")||`input-${t}`}getFieldValue(e){if(e instanceof HTMLInputElement){if(e.type==="checkbox"){if(e.name){let t=e.form||e.closest("form"),r=t?Array.from(t.querySelectorAll(`input[type="checkbox"][name="${e.name}"]:checked`)):[e];return r.length>1?r.map(i=>i.value):r.length===1?r[0].value:""}return e.checked}if(e.type==="radio"){if(e.name){let t=(e.form||e.closest("form"))?.querySelector(`input[type="radio"][name="${e.name}"]:checked`);return t?t.value:""}return e.checked?e.value:""}return e.type==="file"&&e.files&&e.files.length>0?e.multiple?Array.from(e.files):e.files[0]:e.value}return e instanceof HTMLSelectElement?e.multiple?Array.from(e.selectedOptions).map(t=>t.value):e.value:e instanceof HTMLTextAreaElement?e.value:""}isServiceFieldAttribute(e){return q.serviceAttributePrefixes.some(t=>e.startsWith(`${t}[`))}isFormFieldElement(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}getInputEventType(e){return e instanceof HTMLSelectElement||e instanceof HTMLInputElement&&(e.type==="checkbox"||e.type==="radio")?"change":"input"}};J.beforeInputRuleKeys=new Set(["number","integer","email","phone","letters","lettersSpaces","lettersNumbers","alpha","alpha_num","alpha_dash","digits","url","pattern"]),J.crossFieldRuleKeys=new Set(["same","different","after","before"]),J.serviceAttributePrefixes=["error","group"];var N=class{constructor(e,t="orthographic",r=50,i=.1,s=1e4){this.scaleCache=new Map;this._width=1;this._height=1;this.engine=e,this.mode=t,this.perspectiveFov=r,t==="orthographic"?this._camera=e.createOrthographicCamera(-1,1,1,-1,i,s):this._camera=e.createPerspectiveCamera(r,1,i,s),this._position=e.createVector3(0,0,1e3),this.update()}get camera(){return this._camera}resize(e,t){if(this._width=e,this._height=t,this.mode==="orthographic"){let r=this._camera;r.left=-e/2,r.right=e/2,r.top=t/2,r.bottom=-t/2}else this._camera.aspect=e/t;this.update()}setPosition(e,t,r){this._position.set(e,t,r),this._camera.position.copy(this._position),this.update()}lookAt(e,t,r){this._camera.lookAt(e,t,r),this.update()}update(){this._camera.updateProjectionMatrix(),this._camera.updateMatrixWorld?.()}screenToWorld(e,t,r=0){if(this.mode==="orthographic"){let i=e-this._width/2,s=-(t-this._height/2);return this.engine.createVector3(i,s,r)}else{let{width:i,height:s}=this.getFrustumSizeAt(r),n=e/this._width,o=t/this._height,l=(n-.5)*i,h=-(o-.5)*s;return this.engine.createVector3(l,h,r)}}getFrustumSizeAt(e){if(this.mode==="orthographic")return{width:this._width,height:this._height};let t=this.engine.degToRad(this.perspectiveFov),r=Math.abs(e-this._camera.position.z),i=2*Math.tan(t/2)*r;return{width:i*this._camera.aspect,height:i}}getScaleAtZ(e,t){if(this.mode==="orthographic")return 1;let r=Math.round(e*1e3)/1e3;if(this.scaleCache.has(r))return this.scaleCache.get(r);let{height:i}=this.getFrustumSizeAt(e),s=i/t;return this.scaleCache.set(r,s),s}clearScaleCache(){this.scaleCache.clear()}getMode(){return this.mode}getPerspectiveFov(){return this.perspectiveFov}getPositionZ(){return this._position.z}};var z=class{constructor(e,t){this.engine=t,this._container=e;let{width:r,height:i}=e.getBoundingClientRect();this._width=r,this._height=i,this._renderer=t.createRenderer({antialias:!0,alpha:!0,logarithmicDepthBuffer:!0}),this._renderer.setPixelRatio(window.devicePixelRatio),this._renderer.setSize(r,i),this._renderer.shadowMap&&(this._renderer.shadowMap.enabled=!0)}attach(){this._container.appendChild(this._renderer.domElement)}render(e,t){this._renderer.render(e.getScene(),t.camera)}resize(e){let{width:t,height:r}=this._container.getBoundingClientRect();this._width=t,this._height=r,this._renderer.setSize(t,r),e.resize(t,r)}get width(){return this._width}get height(){return this._height}get renderer(){return this._renderer}destroy(){this._renderer.dispose()}};var P=class{constructor(e,t,r,i,s={}){this._uniforms={};this._children=[];this.id=e,this.type=t,this._object=r,this.engine=i,this._material=s.material,this._geometry=s.geometry,this._texture=s.texture,this._quaternion=i.createQuaternion(),this._originalSize=i.createVector3(),this._bbox=i.createBox3(),this.updateBoundingBox()}get children(){return this._children}get object(){return this._object}get material(){return this._material}get originalSize(){return this._originalSize.clone()}get boundingBox(){return this._bbox.clone()}addChild(e){this._children.push(e),this.object.add(e.object)}getWorldMatrix(){return this._object.matrixWorld.clone()}getWorldPosition(){return this.engine.createVector3().setFromMatrixPosition(this._object.matrixWorld)}getOriginalBoundingBox(){if(!this._originalBoundingBox){let e=this.object.scale.clone();this.object.scale.set(1,1,1),this.object.updateMatrixWorld(!0),this._originalBoundingBox=this.engine.computeBoundingBoxRecursively(this.object),this.object.scale.copy(e),this.object.updateMatrixWorld(!0)}return this._originalBoundingBox.clone()}syncTransformFromMatrix(e){let t=this.engine.createVector3(),r=this.engine.createQuaternion(),i=this.engine.createVector3();e.decompose(t,r,i),this._object.position.copy(t),this._object.quaternion.copy(r),this._object.scale.copy(i),this._object.updateMatrix(),this._object.updateMatrixWorld()}applyWorldTransform(e,t,r){this._object.position.copy(e),this._object.quaternion.copy(t),this._object.scale.copy(r),this._object.updateMatrix(),this._object.updateMatrixWorld()}set quaternion(e){this._quaternion.copy(e),this._object.quaternion.copy(this._quaternion),this._object.updateMatrixWorld()}set position(e){this._object.position.copy(e)}set scale(e){this._object.scale.copy(e)}set rotation(e){this._object.rotation.copy(e)}set opacity(e){let t=this._object;t.material&&"opacity"in t.material&&(t.material.opacity=e)}set metalness(e){let t=this._object;t.material&&"metalness"in t.material&&(t.material.metalness=e)}set roughness(e){let t=this._object;t.material&&"roughness"in t.material&&(t.material.roughness=e)}set texture(e){this._texture=e,this._object.isMesh&&e?.applyTexture&&e.applyTexture(this._object)}set material(e){this._material=e}set geometry(e){this._geometry=e}updateBoundingBox(){this._bbox.setFromObject(this._object),this._bbox.getSize(this._originalSize)}destroy(){this.disposeObjectResources(this._object),this._texture?.dispose?.(),this._material?.dispose(),this._geometry?.dispose()}disposeObjectResources(e){let t=e;t?.geometry?.dispose&&t.geometry.dispose();let r=t?.material;Array.isArray(r)?r.forEach(i=>i?.dispose?.()):r?.dispose&&r.dispose(),typeof t?.traverse=="function"&&t.traverse(i=>{i?.geometry?.dispose&&i.geometry.dispose();let s=i?.material;Array.isArray(s)?s.forEach(n=>n?.dispose?.()):s?.dispose&&s.dispose()})}};var _=class{constructor(e,t={}){this._objects=new Map;this._rootObjects=[];this._elementMap=new Map;this._modelLoaderCache=new Map;this.engine=e,this._modelLoader=t.modelLoader,this._modelLoaderFactory=t.modelLoaderFactory,this._scene=e.createScene()}get rootObjects(){return this._rootObjects}getScene(){return this._scene}getObject(e){return this._objects.get(e)}hasObject(e){return this._objects.has(e)}deleteObject(e){let t=this._objects.get(e);return t?(this._scene.remove(t.object),this._objects.delete(e),t.destroy(),!0):!1}createFromElement(e){let t=e.getProperty("3d");if(!t)return;let r=e.htmlElement;if(!r)return;let i=s=>{if(s){let n=e.getProperty("parentId");n==null?(this._scene.add(s.object),this._rootObjects.push(s)):this._objects.get(n)?.addChild(s),this._objects.set(e.id,s),this._elementMap.set(e.id,r),s.el=r}};switch(t){case"group":this.createGroup(e,i);break;case"pointLight":this.createLight(e,"point",i);break;case"ambientLight":this.createLight(e,"ambient",i);break;case"directionalLight":this.createLight(e,"directional",i);break;case"spotLight":this.createLight(e,"spot",i);break;case"hemisphereLight":this.createLight(e,"hemisphere",i);break;case"model":this.createModel(e,i);break;case"box":this.createBox(e,i);break;case"sphere":this.createSphere(e,i);break;case"plane":this.createPlane(e,i);break;case"cylinder":this.createCylinder(e,i);break}}createGroup(e,t){let r=this.engine.createGroup(),i=new P(e.id,"group",r,this.engine);return t(i),i}createLight(e,t,r){let i=e.getProperty("3d-color")||"#ffffff",s=e.getProperty("3d-intensity")??1,n;if(t==="point"){let h=e.getProperty("3d-distance")??1e3,c=e.getProperty("3d-decay")??0;n=this.engine.createPointLight(i,s,h,c)}else if(t==="directional")n=this.engine.createDirectionalLight(i,s);else if(t==="spot"){let h=e.getProperty("3d-distance")??0,c=e.getProperty("3d-angle")??Math.PI/3,d=e.getProperty("3d-penumbra")??0,f=e.getProperty("3d-decay")??1;n=this.engine.createSpotLight(i,s,h,c,d,f)}else if(t==="hemisphere"){let h=e.getProperty("3d-ground-color")||"#ffffff";n=this.engine.createHemisphereLight(i,h,s)}else n=this.engine.createAmbientLight(i,s);if((e.getProperty("3d-cast-shadow")??!1)&&n.shadow){n.castShadow=!0;let h=e.getProperty("3d-shadow-bias")??0,c=e.getProperty("3d-shadow-map-size")??512;n.shadow.bias=h,n.shadow.mapSize.width=c,n.shadow.mapSize.height=c}let l=new P(e.id,t+"Light",n,this.engine);return r(l),l}applyShadowProps(e,t){let r=e.getProperty("3d-cast-shadow")??!1,i=e.getProperty("3d-receive-shadow")??!1;t.castShadow=r,t.receiveShadow=i}createBox(e,t){let r=this.engine.createBoxGeometry(1,1,1),i=this.createMaterialFromObject(e),s=this.engine.createMesh(r,i);this.applyShadowProps(e,s);let n=new P(e.id,"box",s,this.engine,{geometry:r,material:i});return t(n),n}createSphere(e,t){let r=e.getProperty("3d-segments-width")??32,i=e.getProperty("3d-segments-height")??32,s=this.engine.createSphereGeometry(.5,r,i),n=this.createMaterialFromObject(e),o=this.engine.createMesh(s,n);this.applyShadowProps(e,o);let l=new P(e.id,"sphere",o,this.engine,{geometry:s,material:n});return t(l),l}createPlane(e,t){let r=this.engine.createPlaneGeometry(1,1),i=this.createMaterialFromObject(e),s=this.engine.createMesh(r,i);this.applyShadowProps(e,s);let n=new P(e.id,"plane",s,this.engine,{geometry:r,material:i});return t(n),n}createCylinder(e,t){let r=e.getProperty("3d-segments")??32,i=this.engine.createCylinderGeometry(.5,.5,1,r),s=this.createMaterialFromObject(e),n=this.engine.createMesh(i,s);this.applyShadowProps(e,n);let o=new P(e.id,"cylinder",n,this.engine,{geometry:i,material:s});return t(o),o}createModel(e,t){let r=e.getProperty("3d-model");if(!r)return;let i=e.getProperty("3d-model-loader")||void 0,s=this.resolveModelLoader(i);if(!s){console.warn("[String3D] Model loader not configured");return}let n=e.htmlElement;n&&this.applyModelTextureRemap(s,n);let o=e.getProperty("3d-model-center")??!1;s.load(r,l=>{let h=l?.scene||l?.object||l;if(!h){console.warn("[String3D] Model loader returned empty result");return}let c=n&&this.shouldOverrideModelMaterial(n)?this.createMaterialFromElement(n,e):null;typeof h.traverse=="function"&&h.traverse(f=>{f.isMesh&&(c&&(f.material=c),this.applyShadowProps(e,f))}),o&&this.centerObject(h);let d=new P(e.id,"model",h,this.engine);t(d)},l=>{console.log(l.loaded/l.total*100+"% loaded")},l=>{console.error("[String3D] Model loading error:",l)})}resolveModelLoader(e){if(e){if(this._modelLoaderCache.has(e))return this._modelLoaderCache.get(e);if(!this._modelLoaderFactory){console.warn(`[String3D] No model loader factory for type "${e}"`);return}let t=this._modelLoaderFactory(this.engine,e);return this._modelLoaderCache.set(e,t),t}if(this._modelLoader)return this._modelLoader;if(this._modelLoaderFactory)return this._modelLoaderFactory(this.engine)}centerObject(e){if(!e)return;let t=this.engine.computeBoundingBoxRecursively(e),r=this.getBoxCenter(t);e.position?.set&&e.position.set(-r.x,-r.y,-r.z),e.updateMatrixWorld(!0)}getBoxCenter(e){let t=this.engine.createVector3();return t.x=(e.min.x+e.max.x)/2,t.y=(e.min.y+e.max.y)/2,t.z=(e.min.z+e.max.z)/2,t}createMaterialFromObject(e){return this.createMaterialFromElement(e.htmlElement,e)}createMaterialFromElement(e,t){let r=t?.getProperty("3d-material")||"basic[#ffffff]",[i,s]=r.split(/\[|\]/),n=s||"#ffffff",o=t?.getProperty("3d-opacity")??1,l=t?.getProperty("3d-metalness"),h=t?.getProperty("3d-roughness"),c={color:n,transparent:o<1,opacity:o},d=e?.getAttribute("string-3d-map"),f=e?.getAttribute("string-3d-normalMap"),y=e?.getAttribute("string-3d-roughnessMap"),v=e?.getAttribute("string-3d-metalnessMap"),g=e?.getAttribute("string-3d-aoMap"),m=this.parseFlipY(t,e),M=t?.getProperty("3d-colorSpace")||e?.getAttribute("string-3d-colorSpace")||"";return i!=="standard"&&!!(d||f||y||v||g)&&(i="standard"),i==="standard"?(d&&(c.map=this.loadTexture(d,{flipY:m,colorSpace:M})),f&&(c.normalMap=this.loadTexture(f,{flipY:m})),y&&(c.roughnessMap=this.loadTexture(y,{flipY:m})),v&&(c.metalnessMap=this.loadTexture(v,{flipY:m})),g&&(c.aoMap=this.loadTexture(g,{flipY:m})),typeof l=="number"&&(c.metalness=l),typeof h=="number"&&(c.roughness=h),this.engine.createMeshStandardMaterial(c)):this.engine.createMeshBasicMaterial(c)}loadTexture(e,t={}){let i=this.engine.createTextureLoader().load(e);typeof t.flipY=="boolean"&&(i.flipY=t.flipY);let s=(t.colorSpace||"").toLowerCase().trim();return s&&"colorSpace"in i&&(i.colorSpace=s==="srgb"?"srgb":"linear"),i.needsUpdate=!0,i}parseFlipY(e,t){let r=e?.getProperty("3d-texture-flipY")??t?.getAttribute("string-3d-texture-flipY");if(r==null||r==="")return;if(typeof r=="boolean")return r;let i=String(r).toLowerCase().trim();if(i==="false"||i==="0"||i==="no")return!1;if(i==="true"||i==="1"||i==="yes")return!0}shouldOverrideModelMaterial(e){return["string-3d-material","string-3d-color","string-3d-opacity","string-3d-map","string-3d-normalMap","string-3d-roughnessMap","string-3d-metalnessMap","string-3d-aoMap","string-3d-metalness","string-3d-roughness"].some(r=>e.hasAttribute(r))}applyModelTextureRemap(e,t){let r=(t.getAttribute("string-3d-model-texture-base")||"").trim(),i=r?r.replace(/\/?$/,"/"):"",s=t.getAttribute("string-3d-model-textures"),n=null;if(s)try{n=JSON.parse(s)}catch(l){console.warn("[String3D] Invalid model texture mapping JSON:",l)}let o=e?.manager;if(!o||typeof o.setURLModifier!="function"){(n||i)&&console.warn("[String3D] Model loader does not support URL remap.");return}o.setURLModifier(l=>{let h=n&&l in n?n[l]:l;return!i||/^(blob:|data:|https?:|file:|\/)/i.test(h)?h:i+h.replace(/^\.?\//,"")})}destroy(){this._objects.forEach(e=>e.destroy()),this._objects.clear(),this._rootObjects=[]}};var X=class{sync(e,t,r,i){let s=e.getBoundingClientRect(),n=s.left+s.width/2,o=s.top+s.height/2,l=e.computedStyleMap?.(),h=null,c=()=>(h||(h=getComputedStyle(e)),h),d=(u,w)=>{let p=l?.get?.(u);if(p!==void 0){if(typeof p=="number")return p;if(typeof p=="string"){let S=Number.parseFloat(p);if(!Number.isNaN(S))return S}if(p&&typeof p=="object"){let S=p.value;if(typeof S=="number")return S;if(typeof S=="string"){let T=Number.parseFloat(S);if(!Number.isNaN(T))return T}}}let b=c().getPropertyValue(u),E=Number.parseFloat(b);return Number.isNaN(E)?w:E},f=d("--translate-z",0),y=r.camera.screenToWorld(n,o,f);t.position=y;let v=d("--scale",1);t.scale=r.engine.createVector3(v,v,v);let g=-r.engine.degToRad(d("--rotate-x",0)),m=r.engine.degToRad(d("--rotate-y",0)),M=-r.engine.degToRad(d("--rotate-z",0));return t.rotation=r.engine.createEuler(g,m,M,"XYZ"),t.object.updateMatrixWorld(!0),{scale:v}}};var A=class{sync(e,t,r,i){let s=e.getBoundingClientRect(),n=s.left+s.width/2,o=s.top+s.height/2,l=parseFloat(getComputedStyle(e).getPropertyValue("--translate-z")||"0"),h=r.camera.screenToWorld(n,o,l);t.position=h;let c=t.object,d=e.getAttribute("string-3d-color");d&&c.color&&typeof c.color.set=="function"&&c.color.set(d);let f=e.getAttribute("string-3d-intensity");f&&(c.intensity=parseFloat(f));let y=e.getAttribute("string-3d-distance");y&&typeof c.distance<"u"&&(c.distance=parseFloat(y));let v=e.getAttribute("string-3d-decay");v&&typeof c.decay<"u"&&(c.decay=parseFloat(v));let g=e.getAttribute("string-3d-angle");g&&typeof c.angle<"u"&&(c.angle=parseFloat(g));let m=e.getAttribute("string-3d-penumbra");m&&typeof c.penumbra<"u"&&(c.penumbra=parseFloat(m));let M=e.getAttribute("string-3d-ground-color");M&&c.groundColor&&typeof c.groundColor.set=="function"&&c.groundColor.set(M);let u=e.getAttribute("string-3d-cast-shadow")==="true";if(c.castShadow!==u&&(c.castShadow=u),u&&c.shadow){let p=e.getAttribute("string-3d-shadow-bias");p&&(c.shadow.bias=parseFloat(p));let b=e.getAttribute("string-3d-shadow-map-size");if(b){let E=parseFloat(b);c.shadow.mapSize.width!==E&&(c.shadow.mapSize.width=E,c.shadow.mapSize.height=E)}}let w=e.getAttribute("string-3d-target");if(w&&c.target){let p=document.querySelector(`[string-id="${w}"]`);if(p){let b=p.getBoundingClientRect(),E=b.left+b.width/2,S=b.top+b.height/2,T=parseFloat(getComputedStyle(p).getPropertyValue("--translate-z")||"0"),D=r.camera.screenToWorld(E,S,T);c.target.position.copy(D),c.target.updateMatrixWorld(!0)}}return null}};var C=class a{static applyVisualProps(e,t,r){let i=e.getAttribute("string-3d-cast-shadow")==="true",s=e.getAttribute("string-3d-receive-shadow")==="true",n=typeof r=="number"?r:NaN;if(t.object.traverse)t.object.traverse(o=>{o.isMesh&&(o.castShadow!==i&&(o.castShadow=i),o.receiveShadow!==s&&(o.receiveShadow=s),isNaN(n)||(Array.isArray(o.material)?o.material:[o.material]).forEach(h=>{h&&(h.opacity=n,h.transparent=n<1)}))});else if(t.object.isMesh){let o=t.object;o.castShadow!==i&&(o.castShadow=i),o.receiveShadow!==s&&(o.receiveShadow=s),isNaN(n)||(Array.isArray(o.material)?o.material:[o.material]).forEach(h=>{h&&(h.opacity=n,h.transparent=n<1)})}}sync(e,t,r,i){let s=e.computedStyleMap?.(),n=null,o=()=>(n||(n=getComputedStyle(e)),n),l=e.getBoundingClientRect(),h=e.offsetWidth||l.width,c=e.offsetHeight||l.height,d=(k,F)=>{let L=s?.get?.(k);if(L!==void 0){if(typeof L=="number")return L;if(typeof L=="string"){let x=Number.parseFloat(L);if(!Number.isNaN(x))return x}if(L&&typeof L=="object"){let x=L.value;if(typeof x=="number")return x;if(typeof x=="string"){let H=Number.parseFloat(x);if(!Number.isNaN(H))return H}}}let Y=o().getPropertyValue(k),I=Number.parseFloat(Y);return Number.isNaN(I)?F:I},f=d("--translate-z",0),y=d("--scale",1),v=l.left+l.width/2,g=l.top+l.height/2,m=r.camera.screenToWorld(v,g,f);t.position=m;let M=-r.engine.degToRad(d("--rotate-x",0)),u=r.engine.degToRad(d("--rotate-y",0)),w=-r.engine.degToRad(d("--rotate-z",0));t.rotation=r.engine.createEuler(M,u,w,"XYZ");let p=h*y,b=c*y,E=d("--scale-z",1),S=i?.scale||1,T=t.type,D,R,O;switch(T){case"box":case"sphere":{let k=Math.min(p,b);D=k*S,R=k*S,O=k*E*S;break}case"model":{let F=t.getOriginalBoundingBox().getSize(r.engine.createVector3()),L=(e.getAttribute("string-3d-model-fit")||"contain").toLowerCase().trim(),Y=parseFloat(e.getAttribute("string-3d-model-scale")||"1"),I=Number.isFinite(Y)?Y:1;if(F.x>0&&F.y>0){let x=p/F.x,H=b/F.y,K=L==="cover"?Math.max(x,H):Math.min(x,H);D=K*I*S,R=K*I*S,O=K*I*E*S}else{let x=Math.min(p,b);D=x*I*S,R=x*I*S,O=x*I*E*S}break}case"cylinder":{let k=p;D=k*S,R=b*S,O=k*E*S;break}case"plane":default:D=p*S,R=b*S,O=Math.min(p,b)*.5*E*S;break}t.scale=r.engine.createVector3(D,R,O);let $=d("--opacity",NaN);return a.applyVisualProps(e,t,$),{scale:y*S}}};var W=class{constructor(e,t,r,i){this.camera=e;this.viewportWidth=t;this.viewportHeight=r;this.engine=i;this.strategies=new Map;this.strategies.set("box",new C),this.strategies.set("sphere",new C),this.strategies.set("plane",new C),this.strategies.set("cylinder",new C),this.strategies.set("model",new C),this.strategies.set("group",new X),this.strategies.set("pointLight",new A),this.strategies.set("ambientLight",new A),this.strategies.set("directionalLight",new A),this.strategies.set("spotLight",new A),this.strategies.set("hemisphereLight",new A)}syncElement(e,t,r){let i=this.strategies.get(t.type);return i?i.sync(e,t,{camera:this.camera,viewportWidth:this.viewportWidth,viewportHeight:this.viewportHeight,engine:this.engine},r):(console.warn(`[String3D Sync] No strategy for type "${t.type}"`),null)}updateViewportSize(e,t){this.viewportWidth=e,this.viewportHeight=t}};var me=`
|
|
1
|
+
"use strict";var StringTune3D=(()=>{var ee=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var le=Object.prototype.hasOwnProperty;var ce=(h,t)=>{for(var e in t)ee(h,e,{get:t[e],enumerable:!0})},he=(h,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of oe(t))!le.call(h,i)&&i!==e&&ee(h,i,{get:()=>t[i],enumerable:!(r=ae(t,i))||r.enumerable});return h};var ue=h=>he(ee({},"__esModule",{value:!0}),h);var be={};ce(be,{String3D:()=>G,String3DCamera:()=>N,String3DCustomFilterRegistry:()=>R,String3DObject:()=>D,String3DRenderer:()=>_,String3DScene:()=>W,String3DSynchronizer:()=>H,ThreeJSEngine:()=>$,ThreeJSProvider:()=>Q});var de=class{constructor(){this.desktop={rebuild:{width:!0,height:!0,scrollHeight:!0}},this.mobile={rebuild:{width:!0,height:!0,scrollHeight:!0}}}},X=class{constructor(h){this.objectMapOnPage=new Map,this.objectsOnPage=[],this.objectMap=new Map,this.objects=[],this.htmlKey="",this._type=1,this.permissions=new de,this.tools=h.tools,this.data=h.data,this.settings=h.settings,this.events=h.events,this.centers=h.centers,this.hover=h.hover,this.attributesToMap=[{key:"active",type:"boolean",fallback:this.settings.active},{key:"fixed",type:"boolean",fallback:this.settings.fixed},{key:"outside-container",type:"boolean",fallback:this.settings["outside-container"]},{key:"repeat",type:"boolean",fallback:this.settings.repeat},{key:"self-disable",type:"boolean",fallback:this.settings["self-disable"]},{key:"abs",type:"boolean",fallback:this.settings.abs},{key:"key",type:"string",fallback:this.settings.key},{key:"offset-top",type:"dimension",fallback:this.settings["offset-top"]},{key:"offset-bottom",type:"dimension",fallback:this.settings["offset-bottom"]},{key:"inview-top",type:"dimension",fallback:this.settings["inview-top"]},{key:"inview-bottom",type:"dimension",fallback:this.settings["inview-bottom"]},{key:"start",type:"number",fallback:(t,e,r)=>{let i=r.top;return Math.floor(i)+this.data.scroll.container.scrollTop*this.data.viewport.transformScale}},{key:"end",type:"number",fallback:(t,e,r)=>{let i=r.top,s=r.height;return i+s-this.data.scroll.transformedCurrent}},{key:"size",type:"number",fallback:(t,e,r)=>r.height},{key:"half-width",type:"number",fallback:(t,e,r)=>r.width/2},{key:"half-height",type:"number",fallback:(t,e,r)=>r.height/2},{key:"enter-el",type:"string",fallback:this.settings["enter-el"]},{key:"enter-vp",type:"string",fallback:this.settings["enter-vp"]},{key:"exit-el",type:"string",fallback:this.settings["exit-el"]},{key:"exit-vp",type:"string",fallback:this.settings["exit-vp"]}]}get type(){return this._type}initializeObject(h,t,e,r){let i=this.tools.boundingClientRect.process({element:e});for(let{key:s,type:n,fallback:a,transform:l}of this.attributesToMap){let o=typeof a=="function"?a(e,t,i):a,c=this.tools.domAttribute.process({element:e,key:s,fallback:r[s]??this.settings[s]??o}),p=this.parseAttribute(c,n,{element:e,boundingRect:i,viewportHeight:this.data.viewport.windowHeight,baseRem:this.data.viewport.baseRem});l&&(p=l(p)),t.setProperty(s,p)}}calculatePositions(h,t){let e=h.getProperty("start"),r=h.getProperty("size"),i=h.getProperty("offset-bottom"),s=h.getProperty("offset-top"),n=h.getProperty("enter-el"),a=h.getProperty("enter-vp"),l=h.getProperty("exit-el"),o=h.getProperty("exit-vp"),c=0,p=0,m=0,u=0;n==="top"&&a==="top"||n==="left"&&a==="left"?(m=-t+1,c=e-i):n==="top"&&a==="bottom"||n==="left"&&a==="right"?c=e-t-i:n==="bottom"&&a==="top"||n==="right"&&a==="left"?(m=-t-r+1,c=e+r-i):(n==="bottom"&&a==="bottom"||n==="right"&&a==="right")&&(m=-r+1,c=e-t+r-i),l==="top"&&o==="top"||l==="left"&&o==="left"?(u=-r+1,p=e+s):l==="top"&&o==="bottom"||l==="left"&&o==="right"?(u=-t-r+1,p=e-t+s):l==="bottom"&&o==="top"||l==="right"&&o==="left"?p=e+r+s:(l==="bottom"&&o==="bottom"||l==="right"&&o==="right")&&(u=-t+1,p=e-t+r+s),h.setProperty("start-bias",m),h.setProperty("end-bias",u),h.setProperty("start-position",c-this.data.scroll.topPosition),h.setProperty("end-position",p-this.data.scroll.topPosition),h.setProperty("difference-position",p-c);let g=h.getProperty("inview-top")??0,d=h.getProperty("inview-bottom")??0;h.setProperty("inview-start-position",h.getProperty("start-position")+g),h.setProperty("inview-end-position",h.getProperty("end-position")+d)}parseAttribute(h,t,e={}){if(h==null)return null;if(typeof t=="object"&&t.type==="enum")return t.values.includes(h)?h:t.values[0];switch(t){case"number":return parseFloat(h);case"boolean":return h===""||h==="true";case"json":try{return JSON.parse(h)}catch{return null}case"tuple":return h.trim().split(/\s+/);case"easing":return this.tools.easingFunction.process({easing:h});case"color":return this.tools.colorParser.process({value:h});case"dimension":return h=="0"?0:e.element!=null&&e.viewportHeight!=null&&e.baseRem!=null&&e.boundingRect!=null?this.tools.unitParser.process({value:h,element:e.element,viewportHeight:e.viewportHeight,boundingRect:e.boundingRect,baseRem:e.baseRem}):0;case"breakpoint-dimension":if(e.element!=null&&e.viewportHeight!=null&&e.baseRem!=null&&e.boundingRect!=null){let r=h.trim().split("|"),i=[];for(let s of r)if(s.includes(":")){let[n,a]=s.split(":");i.push({breakpoint:parseInt(n),value:this.tools.unitParser.process({value:`${a}|`,element:e.element,viewportHeight:e.viewportHeight,boundingRect:e.boundingRect,baseRem:e.baseRem})})}else i.push({breakpoint:0,value:this.tools.unitParser.process({value:s,element:e.element,viewportHeight:e.viewportHeight,boundingRect:e.boundingRect,baseRem:e.baseRem})});return i}default:return h}}canConnect(h){return h.keys.includes(this.htmlKey)}connectObject(h){h.connect(this),this.onObjectConnected(h)}enterObject(h,t){this.objectMap.has(h)||(this.objectMap.set(h,t),this.objects.push(t))}exitObject(h){let t=this.objectMap.get(h);if(!t)return;this.objectMap.delete(h);let e=this.objects.indexOf(t);e!==-1&&this.objects.splice(e,1)}addObject(h,t){this.objectMapOnPage.has(h)||(this.objectMapOnPage.set(h,t),this.objectsOnPage.push(t))}removeObject(h){let t=this.objectMapOnPage.get(h);if(!t)return;this.objectMapOnPage.delete(h);let e=this.objectsOnPage.indexOf(t);e!==-1&&this.objectsOnPage.splice(e,1),this.onObjectDisconnected(t)}onObjectConnected(h){}onObjectDisconnected(h){}applyToElementAndConnects(h,t,e=t){h.getProperty("self-disable")!==!0&&t(h.htmlElement),h.mirrorObjects.forEach(r=>e(r.htmlElement,r))}destroy(){this.objects=[],this.objectMap=new Map}onInit(){}onFrame(h){}onMutate(h){}onScrollMeasure(h){}onMouseMoveMeasure(h){}onResize(){}onResizeWidth(){}onScroll(h){}onDirectionChange(){}onScrollStart(){}onScrollStop(){}onScrollDirectionChange(){}onAxisChange(){}onDeviceChange(){}onScrollConfigChange(){}onSettingsChange(){}onDOMRebuild(){}onMouseMove(h){}onWheel(h){}onDOMMutate(h,t){}};var pe=class{constructor(){this.pendingVars=new Map,this.pendingProps=new Map,this.isOpen=!1}begin(){this.isOpen||(this.isOpen=!0)}setVars(h,t){if(!this.isOpen){console.warn("StyleTxn: call begin() first to set custom properties.");return}let e=this.pendingVars.get(h)??{};for(let[r,i]of Object.entries(t))e[r]!==i&&(e[r]=i);this.pendingVars.set(h,e)}setProps(h,t){if(!this.isOpen){console.warn("StyleTxn: call begin() first to set standard properties.");return}let e=this.pendingProps.get(h)??{};for(let[r,i]of Object.entries(t))e[r]!==i&&(e[r]=i);this.pendingProps.set(h,e)}run(h){let t=this.isOpen;t||this.begin();try{h(),t||this.commit()}catch(e){throw t||this.cancel(),e}}commit(){if(this.isOpen){this.isOpen=!1;for(let[h,t]of this.pendingVars){let e=h.style;for(let[r,i]of Object.entries(t))e.setProperty(r,String(i))}this.pendingVars.clear();for(let[h,t]of this.pendingProps){let e=h.style;for(let[r,i]of Object.entries(t))e[r]=String(i)}this.pendingProps.clear()}}cancel(){this.pendingVars.clear(),this.pendingProps.clear(),this.isOpen=!1}},ie=new pe;var Se=1/240;var me=class{constructor(){this.measureQueue=[],this.mutateQueue=[],this.scheduled=!1}measure(h){this.measureQueue.push(h),this.schedule()}mutate(h){this.mutateQueue.push(h),this.schedule()}schedule(){this.scheduled||(this.scheduled=!0,requestAnimationFrame(()=>{let h=this.measureQueue;this.measureQueue=[];for(let e=0;e<h.length;e++)try{h[e]()}catch(r){console.error("Error in frameDOM measure task:",r)}let t=this.mutateQueue;this.mutateQueue=[];for(let e=0;e<t.length;e++)try{t[e]()}catch(r){console.error("Error in frameDOM mutate task:",r)}this.scheduled=!1}))}},Me=new me;var we=Math.PI*2,xe=180/Math.PI;var se=(h=>(h.ACTIVE="-active",h.ENTERING="-entering",h.LEAVING="-leaving",h.DISABLED="-disabled",h))(se||{}),ge={PROGRESS:"--sequence-progress",DIRECTION:"--sequence-direction"},fe=class ne extends X{constructor(t){super(t),this.activeStep=new Map,this.leavingStep=new Map,this.transitions=new Map,this.elementIndex=new Map,this.triggerElements=new Map,this.globalSettings=new Map,this.initialized=!1,this.onTriggerClick=e=>{let r=this.triggerElements.get(e.currentTarget);if(!r)return;let i=this.activeStep.get(r.slider)??0,s=this.getMaxStep(r.slider),n,a;if(r.step==="next"){if(n=i+1,a=1,!this.elementIndex.has(`${r.slider}[${n}]`))if(r.loop&&s>=0)n=0;else return}else if(r.step==="prev"){if(n=i-1,a=-1,n<0)if(r.loop&&s>=0)n=s;else return;if(!this.elementIndex.has(`${r.slider}[${n}]`))return}else{if(n=r.step,i===n)return;a=n>i?1:-1}this.startTransition(r.slider,n,a)},this.htmlKey="sequence",this.defaultDuration=this.settings["sequence-duration"]??600,this.attributesToMap=[...this.attributesToMap,{key:"sequence",type:"string",fallback:""},{key:"sequence-trigger",type:"string",fallback:""},{key:"entering-easing",type:"string",fallback:""},{key:"leaving-easing",type:"string",fallback:""},{key:"entering-duration",type:"string",fallback:""},{key:"leaving-duration",type:"string",fallback:""},{key:"sequence-duration",type:"string",fallback:""},{key:"active-step",type:"string",fallback:""}]}onInit(){super.onInit(),this.events.on("sequence",this.onSequenceEvent.bind(this)),this.scanStandaloneTriggers()}scanStandaloneTriggers(){let t=document.querySelectorAll("[string-sequence-trigger]:not([string-inited])");for(let e of t){let r=e.getAttribute("string-sequence-trigger"),i=r?this.parseTriggerKey(r):null;i&&(this.triggerElements.set(e,i),e.addEventListener("click",this.onTriggerClick))}}parseGlobalSettingsFromObject(t){let e=i=>t.getProperty(i),r=e("sequence-duration");this.tryParseGlobalSetting(r,"enteringDuration"),this.tryParseGlobalSetting(r,"leavingDuration"),this.tryParseGlobalSetting(e("entering-duration"),"enteringDuration"),this.tryParseGlobalSetting(e("leaving-duration"),"leavingDuration"),this.tryParseGlobalSetting(e("entering-easing"),"enteringEasing"),this.tryParseGlobalSetting(e("leaving-easing"),"leavingEasing"),this.tryParseGlobalSetting(e("active-step"),"activeStep")}tryParseGlobalSetting(t,e){if(!t)return;let r=t.match(/^(.+)\[(.+)\]$/);if(!r)return;let[,i,s]=r,n=this.globalSettings.get(i)??{};this.globalSettings.set(i,n),n[e]=e==="enteringEasing"||e==="leavingEasing"?s:parseFloat(s),this.applyGlobalSettingsToExistingObjects(i)}applyGlobalSettingsToExistingObjects(t){let e=this.globalSettings.get(t);if(e){for(let[r,i]of this.elementIndex)if(this.parseSequenceKey(r)?.slider===t){e.enteringDuration!==void 0&&(i.enteringDuration=e.enteringDuration),e.leavingDuration!==void 0&&(i.leavingDuration=e.leavingDuration);for(let s of i.objects)this.resolveEasings(s,r)}}}initializeSliders(){let t=new Set;for(let e of this.elementIndex.keys()){let r=this.parseSequenceKey(e);r&&t.add(r.slider)}for(let e of t){if(this.activeStep.has(e))continue;let r=this.globalSettings.get(e)?.activeStep??0;this.elementIndex.has(`${e}[${r}]`)||(r=0),this.switchInstant(e,r,1)}}tryApplyPendingActiveStep(t){if(this.activeStep.has(t))return;let e=this.globalSettings.get(t)?.activeStep;e!==void 0&&this.elementIndex.has(`${t}[${e}]`)&&this.switchInstant(t,e,1)}canConnect(t){return t.keys.includes("sequence")||t.keys.includes("sequence-trigger")}onObjectConnected(t){super.onObjectConnected(t),this.parseGlobalSettingsFromObject(t);let e=t.getProperty("sequence"),r=t.getProperty("sequence-trigger");if(!e&&r){let i=this.parseTriggerKey(r);i&&typeof i.step=="number"&&(e=`${i.slider}[${i.step}]`,t.setProperty("sequence",e))}if(e){let i=this.parseSequenceKey(e);if(i){let s=this.elementIndex.get(e);if(!s){let{enteringDuration:a,leavingDuration:l}=this.resolveDurations(t,e);s={objects:[],enteringDuration:a,leavingDuration:l},this.elementIndex.set(e,s)}s.objects.push(t),this.resolveEasings(t,e);let n=this.activeStep.get(i.slider);this.setState(t,n===i.step?"-active":"-disabled",n===i.step?1:0,1),this.tryApplyPendingActiveStep(i.slider)}}if(r){let i=this.parseTriggerKey(r);i&&(this.triggerElements.set(t.htmlElement,i),t.htmlElement.addEventListener("click",this.onTriggerClick))}}parseTriggerKey(t){let e=t.match(/^(.+)\[(next|prev|\d+)(\|loop)?\]$/);if(!e)return null;let r=e[2]==="next"||e[2]==="prev"?e[2]:parseInt(e[2],10);return{slider:e[1],step:r,loop:e[3]==="|loop"}}getMaxStep(t){let e=-1;for(let r of this.elementIndex.keys()){let i=this.parseSequenceKey(r);i?.slider===t&&i.step>e&&(e=i.step)}return e}resolveDuration(t,e,r,i){let s=t.getProperty(i),n=t.getProperty("sequence-duration"),a=this.globalSettings.get(e)?.[r];if(s&&!s.includes("[")){let l=parseFloat(s);if(!isNaN(l))return l}if(n&&!n.includes("[")){let l=parseFloat(n);if(!isNaN(l))return l}return a??this.defaultDuration}resolveDurations(t,e){let r=this.parseSequenceKey(e)?.slider??"";return{enteringDuration:this.resolveDuration(t,r,"enteringDuration","entering-duration"),leavingDuration:this.resolveDuration(t,r,"leavingDuration","leaving-duration")}}resolveEasing(t,e,r,i){let s=t.getProperty(i);(!s||typeof s=="string"&&s.includes("["))&&(s=this.globalSettings.get(e)?.[r]??this.settings.easing??"ease-out"),typeof s=="string"&&t.setProperty(i,this.tools.easingFunction.process({easing:s}))}resolveEasings(t,e){let r=this.parseSequenceKey(e)?.slider;r&&(this.resolveEasing(t,r,"enteringEasing","entering-easing"),this.resolveEasing(t,r,"leavingEasing","leaving-easing"))}onObjectDisconnected(t){super.onObjectDisconnected(t);let e=t.getProperty("sequence");if(e){let r=this.elementIndex.get(e);if(r){let i=r.objects.indexOf(t);i!==-1&&r.objects.splice(i,1),r.objects.length||this.elementIndex.delete(e)}}this.triggerElements.has(t.htmlElement)&&(t.htmlElement.removeEventListener("click",this.onTriggerClick),this.triggerElements.delete(t.htmlElement))}parseSequenceKey(t){let e=t.match(/^(.+)\[(\d+)\]$/);return e?{slider:e[1],step:parseInt(e[2],10)}:null}onSequenceEvent(t){let{slider:e,step:r,transitionProgress:i,direction:s=1,duration:n,instant:a}=t;this.activeStep.get(e)===r&&i===void 0||(i!==void 0?this.handleScrub(e,r,i,s):a?this.switchInstant(e,r,s):this.startTransition(e,r,s,n))}startTransition(t,e,r,i){let s=this.activeStep.get(t),n=this.leavingStep.get(t);n!==void 0&&n!==s&&this.setStepState(t,n,"-disabled",0,r);let a=this.elementIndex.get(`${t}[${e}]`),l=s!==void 0?this.elementIndex.get(`${t}[${s}]`):null;s!==void 0&&this.leavingStep.set(t,s),this.activeStep.set(t,e),this.transitions.set(t,{fromStep:s??e,toStep:e,direction:r,startTime:this.data.time.now,enteringDuration:i??a?.enteringDuration??this.defaultDuration,leavingDuration:i??l?.leavingDuration??this.defaultDuration})}handleScrub(t,e,r,i){this.transitions.delete(t);let s=this.activeStep.get(t);if(s!==e){let n=this.leavingStep.get(t);n!==void 0&&this.setStepState(t,n,"-disabled",0,i),s!==void 0&&this.leavingStep.set(t,s),this.activeStep.set(t,e)}this.applyProgress(t,r,r,i)}switchInstant(t,e,r){this.transitions.delete(t);let i=this.activeStep.get(t),s=this.leavingStep.get(t);s!==void 0&&this.setStepState(t,s,"-disabled",0,r),i!==void 0&&i!==e&&this.setStepState(t,i,"-disabled",0,r),this.activeStep.set(t,e),this.leavingStep.delete(t),this.setStepState(t,e,"-active",1,r)}applyProgress(t,e,r,i){let s=this.activeStep.get(t),n=this.leavingStep.get(t);this.setStepState(t,s,e>=1?"-active":"-entering",e,i),n!==void 0&&n!==s&&(r>=1?(this.setStepState(t,n,"-disabled",0,i),this.leavingStep.delete(t)):this.setStepState(t,n,"-leaving",r,i))}setStepState(t,e,r,i,s){let n=this.elementIndex.get(`${t}[${e}]`);if(n)for(let a of n.objects)this.setState(a,r,i,s)}setState(t,e,r,i){let s=t.htmlElement,n=t.getProperty("_state"),a=t.getProperty("_direction"),l=t.getProperty(e==="-leaving"?"leaving-easing":"entering-easing"),o=typeof l=="function"?l(r):r;n!==e&&(s.classList.remove(...ne.ALL_STATES),s.classList.add(e),t.setProperty("_state",e)),a!==i&&(t.setProperty("_direction",i),ie.run(()=>ie.setVars(s,{[ge.DIRECTION]:i.toString()})))}onFrame(t){super.onFrame(t),this.initialized||(this.initialized=!0,this.initializeSliders());for(let[e,r]of this.transitions){let i=t.time.now-r.startTime,s=Math.min(1,i/r.enteringDuration),n=Math.min(1,i/r.leavingDuration);this.applyProgress(e,s,n,r.direction),s>=1&&n>=1&&this.transitions.delete(e)}}};fe.ALL_STATES=Object.values(se);var te=class Y extends X{constructor(t){super(t),this.htmlKey="form"}initializeObject(t,e,r,i){super.initializeObject(t,e,r,i);let s=e.getProperty("form-events")??[];s.forEach(c=>{c.eventElement.removeEventListener(c.eventType,c.eventCallback)}),s.length=0,e.setProperty("form-events",s),super.onObjectConnected(e);let n=e.htmlElement,a=[],l={};this.getInteractiveFields(n).forEach((c,p)=>this.registerField(c,n,a,l,s,p));let o=c=>{c.preventDefault();let p=!0,m={},u=new Set;for(let g of a){let d=g.field;if(!d.isConnected||!this.shouldValidateField(d))continue;if(this.isRadioField(d)){if(u.has(g.key))continue;u.add(g.key)}let{key:f,rules:v,needsContext:b}=g,M=this.getFieldValue(d);m[f]=M,l[f]=M;let{valid:y,errors:w}=this.tools.validation.process({rules:v,value:M,context:this.buildContext(b,f,l)});this.applyValidationState(n,d,f,y,w,"submit"),y||(p=!1)}if(p)this.events.emit(`form:submit:${e.id}`,m);else{let g=new Set,d=a.find(f=>{let v=f.field;if(!v.isConnected||!this.shouldValidateField(v))return!1;if(this.isRadioField(v)){if(g.has(f.key))return!1;g.add(f.key)}let{key:b,rules:M,needsContext:y}=f,w=this.getFieldValue(v);l[b]=w;let{valid:x}=this.tools.validation.process({rules:M,value:w,context:this.buildContext(y,b,l)});return!x});d?.field&&typeof d.field.focus=="function"&&d.field.focus(),this.events.emit(`form:invalid:${e.id}`)}};n.addEventListener("submit",o),s.push({eventElement:n,eventType:"submit",eventCallback:o}),e.setProperty("form-field-entries",a),e.setProperty("form-field-values",l)}onObjectConnected(t){}onDOMMutate(t,e){this.objects.length!==0&&(t.length>0&&this.handleMutationAdditions(t),e.length>0&&this.handleMutationRemovals(e))}applyValidationState(t,e,r,i,s,n){let a=t.querySelector(`[string-input="error[${r}]"]`),l=t.querySelector(`[string-input="group[${r}]"]`);a&&(a.innerHTML="",s.forEach(c=>{let p=document.createElement("span");p.textContent=c,a.appendChild(p)})),n==="live"?(e.classList.toggle("-invalid",!i),e.classList.remove("-error")):(e.classList.remove("-invalid"),e.classList.toggle("-error",!i)),e.classList.toggle("-valid",i),l&&(n==="live"?(l.classList.toggle("-invalid",!i),l.classList.remove("-error")):(l.classList.remove("-invalid"),l.classList.toggle("-error",!i)),l.classList.toggle("-valid",i));let o=i?"valid":n==="live"?"invalid":"error";this.events.emit(`form:field:${o}:${r}`,{key:r,field:e,errors:s,phase:n,valid:i})}getInteractiveFields(t){return Array.from(t.querySelectorAll("[string-input]")).filter(e=>!this.isServiceFieldAttribute(e.getAttribute("string-input")||"")).filter(e=>this.isFormFieldElement(e)).map(e=>e)}getFieldRules(t){let e=this.tools.domAttribute.process({element:t,key:"input"})??"";return this.tools.ruleParser.process({value:e})}registerField(t,e,r,i,s,n){if(!this.isFormFieldElement(t)||t.closest("form")!==e||r.some(d=>d.field===t))return;let a=this.registerFieldIndex(t,n??r.length),l=this.getInputKey(t,a),o=this.getFieldRules(t),c=this.supportsBeforeInputValidation(o),p=this.requiresContext(o),m=this.getInputEventType(t),u={field:t,key:l,rules:o,supportsRealtime:c,needsContext:p,inputEventType:m,inputHandler:()=>{}},g=d=>{let f=d.currentTarget||d.target;if(!f||!f.isConnected||!this.shouldValidateField(f))return;let v=this.getFieldValue(f);i[u.key]=v;let b=this.buildContext(u.needsContext,u.key,i),{valid:M,errors:y}=this.tools.validation.process({rules:u.rules,value:v,context:b});this.applyValidationState(e,f,u.key,M,y,"live")};if(u.inputHandler=g,t.addEventListener(m,g),s.push({eventElement:t,eventType:m,eventCallback:g}),c&&(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement)){let d=f=>{let v=f;if(v.isComposing||v.inputType?.startsWith("insertComposition"))return;let b=f.currentTarget||f.target;if(!b||!(b instanceof HTMLInputElement||b instanceof HTMLTextAreaElement)||!b.isConnected)return;let M=b.selectionStart??0,y=b.selectionEnd??0,w=b.value;switch(v.inputType){case"deleteContentBackward":w=M===y&&M>0?b.value.slice(0,M-1)+b.value.slice(y):b.value.slice(0,M)+b.value.slice(y);break;case"deleteContentForward":w=M===y&&M<b.value.length?b.value.slice(0,M)+b.value.slice(M+1):b.value.slice(0,M)+b.value.slice(y);break;case"insertFromPaste":case"insertFromDrop":case"insertReplacementText":w=b.value.slice(0,M)+(v.data||"")+b.value.slice(y);break;default:typeof v.data=="string"&&(w=b.value.slice(0,M)+v.data+b.value.slice(y))}let{errors:x}=this.tools.validation.process({rules:u.rules,value:w,type:"beforeinput",context:this.buildContext(u.needsContext,u.key,i,{applied:!0,value:w})});x.length>0&&f.cancelable&&f.preventDefault()};u.beforeInputHandler=d,t.addEventListener("beforeinput",d),s.push({eventElement:t,eventType:"beforeinput",eventCallback:d})}t.classList.add("-inited"),r.push(u),i[l]=this.getFieldValue(t)}unregisterField(t,e,r,i){let s=e.findIndex(a=>a.field===t);if(s===-1)return;let n=e[s];n.inputHandler&&t.removeEventListener(n.inputEventType,n.inputHandler),n.beforeInputHandler&&t.removeEventListener("beforeinput",n.beforeInputHandler),delete r[n.key],e.splice(s,1);for(let a=i.length-1;a>=0;a--){let l=i[a];l.eventElement===t&&(l.eventCallback===n.inputHandler||n.beforeInputHandler&&l.eventCallback===n.beforeInputHandler)&&i.splice(a,1)}t.classList.remove("-inited")}collectInteractiveFieldsFromNode(t){let e=[];return t instanceof Element?(t.hasAttribute("string-input")&&e.push(t),e.push(...Array.from(t.querySelectorAll("[string-input]")))):t instanceof DocumentFragment&&e.push(...Array.from(t.querySelectorAll("[string-input]"))),e.filter(r=>!this.isServiceFieldAttribute(r.getAttribute("string-input")||"")).filter(r=>this.isFormFieldElement(r))}isRadioField(t){return t instanceof HTMLInputElement&&t.type==="radio"}handleMutationAdditions(t){t.forEach(e=>{this.collectInteractiveFieldsFromNode(e).forEach(r=>{let i=this.getFormStateByContainment(r);i&&this.registerField(r,i.form,i.entries,i.values,i.events)})})}handleMutationRemovals(t){t.forEach(e=>{this.collectInteractiveFieldsFromNode(e).forEach(r=>{let i=this.getFormStateByReference(r);i&&this.unregisterField(r,i.entries,i.values,i.events)})})}getFormStateByContainment(t){let e=this.objects.find(r=>r.htmlElement instanceof HTMLFormElement&&r.htmlElement.contains(t));return e?this.buildFormState(e):null}getFormStateByReference(t){for(let e of this.objects){let r=e.getProperty("form-field-entries");if(r&&r.some(i=>i.field===t))return this.buildFormState(e,r)}return null}buildFormState(t,e){let r=t.htmlElement;if(!(r instanceof HTMLFormElement))return null;let i=e??t.getProperty("form-field-entries"),s=t.getProperty("form-field-values"),n=t.getProperty("form-events");return!i||!s||!n?null:{object:t,form:r,entries:i,values:s,events:n}}registerFieldIndex(t,e){let r=t.getAttribute("data-string-form-index");return r!==null?Number(r):(t.setAttribute("data-string-form-index",String(e)),e)}getFieldIndex(t,e){let r=t.getAttribute("data-string-form-index");if(r!==null){let i=Number(r);return Number.isNaN(i)?e:i}return this.registerFieldIndex(t,e)}shouldValidateField(t){return!(t.disabled||t instanceof HTMLInputElement&&t.type==="hidden")}supportsBeforeInputValidation(t){return t.some(e=>Y.beforeInputRuleKeys.has(e.key))}requiresContext(t){return t.some(e=>Y.crossFieldRuleKeys.has(e.key))}buildContext(t,e,r,i){if(!t)return{fieldKey:e};let s=!!i?.applied,n=s?{...r,[e]:i.value}:r;return{fieldKey:e,values:n,getValue:a=>s&&a===e?i.value:n[a]}}getInputKey(t,e){return this.tools.domAttribute.process({element:t,key:"id"})||t.getAttribute("name")||t.getAttribute("id")||`input-${e}`}getFieldValue(t){if(t instanceof HTMLInputElement){if(t.type==="checkbox"){if(t.name){let e=t.form||t.closest("form"),r=e?Array.from(e.querySelectorAll(`input[type="checkbox"][name="${t.name}"]:checked`)):[t];return r.length>1?r.map(i=>i.value):r.length===1?r[0].value:""}return t.checked}if(t.type==="radio"){if(t.name){let e=(t.form||t.closest("form"))?.querySelector(`input[type="radio"][name="${t.name}"]:checked`);return e?e.value:""}return t.checked?t.value:""}return t.type==="file"&&t.files&&t.files.length>0?t.multiple?Array.from(t.files):t.files[0]:t.value}return t instanceof HTMLSelectElement?t.multiple?Array.from(t.selectedOptions).map(e=>e.value):t.value:t instanceof HTMLTextAreaElement?t.value:""}isServiceFieldAttribute(t){return Y.serviceAttributePrefixes.some(e=>t.startsWith(`${e}[`))}isFormFieldElement(t){return t instanceof HTMLInputElement||t instanceof HTMLSelectElement||t instanceof HTMLTextAreaElement}getInputEventType(t){return t instanceof HTMLSelectElement||t instanceof HTMLInputElement&&(t.type==="checkbox"||t.type==="radio")?"change":"input"}};te.beforeInputRuleKeys=new Set(["number","integer","email","phone","letters","lettersSpaces","lettersNumbers","alpha","alpha_num","alpha_dash","digits","url","pattern"]),te.crossFieldRuleKeys=new Set(["same","different","after","before"]),te.serviceAttributePrefixes=["error","group"];var N=class{constructor(t,e="orthographic",r=50,i=.1,s=1e4){this.scaleCache=new Map;this._width=1;this._height=1;this.engine=t,this.mode=e,this.perspectiveFov=r,e==="orthographic"?this._camera=t.createOrthographicCamera(-1,1,1,-1,i,s):this._camera=t.createPerspectiveCamera(r,1,i,s),this._position=t.createVector3(0,0,1e3),this.update()}get camera(){return this._camera}resize(t,e){if(this._width=t,this._height=e,this.mode==="orthographic"){let r=this._camera;r.left=-t/2,r.right=t/2,r.top=e/2,r.bottom=-e/2}else this._camera.aspect=t/e;this.update()}setPosition(t,e,r){this._position.set(t,e,r),this._camera.position.copy(this._position),this.update()}lookAt(t,e,r){this._camera.lookAt(t,e,r),this.update()}update(){this._camera.updateProjectionMatrix(),this._camera.updateMatrixWorld?.()}screenToWorld(t,e,r=0){if(this.mode==="orthographic"){let i=t-this._width/2,s=-(e-this._height/2);return this.engine.createVector3(i,s,r)}else{let{width:i,height:s}=this.getFrustumSizeAt(r),n=t/this._width,a=e/this._height,l=(n-.5)*i,o=-(a-.5)*s;return this.engine.createVector3(l,o,r)}}getFrustumSizeAt(t){if(this.mode==="orthographic")return{width:this._width,height:this._height};let e=this.engine.degToRad(this.perspectiveFov),r=Math.abs(t-this._camera.position.z),i=2*Math.tan(e/2)*r;return{width:i*this._camera.aspect,height:i}}getScaleAtZ(t,e){if(this.mode==="orthographic")return 1;let r=Math.round(t*1e3)/1e3;if(this.scaleCache.has(r))return this.scaleCache.get(r);let{height:i}=this.getFrustumSizeAt(t),s=i/e;return this.scaleCache.set(r,s),s}clearScaleCache(){this.scaleCache.clear()}getMode(){return this.mode}getPerspectiveFov(){return this.perspectiveFov}getPositionZ(){return this._position.z}};var R=class{static register(t){let e=t.name.trim().toLowerCase();if(!e)throw new Error("[String3D] Custom filter name is required.");this.filters.set(e,{...t,name:e})}static get(t){return this.filters.get(t.trim().toLowerCase())}static has(t){return this.filters.has(t.trim().toLowerCase())}static list(){return Array.from(this.filters.values())}};R.filters=new Map;var re=class{constructor(t){this.pool=[];this.create=t}acquire(t,e){let r=this.pool.pop()||this.create(t,e);return(r.width!==t||r.height!==e)&&r.setSize(t,e),r}release(t){this.pool.push(t)}dispose(){this.pool.forEach(t=>t.dispose()),this.pool=[]}},K=class{constructor(t,e,r,i){this.scale=1;this.customMaterials=new Map;this.engine=t,this.renderer=e,this.width=r,this.height=i,this.scene=t.createScene(),this.camera=t.createOrthographicCamera(-1,1,1,-1,0,1);let s=t.createPlaneGeometry(2,2);this.copyMaterial=this.createCopyMaterial(),this.blurMaterial=this.createBlurMaterial(),this.pixelMaterial=this.createPixelMaterial(),this.bloomExtractMaterial=this.createBloomExtractMaterial(),this.bloomAddMaterial=this.createBloomAddMaterial(),this.colorMaterial=this.createColorMaterial(),this.quad=t.createMesh(s,this.copyMaterial),this.scene.add(this.quad);let n=(a,l)=>{if(!this.engine.createRenderTarget)throw new Error("[String3DFilterPipeline] Render target support missing.");return this.engine.createRenderTarget(a,l)};this.pool=new re(n)}isSupported(){return!!this.engine.createRenderTarget&&!!this.engine.createShaderMaterial&&!!this.renderer.setRenderTarget}resize(t,e){this.width=t,this.height=e}setScale(t){let e=Math.max(.75,Math.min(1,t));this.scale=e}applyFilters(t,e,r=1){let i=t,s=[],n=l=>{let o=s.indexOf(l);o>=0&&(s.splice(o,1),this.pool.release(l))},a=()=>{let{width:l,height:o}=this.getScaledSize(),c=this.pool.acquire(l,o);return s.push(c),c};return e.forEach(l=>{if(l.type==="blur"){let o=l.amount*r;if(o<=1e-4)return;let c=a();this.renderPass(this.blurMaterial,i,c,{uDirection:[1,0],uRadius:o});let p=a();this.renderPass(this.blurMaterial,c,p,{uDirection:[0,1],uRadius:o}),n(c),i!==t&&n(i),i=p}else if(l.type==="pixel"){if(l.size<=.5)return;let o=a();this.renderPass(this.pixelMaterial,i,o,{uPixelSize:l.size}),i!==t&&n(i),i=o}else if(l.type==="bloom"){let o=l.intensity;if(o<=1e-4||l.threshold>=.99)return;let c=Math.max(1,4*r),p=a();this.renderPass(this.bloomExtractMaterial,i,p,{uThreshold:l.threshold});let m=a();this.renderPass(this.blurMaterial,p,m,{uDirection:[1,0],uRadius:c});let u=a();this.renderPass(this.blurMaterial,m,u,{uDirection:[0,1],uRadius:c}),n(p),n(m);let g=a();this.renderAddPass(i,u,g,o),n(u),i!==t&&n(i),i=g}else if(l.type==="brightness"||l.type==="contrast"||l.type==="saturate"||l.type==="grayscale"||l.type==="sepia"||l.type==="invert"||l.type==="hue-rotate"){let o=a(),c=this.getColorMode(l.type),p=l.type==="hue-rotate"?l.angle:l.amount;this.renderPass(this.colorMaterial,i,o,{uMode:c,uAmount:p}),i!==t&&n(i),i=o}else if(l.type==="custom"){let o=a(),c=this.getCustomMaterial(l.name);c?(this.renderPass(c,i,o,l.uniforms),i!==t&&n(i),i=o):n(o)}}),s.forEach(l=>{l!==i&&this.pool.release(l)}),i}acquireTarget(){let{width:t,height:e}=this.getScaledSize();return this.pool.acquire(t,e)}releaseTarget(t){this.pool.release(t)}renderToScreen(t){this.renderPass(this.copyMaterial,t,null,{},!1)}dispose(){this.pool.dispose(),this.customMaterials.forEach(t=>t.dispose()),this.customMaterials.clear()}renderPass(t,e,r,i={},s=!0){let n=this.renderer;n.setRenderTarget&&n.setRenderTarget(r),this.setMaterial(this.quad,t),this.setUniform(t,"tDiffuse",e.texture);let{width:a,height:l}=this.getScaledSize();this.setUniform(t,"uResolution",[a,l]),this.setUniform(t,"uTexel",[1/a,1/l]),Object.entries(i).forEach(([o,c])=>this.setUniform(t,o,c)),s&&n.clear&&n.clear(!0,!0,!0),this.renderer.render(this.scene,this.camera)}renderAddPass(t,e,r,i){let s=this.renderer;s.setRenderTarget&&s.setRenderTarget(r),this.setMaterial(this.quad,this.bloomAddMaterial),this.setUniform(this.bloomAddMaterial,"tBase",t.texture),this.setUniform(this.bloomAddMaterial,"tBloom",e.texture),this.setUniform(this.bloomAddMaterial,"uIntensity",i);let{width:n,height:a}=this.getScaledSize();this.setUniform(this.bloomAddMaterial,"uResolution",[n,a]),s.clear&&s.clear(!0,!0,!0),this.renderer.render(this.scene,this.camera)}setMaterial(t,e){let r=t;r.material!==e&&(r.material=e)}setUniform(t,e,r){let i=t.uniforms;i&&(i[e]?i[e].value=r:i[e]={value:r})}createCopyMaterial(){return this.createShaderMaterial({uniforms:{tDiffuse:{value:null}},vertexShader:this.getVertexShader(),fragmentShader:`
|
|
2
|
+
varying vec2 vUv;
|
|
3
|
+
uniform sampler2D tDiffuse;
|
|
4
|
+
void main() {
|
|
5
|
+
gl_FragColor = texture2D(tDiffuse, vUv);
|
|
6
|
+
}
|
|
7
|
+
`,transparent:!0,depthTest:!1,depthWrite:!1})}createPixelMaterial(){return this.createShaderMaterial({uniforms:{tDiffuse:{value:null},uResolution:{value:[this.width,this.height]},uPixelSize:{value:1}},vertexShader:this.getVertexShader(),fragmentShader:`
|
|
8
|
+
varying vec2 vUv;
|
|
9
|
+
uniform sampler2D tDiffuse;
|
|
10
|
+
uniform vec2 uResolution;
|
|
11
|
+
uniform float uPixelSize;
|
|
12
|
+
void main() {
|
|
13
|
+
vec2 pixel = uPixelSize / uResolution;
|
|
14
|
+
vec2 coord = floor(vUv / pixel) * pixel + pixel * 0.5;
|
|
15
|
+
gl_FragColor = texture2D(tDiffuse, coord);
|
|
16
|
+
}
|
|
17
|
+
`,transparent:!0,depthTest:!1,depthWrite:!1})}createBlurMaterial(){return this.createShaderMaterial({uniforms:{tDiffuse:{value:null},uTexel:{value:[1/this.width,1/this.height]},uDirection:{value:[1,0]},uRadius:{value:2}},vertexShader:this.getVertexShader(),fragmentShader:`
|
|
18
|
+
varying vec2 vUv;
|
|
19
|
+
uniform sampler2D tDiffuse;
|
|
20
|
+
uniform vec2 uTexel;
|
|
21
|
+
uniform vec2 uDirection;
|
|
22
|
+
uniform float uRadius;
|
|
23
|
+
void main() {
|
|
24
|
+
vec2 off1 = uDirection * uTexel * uRadius;
|
|
25
|
+
vec2 off2 = uDirection * uTexel * uRadius * 2.0;
|
|
26
|
+
vec2 off3 = uDirection * uTexel * uRadius * 3.0;
|
|
27
|
+
vec2 off4 = uDirection * uTexel * uRadius * 4.0;
|
|
28
|
+
vec4 color = texture2D(tDiffuse, vUv) * 0.227027;
|
|
29
|
+
color += texture2D(tDiffuse, vUv + off1) * 0.1945946;
|
|
30
|
+
color += texture2D(tDiffuse, vUv - off1) * 0.1945946;
|
|
31
|
+
color += texture2D(tDiffuse, vUv + off2) * 0.1216216;
|
|
32
|
+
color += texture2D(tDiffuse, vUv - off2) * 0.1216216;
|
|
33
|
+
color += texture2D(tDiffuse, vUv + off3) * 0.054054;
|
|
34
|
+
color += texture2D(tDiffuse, vUv - off3) * 0.054054;
|
|
35
|
+
color += texture2D(tDiffuse, vUv + off4) * 0.016216;
|
|
36
|
+
color += texture2D(tDiffuse, vUv - off4) * 0.016216;
|
|
37
|
+
gl_FragColor = color;
|
|
38
|
+
}
|
|
39
|
+
`,transparent:!0,depthTest:!1,depthWrite:!1})}createBloomExtractMaterial(){return this.createShaderMaterial({uniforms:{tDiffuse:{value:null},uThreshold:{value:.8}},vertexShader:this.getVertexShader(),fragmentShader:`
|
|
40
|
+
varying vec2 vUv;
|
|
41
|
+
uniform sampler2D tDiffuse;
|
|
42
|
+
uniform float uThreshold;
|
|
43
|
+
void main() {
|
|
44
|
+
vec4 color = texture2D(tDiffuse, vUv);
|
|
45
|
+
float brightness = max(max(color.r, color.g), color.b);
|
|
46
|
+
gl_FragColor = brightness > uThreshold ? color : vec4(0.0);
|
|
47
|
+
}
|
|
48
|
+
`,transparent:!0,depthTest:!1,depthWrite:!1})}createBloomAddMaterial(){return this.createShaderMaterial({uniforms:{tBase:{value:null},tBloom:{value:null},uIntensity:{value:1},uResolution:{value:[this.width,this.height]}},vertexShader:this.getVertexShader(),fragmentShader:`
|
|
49
|
+
varying vec2 vUv;
|
|
50
|
+
uniform sampler2D tBase;
|
|
51
|
+
uniform sampler2D tBloom;
|
|
52
|
+
uniform float uIntensity;
|
|
53
|
+
void main() {
|
|
54
|
+
vec4 base = texture2D(tBase, vUv);
|
|
55
|
+
vec4 bloom = texture2D(tBloom, vUv);
|
|
56
|
+
gl_FragColor = vec4(base.rgb + bloom.rgb * uIntensity, base.a);
|
|
57
|
+
}
|
|
58
|
+
`,transparent:!0,depthTest:!1,depthWrite:!1})}createColorMaterial(){return this.createShaderMaterial({uniforms:{tDiffuse:{value:null},uMode:{value:0},uAmount:{value:1}},vertexShader:this.getVertexShader(),fragmentShader:`
|
|
59
|
+
varying vec2 vUv;
|
|
60
|
+
uniform sampler2D tDiffuse;
|
|
61
|
+
uniform int uMode;
|
|
62
|
+
uniform float uAmount;
|
|
63
|
+
|
|
64
|
+
vec3 applyHueRotate(vec3 color, float angle) {
|
|
65
|
+
float cosA = cos(angle);
|
|
66
|
+
float sinA = sin(angle);
|
|
67
|
+
mat3 m = mat3(
|
|
68
|
+
0.213 + cosA * 0.787 - sinA * 0.213,
|
|
69
|
+
0.715 - cosA * 0.715 - sinA * 0.715,
|
|
70
|
+
0.072 - cosA * 0.072 + sinA * 0.928,
|
|
71
|
+
0.213 - cosA * 0.213 + sinA * 0.143,
|
|
72
|
+
0.715 + cosA * 0.285 + sinA * 0.140,
|
|
73
|
+
0.072 - cosA * 0.072 - sinA * 0.283,
|
|
74
|
+
0.213 - cosA * 0.213 - sinA * 0.787,
|
|
75
|
+
0.715 - cosA * 0.715 + sinA * 0.715,
|
|
76
|
+
0.072 + cosA * 0.928 + sinA * 0.072
|
|
77
|
+
);
|
|
78
|
+
return clamp(m * color, 0.0, 1.0);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
void main() {
|
|
82
|
+
vec4 color = texture2D(tDiffuse, vUv);
|
|
83
|
+
float luma = dot(color.rgb, vec3(0.299, 0.587, 0.114));
|
|
84
|
+
|
|
85
|
+
if (uMode == 1) {
|
|
86
|
+
color.rgb *= uAmount;
|
|
87
|
+
} else if (uMode == 2) {
|
|
88
|
+
color.rgb = (color.rgb - 0.5) * uAmount + 0.5;
|
|
89
|
+
} else if (uMode == 3) {
|
|
90
|
+
color.rgb = mix(vec3(luma), color.rgb, uAmount);
|
|
91
|
+
} else if (uMode == 4) {
|
|
92
|
+
color.rgb = mix(color.rgb, vec3(luma), uAmount);
|
|
93
|
+
} else if (uMode == 5) {
|
|
94
|
+
vec3 sepia = vec3(
|
|
95
|
+
dot(color.rgb, vec3(0.393, 0.769, 0.189)),
|
|
96
|
+
dot(color.rgb, vec3(0.349, 0.686, 0.168)),
|
|
97
|
+
dot(color.rgb, vec3(0.272, 0.534, 0.131))
|
|
98
|
+
);
|
|
99
|
+
color.rgb = mix(color.rgb, sepia, uAmount);
|
|
100
|
+
} else if (uMode == 6) {
|
|
101
|
+
color.rgb = mix(color.rgb, vec3(1.0) - color.rgb, uAmount);
|
|
102
|
+
} else if (uMode == 7) {
|
|
103
|
+
color.rgb = applyHueRotate(color.rgb, uAmount);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
gl_FragColor = color;
|
|
107
|
+
}
|
|
108
|
+
`,transparent:!0,depthTest:!1,depthWrite:!1})}getColorMode(t){switch(t){case"brightness":return 1;case"contrast":return 2;case"saturate":return 3;case"grayscale":return 4;case"sepia":return 5;case"invert":return 6;case"hue-rotate":return 7;default:return 0}}createShaderMaterial(t){if(!this.engine.createShaderMaterial)throw new Error("[String3DFilterPipeline] Shader material support missing.");return this.engine.createShaderMaterial(t)}getCustomMaterial(t){let e=t.trim().toLowerCase();if(!e)return null;if(this.customMaterials.has(e))return this.customMaterials.get(e);let r=R.get(e);if(!r)return null;let i={tDiffuse:{value:null}},{width:s,height:n}=this.getScaledSize();i.uResolution={value:[s,n]},i.uTexel={value:[1/s,1/n]},Object.entries(r.uniforms||{}).forEach(([l,o])=>{i[l]={value:o}});let a=this.createShaderMaterial({uniforms:i,vertexShader:this.getVertexShader(),fragmentShader:r.fragmentShader,transparent:!0,depthTest:!1,depthWrite:!1});return this.customMaterials.set(e,a),a}getScaledSize(){let t=Math.max(1,Math.round(this.width*this.scale)),e=Math.max(1,Math.round(this.height*this.scale));return{width:t,height:e}}getVertexShader(){return`
|
|
109
|
+
varying vec2 vUv;
|
|
110
|
+
void main() {
|
|
111
|
+
vUv = uv;
|
|
112
|
+
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
113
|
+
}
|
|
114
|
+
`}};var _=class{constructor(t,e){this.filterPipeline=null;this.filterCache=new Map;this.frameId=0;this.lastFrameTime=performance.now();this.avgFrameMs=16.7;this.qualityScale=1;this.lastQualityChange=0;this.filterLayer=1;this.engine=e,this._container=t;let{width:r,height:i}=t.getBoundingClientRect();this._width=r,this._height=i,this._renderer=e.createRenderer({antialias:!0,alpha:!0,logarithmicDepthBuffer:!0}),this._renderer.setPixelRatio(window.devicePixelRatio),this._renderer.setSize(r,i),this._renderer.shadowMap&&(this._renderer.shadowMap.enabled=!0)}attach(){this._container.appendChild(this._renderer.domElement)}render(t,e,r=[]){if(r.length===0){this._renderer.render(t.getScene(),e.camera);return}let i=this.ensureFilterPipeline();if(!i?.isSupported()){this._renderer.render(t.getScene(),e.camera);return}this.frameId+=1,this.updateQuality(r.length,i);let s=t.getAllObjects(),n=new Map;s.forEach(m=>{let u=m.object;"visible"in u&&n.set(m.object,u.visible)});let a=new Set;r.forEach(m=>{this.collectSubtreeObjects(m.object,a)}),s.forEach(m=>{a.has(m.object)&&this.setVisible(m.object,!1)});let l=this._renderer,o=l.autoClear;l.autoClear=!0,l.setRenderTarget&&l.setRenderTarget(null),l.clear&&l.clear(!0,!0,!0),this._renderer.render(t.getScene(),e.camera),l.autoClear=!1,s.forEach(m=>{let u=n.get(m.object);typeof u<"u"&&this.setVisible(m.object,u)});let c=s.filter(m=>m.type.endsWith("Light")),p=this.supportsLayers(e.camera,s);r.forEach(m=>{let u=this.filterCache.get(m.object.id);if(!m.dirty&&u&&u.effectsKey===m.effectsKey&&u.qualityScale===this.qualityScale){u.lastUsedFrame=this.frameId,i.renderToScreen(u.target);return}let d=this.injectEffectContext(m.object.el,m.effects),f=new Set;this.collectSubtreeObjects(m.object,f);let v=[],b=null;if(p){let S=m.object.getSubtreeObjects();v=this.applyLayerMask(S,c,this.filterLayer),b=this.setCameraLayer(e.camera,this.filterLayer)}else s.forEach(S=>{if(n.get(S.object)===!1){this.setVisible(S.object,!1);return}if(S.type.endsWith("Light")){this.setVisible(S.object,!0);return}this.setVisible(S.object,f.has(S.object))});let M=i.acquireTarget();l.setRenderTarget&&l.setRenderTarget(M),l.clear&&l.clear(!0,!0,!0),this._renderer.render(t.getScene(),e.camera);let y=i.applyFilters(M,d,this.qualityScale);l.setRenderTarget&&l.setRenderTarget(null),i.renderToScreen(y),p&&(this.restoreLayerMask(v),b!==null&&this.restoreCameraLayer(e.camera,b)),y!==M&&i.releaseTarget(M);let w={target:y,effectsKey:m.effectsKey,lastUsedFrame:this.frameId,qualityScale:this.qualityScale},x=this.filterCache.get(m.object.id);x&&x.target!==y&&i.releaseTarget(x.target),this.filterCache.set(m.object.id,w)}),p||s.forEach(m=>{let u=n.get(m.object);typeof u<"u"&&this.setVisible(m.object,u)}),l.autoClear=o,this.evictCache()}resize(t){let{width:e,height:r}=this._container.getBoundingClientRect();this._width=e,this._height=r,this._renderer.setSize(e,r),t.resize(e,r),this.filterPipeline?.resize(e,r),this.invalidateFilterCache()}get width(){return this._width}get height(){return this._height}get renderer(){return this._renderer}destroy(){this._renderer.dispose(),this.filterPipeline?.dispose(),this.filterCache.clear()}ensureFilterPipeline(){return this.canCreateFilterPipeline()?(this.filterPipeline||(this.filterPipeline=new K(this.engine,this._renderer,this._width,this._height),this.filterPipeline.setScale(this.qualityScale)),this.filterPipeline):null}canCreateFilterPipeline(){return typeof this.engine.createRenderTarget=="function"&&typeof this.engine.createShaderMaterial=="function"&&typeof this._renderer.setRenderTarget=="function"}collectSubtreeObjects(t,e){e.add(t.object),t.children.forEach(r=>this.collectSubtreeObjects(r,e))}setVisible(t,e){let r=t;"visible"in r&&(r.visible=e)}getFilterCenter(t){if(!t||!this._width||!this._height)return[.5,.5];let e=t.getBoundingClientRect(),r=(e.left+e.width/2)/this._width,i=1-(e.top+e.height/2)/this._height,s=n=>Math.max(0,Math.min(1,n));return[s(r),s(i)]}injectEffectContext(t,e){if(!e.some(n=>n.type==="custom"))return e;let r=this.getFilterCenter(t),i=!1,s=e.map(n=>{if(n.type!=="custom"||n.uniforms&&"uCenter"in n.uniforms)return n;let a={...n.uniforms||{},uCenter:r};return i=!0,{...n,uniforms:a}});return i?s:e}updateQuality(t,e){let r=performance.now(),i=Math.max(.1,r-this.lastFrameTime);this.lastFrameTime=r,this.avgFrameMs=this.avgFrameMs*.9+i*.1;let s=1e3/this.avgFrameMs,n=Math.max(.75,1-Math.min(.4,t*.03)),a=n;s<48&&(a=Math.max(.75,n-.1)),s<40&&(a=Math.max(.75,n-.2)),s>58&&(a=Math.min(1,n+.05)),Math.abs(a-this.qualityScale)>=.05&&r-this.lastQualityChange>300&&(this.qualityScale=a,this.lastQualityChange=r,e.setScale(this.qualityScale),this.invalidateFilterCache())}invalidateFilterCache(){this.filterPipeline&&(this.filterCache.forEach(t=>{this.filterPipeline?.releaseTarget(t.target)}),this.filterCache.clear())}evictCache(){if(!this.filterPipeline)return;let t=120;this.filterCache.forEach((e,r)=>{this.frameId-e.lastUsedFrame>t&&(this.filterPipeline?.releaseTarget(e.target),this.filterCache.delete(r))})}supportsLayers(t,e){return!t?.layers||typeof t.layers.set!="function"?!1:e.some(r=>this.hasLayers(r.object))}hasLayers(t){return t?.layers&&typeof t.layers.set=="function"}applyLayerMask(t,e,r){let i=new Map,s=(n,a)=>{let l=n;this.hasLayers(l)&&(i.has(n)||i.set(n,l.layers.mask),a==="set"?l.layers.set(r):l.layers.enable(r))};return t.forEach(n=>s(n,"set")),e.forEach(n=>s(n.object,"enable")),Array.from(i.entries()).map(([n,a])=>({object:n,mask:a}))}restoreLayerMask(t){t.forEach(e=>{let r=e.object;this.hasLayers(r)&&(r.layers.mask=e.mask)})}setCameraLayer(t,e){if(!t?.layers||typeof t.layers.set!="function")return null;let r=t.layers.mask;return t.layers.set(e),r}restoreCameraLayer(t,e){t?.layers&&(t.layers.mask=e)}};var D=class{constructor(t,e,r,i,s={}){this._uniforms={};this._children=[];this._flatObjectsCache=null;this._subtreeCache=null;this.id=t,this.type=e,this._object=r,this.engine=i,this._material=s.material,this._geometry=s.geometry,this._texture=s.texture,this._quaternion=i.createQuaternion(),this._originalSize=i.createVector3(),this._bbox=i.createBox3(),this.updateBoundingBox()}get children(){return this._children}get object(){return this._object}get material(){return this._material}get originalSize(){return this._originalSize.clone()}get boundingBox(){return this._bbox.clone()}addChild(t){this._children.push(t),this.object.add(t.object),this.invalidateFlatCache(),this.invalidateSubtreeCache()}getWorldMatrix(){return this._object.matrixWorld.clone()}getWorldPosition(){return this.engine.createVector3().setFromMatrixPosition(this._object.matrixWorld)}getOriginalBoundingBox(){if(!this._originalBoundingBox){let t=this.object.scale.clone();this.object.scale.set(1,1,1),this.object.updateMatrixWorld(!0),this._originalBoundingBox=this.engine.computeBoundingBoxRecursively(this.object),this.object.scale.copy(t),this.object.updateMatrixWorld(!0)}return this._originalBoundingBox.clone()}syncTransformFromMatrix(t){let e=this.engine.createVector3(),r=this.engine.createQuaternion(),i=this.engine.createVector3();t.decompose(e,r,i),this._object.position.copy(e),this._object.quaternion.copy(r),this._object.scale.copy(i),this._object.updateMatrix(),this._object.updateMatrixWorld()}applyWorldTransform(t,e,r){this._object.position.copy(t),this._object.quaternion.copy(e),this._object.scale.copy(r),this._object.updateMatrix(),this._object.updateMatrixWorld()}set quaternion(t){this._quaternion.copy(t),this._object.quaternion.copy(this._quaternion),this._object.updateMatrixWorld()}set position(t){this._object.position.copy(t)}set scale(t){this._object.scale.copy(t)}set rotation(t){this._object.rotation.copy(t)}set opacity(t){let e=this._object;e.material&&"opacity"in e.material&&(e.material.opacity=t)}set metalness(t){let e=this._object;e.material&&"metalness"in e.material&&(e.material.metalness=t)}set roughness(t){let e=this._object;e.material&&"roughness"in e.material&&(e.material.roughness=t)}set texture(t){this._texture=t,this._object.isMesh&&t?.applyTexture&&t.applyTexture(this._object)}set material(t){this._material=t}set geometry(t){this._geometry=t}updateBoundingBox(){this._bbox.setFromObject(this._object),this._bbox.getSize(this._originalSize)}destroy(){this.disposeObjectResources(this._object),this._texture?.dispose?.(),this._material?.dispose(),this._geometry?.dispose(),this._subtreeCache=null}getFlatObjects(){if(this._flatObjectsCache)return this._flatObjectsCache;let t=[],e=r=>{t.push(r.object),r.children.forEach(i=>e(i))};return e(this),this._flatObjectsCache=t,t}getSubtreeObjects(){if(this._subtreeCache)return this._subtreeCache;let t=[],e=this._object;return t.push(this._object),typeof e.traverse=="function"&&e.traverse(r=>{r&&r!==this._object&&t.push(r)}),this._subtreeCache=t,t}invalidateFlatCache(){this._flatObjectsCache=null}invalidateSubtreeCache(){this._subtreeCache=null}disposeObjectResources(t){let e=t;e?.geometry?.dispose&&e.geometry.dispose();let r=e?.material;Array.isArray(r)?r.forEach(i=>i?.dispose?.()):r?.dispose&&r.dispose(),typeof e?.traverse=="function"&&e.traverse(i=>{i?.geometry?.dispose&&i.geometry.dispose();let s=i?.material;Array.isArray(s)?s.forEach(n=>n?.dispose?.()):s?.dispose&&s.dispose()})}};var W=class{constructor(t,e={}){this._objects=new Map;this._rootObjects=[];this._elementMap=new Map;this._modelLoaderCache=new Map;this.engine=t,this._modelLoader=e.modelLoader,this._modelLoaderFactory=e.modelLoaderFactory,this._scene=t.createScene()}get rootObjects(){return this._rootObjects}getScene(){return this._scene}getObject(t){return this._objects.get(t)}getAllObjects(){let t=[],e=r=>{t.push(r),r.children.forEach(i=>e(i))};return this._rootObjects.forEach(r=>e(r)),t}hasObject(t){return this._objects.has(t)}deleteObject(t){let e=this._objects.get(t);return e?(this._scene.remove(e.object),this._objects.delete(t),e.destroy(),!0):!1}createFromElement(t){let e=t.getProperty("3d");if(!e)return;let r=t.htmlElement;if(!r)return;let i=s=>{if(s){let n=t.getProperty("parentId");n==null?(this._scene.add(s.object),this._rootObjects.push(s)):this._objects.get(n)?.addChild(s),this._objects.set(t.id,s),this._elementMap.set(t.id,r),s.el=r}};switch(e){case"group":this.createGroup(t,i);break;case"pointLight":this.createLight(t,"point",i);break;case"ambientLight":this.createLight(t,"ambient",i);break;case"directionalLight":this.createLight(t,"directional",i);break;case"spotLight":this.createLight(t,"spot",i);break;case"hemisphereLight":this.createLight(t,"hemisphere",i);break;case"model":this.createModel(t,i);break;case"box":this.createBox(t,i);break;case"sphere":this.createSphere(t,i);break;case"plane":this.createPlane(t,i);break;case"cylinder":this.createCylinder(t,i);break}}createGroup(t,e){let r=this.engine.createGroup(),i=new D(t.id,"group",r,this.engine);return e(i),i}createLight(t,e,r){let i=t.getProperty("3d-color")||"#ffffff",s=t.getProperty("3d-intensity")??1,n;if(e==="point"){let o=t.getProperty("3d-distance")??1e3,c=t.getProperty("3d-decay")??0;n=this.engine.createPointLight(i,s,o,c)}else if(e==="directional")n=this.engine.createDirectionalLight(i,s);else if(e==="spot"){let o=t.getProperty("3d-distance")??0,c=t.getProperty("3d-angle")??Math.PI/3,p=t.getProperty("3d-penumbra")??0,m=t.getProperty("3d-decay")??1;n=this.engine.createSpotLight(i,s,o,c,p,m)}else if(e==="hemisphere"){let o=t.getProperty("3d-ground-color")||"#ffffff";n=this.engine.createHemisphereLight(i,o,s)}else n=this.engine.createAmbientLight(i,s);if((t.getProperty("3d-cast-shadow")??!1)&&n.shadow){n.castShadow=!0;let o=t.getProperty("3d-shadow-bias")??0,c=t.getProperty("3d-shadow-map-size")??512;n.shadow.bias=o,n.shadow.mapSize.width=c,n.shadow.mapSize.height=c}let l=new D(t.id,e+"Light",n,this.engine);return r(l),l}applyShadowProps(t,e){let r=t.getProperty("3d-cast-shadow")??!1,i=t.getProperty("3d-receive-shadow")??!1;e.castShadow=r,e.receiveShadow=i}createBox(t,e){let r=this.engine.createBoxGeometry(1,1,1),i=this.createMaterialFromObject(t),s=this.engine.createMesh(r,i);this.applyShadowProps(t,s);let n=new D(t.id,"box",s,this.engine,{geometry:r,material:i});return e(n),n}createSphere(t,e){let r=t.getProperty("3d-segments-width")??32,i=t.getProperty("3d-segments-height")??32,s=this.engine.createSphereGeometry(.5,r,i),n=this.createMaterialFromObject(t),a=this.engine.createMesh(s,n);this.applyShadowProps(t,a);let l=new D(t.id,"sphere",a,this.engine,{geometry:s,material:n});return e(l),l}createPlane(t,e){let r=this.engine.createPlaneGeometry(1,1),i=this.createMaterialFromObject(t),s=this.engine.createMesh(r,i);this.applyShadowProps(t,s);let n=new D(t.id,"plane",s,this.engine,{geometry:r,material:i});return e(n),n}createCylinder(t,e){let r=t.getProperty("3d-segments")??32,i=this.engine.createCylinderGeometry(.5,.5,1,r),s=this.createMaterialFromObject(t),n=this.engine.createMesh(i,s);this.applyShadowProps(t,n);let a=new D(t.id,"cylinder",n,this.engine,{geometry:i,material:s});return e(a),a}createModel(t,e){let r=t.getProperty("3d-model");if(!r)return;let i=t.getProperty("3d-model-loader")||void 0,s=this.resolveModelLoader(i);if(!s){console.warn("[String3D] Model loader not configured");return}let n=t.htmlElement;n&&this.applyModelTextureRemap(s,n);let a=t.getProperty("3d-model-center")??!1;s.load(r,l=>{let o=l?.scene||l?.object||l;if(!o){console.warn("[String3D] Model loader returned empty result");return}let c=n&&this.shouldOverrideModelMaterial(n)?this.createMaterialFromElement(n,t):null;typeof o.traverse=="function"&&o.traverse(m=>{m.isMesh&&(c&&(m.material=c),this.applyShadowProps(t,m))}),a&&this.centerObject(o);let p=new D(t.id,"model",o,this.engine);e(p)},l=>{console.log(l.loaded/l.total*100+"% loaded")},l=>{console.error("[String3D] Model loading error:",l)})}resolveModelLoader(t){if(t){if(this._modelLoaderCache.has(t))return this._modelLoaderCache.get(t);if(!this._modelLoaderFactory){console.warn(`[String3D] No model loader factory for type "${t}"`);return}let e=this._modelLoaderFactory(this.engine,t);return this._modelLoaderCache.set(t,e),e}if(this._modelLoader)return this._modelLoader;if(this._modelLoaderFactory)return this._modelLoaderFactory(this.engine)}centerObject(t){if(!t)return;let e=this.engine.computeBoundingBoxRecursively(t),r=this.getBoxCenter(e);t.position?.set&&t.position.set(-r.x,-r.y,-r.z),t.updateMatrixWorld(!0)}getBoxCenter(t){let e=this.engine.createVector3();return e.x=(t.min.x+t.max.x)/2,e.y=(t.min.y+t.max.y)/2,e.z=(t.min.z+t.max.z)/2,e}createMaterialFromObject(t){return this.createMaterialFromElement(t.htmlElement,t)}createMaterialFromElement(t,e){let r=e?.getProperty("3d-material")||"basic[#ffffff]",[i,s]=r.split(/\[|\]/),n=s||"#ffffff",a=e?.getProperty("3d-opacity")??1,l=e?.getProperty("3d-metalness"),o=e?.getProperty("3d-roughness"),c={color:n,transparent:a<1,opacity:a},p=t?.getAttribute("string-3d-map"),m=t?.getAttribute("string-3d-normalMap"),u=t?.getAttribute("string-3d-roughnessMap"),g=t?.getAttribute("string-3d-metalnessMap"),d=t?.getAttribute("string-3d-aoMap"),f=this.parseFlipY(e,t),v=e?.getProperty("3d-colorSpace")||t?.getAttribute("string-3d-colorSpace")||"";return i!=="standard"&&!!(p||m||u||g||d)&&(i="standard"),i==="standard"?(p&&(c.map=this.loadTexture(p,{flipY:f,colorSpace:v})),m&&(c.normalMap=this.loadTexture(m,{flipY:f})),u&&(c.roughnessMap=this.loadTexture(u,{flipY:f})),g&&(c.metalnessMap=this.loadTexture(g,{flipY:f})),d&&(c.aoMap=this.loadTexture(d,{flipY:f})),typeof l=="number"&&(c.metalness=l),typeof o=="number"&&(c.roughness=o),this.engine.createMeshStandardMaterial(c)):this.engine.createMeshBasicMaterial(c)}loadTexture(t,e={}){let i=this.engine.createTextureLoader().load(t);typeof e.flipY=="boolean"&&(i.flipY=e.flipY);let s=(e.colorSpace||"").toLowerCase().trim();return s&&"colorSpace"in i&&(i.colorSpace=s==="srgb"?"srgb":"linear"),i.needsUpdate=!0,i}parseFlipY(t,e){let r=t?.getProperty("3d-texture-flipY")??e?.getAttribute("string-3d-texture-flipY");if(r==null||r==="")return;if(typeof r=="boolean")return r;let i=String(r).toLowerCase().trim();if(i==="false"||i==="0"||i==="no")return!1;if(i==="true"||i==="1"||i==="yes")return!0}shouldOverrideModelMaterial(t){return["string-3d-material","string-3d-color","string-3d-opacity","string-3d-map","string-3d-normalMap","string-3d-roughnessMap","string-3d-metalnessMap","string-3d-aoMap","string-3d-metalness","string-3d-roughness"].some(r=>t.hasAttribute(r))}applyModelTextureRemap(t,e){let r=(e.getAttribute("string-3d-model-texture-base")||"").trim(),i=r?r.replace(/\/?$/,"/"):"",s=e.getAttribute("string-3d-model-textures"),n=null;if(s)try{n=JSON.parse(s)}catch(l){console.warn("[String3D] Invalid model texture mapping JSON:",l)}let a=t?.manager;if(!a||typeof a.setURLModifier!="function"){(n||i)&&console.warn("[String3D] Model loader does not support URL remap.");return}a.setURLModifier(l=>{let o=n&&l in n?n[l]:l;return!i||/^(blob:|data:|https?:|file:|\/)/i.test(o)?o:i+o.replace(/^\.?\//,"")})}destroy(){this._objects.forEach(t=>t.destroy()),this._objects.clear(),this._rootObjects=[]}};var Z=class{sync(t,e,r,i){let s=t.getBoundingClientRect(),n=s.left+s.width/2,a=s.top+s.height/2,l=t.computedStyleMap?.(),o=null,c=()=>(o||(o=getComputedStyle(t)),o),p=(b,M)=>{let y=l?.get?.(b);if(y!==void 0){if(typeof y=="number")return y;if(typeof y=="string"){let S=Number.parseFloat(y);if(!Number.isNaN(S))return S}if(y&&typeof y=="object"){let S=y.value;if(typeof S=="number")return S;if(typeof S=="string"){let C=Number.parseFloat(S);if(!Number.isNaN(C))return C}}}let w=c().getPropertyValue(b),x=Number.parseFloat(w);return Number.isNaN(x)?M:x},m=p("--translate-z",0),u=r.camera.screenToWorld(n,a,m);e.position=u;let g=p("--scale",1);e.scale=r.engine.createVector3(g,g,g);let d=-r.engine.degToRad(p("--rotate-x",0)),f=r.engine.degToRad(p("--rotate-y",0)),v=-r.engine.degToRad(p("--rotate-z",0));return e.rotation=r.engine.createEuler(d,f,v,"XYZ"),e.object.updateMatrixWorld(!0),{scale:g}}};var F=class{sync(t,e,r,i){let s=t.getBoundingClientRect(),n=s.left+s.width/2,a=s.top+s.height/2,l=parseFloat(getComputedStyle(t).getPropertyValue("--translate-z")||"0"),o=r.camera.screenToWorld(n,a,l);e.position=o;let c=e.object,p=t.getAttribute("string-3d-color");p&&c.color&&typeof c.color.set=="function"&&c.color.set(p);let m=t.getAttribute("string-3d-intensity");m&&(c.intensity=parseFloat(m));let u=t.getAttribute("string-3d-distance");u&&typeof c.distance<"u"&&(c.distance=parseFloat(u));let g=t.getAttribute("string-3d-decay");g&&typeof c.decay<"u"&&(c.decay=parseFloat(g));let d=t.getAttribute("string-3d-angle");d&&typeof c.angle<"u"&&(c.angle=parseFloat(d));let f=t.getAttribute("string-3d-penumbra");f&&typeof c.penumbra<"u"&&(c.penumbra=parseFloat(f));let v=t.getAttribute("string-3d-ground-color");v&&c.groundColor&&typeof c.groundColor.set=="function"&&c.groundColor.set(v);let b=t.getAttribute("string-3d-cast-shadow")==="true";if(c.castShadow!==b&&(c.castShadow=b),b&&c.shadow){let y=t.getAttribute("string-3d-shadow-bias");y&&(c.shadow.bias=parseFloat(y));let w=t.getAttribute("string-3d-shadow-map-size");if(w){let x=parseFloat(w);c.shadow.mapSize.width!==x&&(c.shadow.mapSize.width=x,c.shadow.mapSize.height=x)}}let M=t.getAttribute("string-3d-target");if(M&&c.target){let y=document.querySelector(`[string-id="${M}"]`);if(y){let w=y.getBoundingClientRect(),x=w.left+w.width/2,S=w.top+w.height/2,C=parseFloat(getComputedStyle(y).getPropertyValue("--translate-z")||"0"),P=r.camera.screenToWorld(x,S,C);c.target.position.copy(P),c.target.updateMatrixWorld(!0)}}return null}};var k=class h{static applyVisualProps(t,e,r){let i=t.getAttribute("string-3d-cast-shadow")==="true",s=t.getAttribute("string-3d-receive-shadow")==="true",n=typeof r=="number"?r:NaN;if(e.object.traverse)e.object.traverse(a=>{a.isMesh&&(a.castShadow!==i&&(a.castShadow=i),a.receiveShadow!==s&&(a.receiveShadow=s),isNaN(n)||(Array.isArray(a.material)?a.material:[a.material]).forEach(o=>{o&&(o.opacity=n,o.transparent=n<1)}))});else if(e.object.isMesh){let a=e.object;a.castShadow!==i&&(a.castShadow=i),a.receiveShadow!==s&&(a.receiveShadow=s),isNaN(n)||(Array.isArray(a.material)?a.material:[a.material]).forEach(o=>{o&&(o.opacity=n,o.transparent=n<1)})}}sync(t,e,r,i){let s=t.computedStyleMap?.(),n=null,a=()=>(n||(n=getComputedStyle(t)),n),l=t.getBoundingClientRect(),o=t.offsetWidth||l.width,c=t.offsetHeight||l.height,p=(T,z)=>{let L=s?.get?.(T);if(L!==void 0){if(typeof L=="number")return L;if(typeof L=="string"){let E=Number.parseFloat(L);if(!Number.isNaN(E))return E}if(L&&typeof L=="object"){let E=L.value;if(typeof E=="number")return E;if(typeof E=="string"){let V=Number.parseFloat(E);if(!Number.isNaN(V))return V}}}let q=a().getPropertyValue(T),O=Number.parseFloat(q);return Number.isNaN(O)?z:O},m=p("--translate-z",0),u=p("--scale",1),g=l.left+l.width/2,d=l.top+l.height/2,f=r.camera.screenToWorld(g,d,m);e.position=f;let v=-r.engine.degToRad(p("--rotate-x",0)),b=r.engine.degToRad(p("--rotate-y",0)),M=-r.engine.degToRad(p("--rotate-z",0));e.rotation=r.engine.createEuler(v,b,M,"XYZ");let y=o*u,w=c*u,x=p("--scale-z",1),S=i?.scale||1,C=e.type,P,A,I;switch(C){case"box":case"sphere":{let T=Math.min(y,w);P=T*S,A=T*S,I=T*x*S;break}case"model":{let z=e.getOriginalBoundingBox().getSize(r.engine.createVector3()),L=(t.getAttribute("string-3d-model-fit")||"contain").toLowerCase().trim(),q=parseFloat(t.getAttribute("string-3d-model-scale")||"1"),O=Number.isFinite(q)?q:1;if(z.x>0&&z.y>0){let E=y/z.x,V=w/z.y,J=L==="cover"?Math.max(E,V):Math.min(E,V);P=J*O*S,A=J*O*S,I=J*O*x*S}else{let E=Math.min(y,w);P=E*O*S,A=E*O*S,I=E*O*x*S}break}case"cylinder":{let T=y;P=T*S,A=w*S,I=T*x*S;break}case"plane":default:P=y*S,A=w*S,I=Math.min(y,w)*.5*x*S;break}e.scale=r.engine.createVector3(P,A,I);let U=p("--opacity",NaN);return h.applyVisualProps(t,e,U),{scale:u*S}}};var H=class{constructor(t,e,r,i){this.camera=t;this.viewportWidth=e;this.viewportHeight=r;this.engine=i;this.strategies=new Map;this.strategies.set("box",new k),this.strategies.set("sphere",new k),this.strategies.set("plane",new k),this.strategies.set("cylinder",new k),this.strategies.set("model",new k),this.strategies.set("group",new Z),this.strategies.set("pointLight",new F),this.strategies.set("ambientLight",new F),this.strategies.set("directionalLight",new F),this.strategies.set("spotLight",new F),this.strategies.set("hemisphereLight",new F)}syncElement(t,e,r){let i=this.strategies.get(e.type);return i?i.sync(t,e,{camera:this.camera,viewportWidth:this.viewportWidth,viewportHeight:this.viewportHeight,engine:this.engine},r):(console.warn(`[String3D Sync] No strategy for type "${e.type}"`),null)}updateViewportSize(t,e){this.viewportWidth=t,this.viewportHeight=e}};var ye=`
|
|
2
115
|
let wasm = null;
|
|
3
116
|
let wasmReady = false;
|
|
4
117
|
|
|
@@ -131,7 +244,7 @@ self.onmessage = async (event) => {
|
|
|
131
244
|
self.postMessage({ type: "result", frameId: data.frameId, results });
|
|
132
245
|
}
|
|
133
246
|
};
|
|
134
|
-
`,
|
|
247
|
+
`,B=class{constructor(t={}){this.worker=null;this.ready=!1;this.lastResult=null;this.pending=!1;if(typeof Worker>"u")return;let e=new Blob([ye],{type:"text/javascript"});this.worker=new Worker(URL.createObjectURL(e)),this.worker.onmessage=r=>{let i=r.data||{};if(i.type==="ready"){this.ready=!0;return}i.type==="result"&&(this.lastResult={frameId:typeof i.frameId=="number"?i.frameId:0,results:i.results||[]},this.pending=!1)},this.worker.postMessage({type:"init",wasmUrl:t.wasmUrl})}isReady(){return this.ready}isPending(){return this.pending}submit(t,e,r){!this.worker||!this.ready||this.pending||(this.pending=!0,this.worker.postMessage({type:"compute",frameId:r,items:t,camera:e}))}takeLastResult(){let t=this.lastResult;return this.lastResult=null,t}destroy(){this.worker?.terminate(),this.worker=null,this.ready=!1,this.pending=!1,this.lastResult=null}};var j=class j extends X{constructor(e){super(e);this.renderer=null;this.camera=null;this.scene=null;this.synchronizer=null;this.engine=null;this.canvasContainer=null;this.isLoading=new Map;this.useDirtySync=!1;this.dirtyElements=new Set;this.observedElements=new Set;this.resizeObserver=null;this.mutationObserver=null;this.lastSyncData=new WeakMap;this.transformWorker=null;this.workerHasResult=!1;this.workerObjectMap=new Map;this.domVersion=0;this.lastSubmittedVersion=0;this.scrollTicking=!1;this.onScrollBound=()=>this.handleScroll();this.filterStates=new WeakMap;this.filterWarnings=new WeakMap;this.htmlKey="3d",this.options=this.buildOptionsFromSettings(),this.attributesToMap=[...this.attributesToMap,{key:"3d",type:"string",fallback:"box"},{key:"3d-material",type:"string",fallback:"basic[#ffffff]"},{key:"3d-color",type:"string",fallback:"#ffffff"},{key:"3d-opacity",type:"number",fallback:1},{key:"3d-intensity",type:"number",fallback:1},{key:"3d-distance",type:"number",fallback:1e3},{key:"3d-decay",type:"number",fallback:0},{key:"3d-model",type:"string",fallback:""},{key:"3d-segments",type:"number",fallback:32},{key:"3d-segments-width",type:"number",fallback:32},{key:"3d-segments-height",type:"number",fallback:32},{key:"3d-model-loader",type:"string",fallback:""},{key:"3d-model-scale",type:"number",fallback:1},{key:"3d-model-center",type:"boolean",fallback:!1},{key:"3d-model-fit",type:"string",fallback:"contain"},{key:"3d-metalness",type:"number",fallback:0},{key:"3d-roughness",type:"number",fallback:1},{key:"3d-texture-flipY",type:"boolean",fallback:!0},{key:"3d-colorSpace",type:"string",fallback:""},{key:"3d-cast-shadow",type:"boolean",fallback:!1},{key:"3d-receive-shadow",type:"boolean",fallback:!1},{key:"3d-shadow-bias",type:"number",fallback:0},{key:"3d-shadow-map-size",type:"number",fallback:512},{key:"3d-angle",type:"number",fallback:Math.PI/3},{key:"3d-penumbra",type:"number",fallback:0},{key:"3d-ground-color",type:"string",fallback:"#ffffff"},{key:"3d-target",type:"string",fallback:""}]}static setProvider(e){j.provider=e}canConnect(e){let r=super.canConnect(e);return console.log("[String3D] canConnect:",e.id,"keys:",e.keys,"htmlKey:",this.htmlKey,"result:",r),r}initializeObject(e,r,i,s){super.initializeObject(e,r,i,s),r.setProperty("parentId",null);let n=i.parentElement?.closest('[string-3d="group"]');if(n){let a=n.getAttribute("string-id");a&&(r.setProperty("parentId",a),r.setProperty("parent",n))}}onResize(){this.renderer&&this.camera&&this.synchronizer&&(this.renderer.resize(this.camera),this.synchronizer.updateViewportSize(this.renderer.width,this.renderer.height),this.camera.clearScaleCache(),this.useDirtySync&&this.markAllDirty())}onInit(){if(this.options=this.buildOptionsFromSettings(),!j.provider){console.error("[String3D] No provider set. Call String3D.setProvider() before use.");return}this.engine=j.provider.getEngine(),this.canvasContainer=this.createOrGetContainer(),this.registerTypedProperties(),this.injectCSS(),this.useDirtySync=!!this.options.useDirtySync,this.useDirtySync&&(this.setupObservers(),this.setupScrollListeners()),this.renderer=new _(this.canvasContainer,this.engine),this.renderer.attach(),this.camera=new N(this.engine,"orthographic"),this.camera.setPosition(0,0,1e3),this.camera.resize(this.renderer.width,this.renderer.height);let e=this.resolveModelLoader(),r=this.resolveModelLoaderFactory();this.scene=new W(this.engine,{modelLoader:e,modelLoaderFactory:r}),this.scene.getScene().add(this.camera.camera),this.synchronizer=new H(this.camera,this.renderer.width,this.renderer.height,this.engine),this.options.useTransformWorker&&(this.transformWorker=new B({wasmUrl:this.options.transformWorkerWasmUrl})),console.info(`[String3D] Initialized with: ${j.provider.getName()}`)}onSettingsChange(){this.options=this.buildOptionsFromSettings();let e=!!this.options.useDirtySync;e&&!this.useDirtySync?(this.useDirtySync=!0,this.setupObservers(),this.setupScrollListeners(),this.observeSceneElements(),this.markAllDirty()):!e&&this.useDirtySync&&(this.useDirtySync=!1,this.removeScrollListeners(),this.resizeObserver?.disconnect(),this.mutationObserver?.disconnect(),this.dirtyElements.clear());let r=!!this.options.useTransformWorker;r&&!this.transformWorker?(this.transformWorker=new B({wasmUrl:this.options.transformWorkerWasmUrl}),this.workerHasResult=!1):!r&&this.transformWorker&&(this.transformWorker.destroy(),this.transformWorker=null,this.workerHasResult=!1)}buildOptionsFromSettings(){return{hideHTML:this.getSettingValue("hideHTML",!1),container:this.getSettingValue("container",void 0),zIndex:this.getSettingValue("zIndex",1),modelLoaderType:this.getSettingValue("modelLoaderType",void 0),modelLoader:this.getSettingValue("modelLoader",void 0),modelLoaderFactory:this.getSettingValue("modelLoaderFactory",void 0),useDirtySync:this.getSettingValue("useDirtySync",!1),useTransformWorker:this.getSettingValue("useTransformWorker",!1),transformWorkerWasmUrl:this.getSettingValue("transformWorkerWasmUrl",void 0)}}getSettingValue(e,r){return!this.settings||!(e in this.settings)?r:this.settings[e]}resolveModelLoader(){if(this.engine){if(this.options.modelLoader)return this.options.modelLoader;if(!this.options.modelLoaderFactory&&this.options.modelLoaderType)try{return this.engine.createModelLoader(this.options.modelLoaderType)}catch(e){console.warn("[String3D] Failed to create model loader:",e)}}}resolveModelLoaderFactory(){if(this.engine){if(this.options.modelLoaderFactory)return this.options.modelLoaderFactory;if(this.options.modelLoaderType)return(e,r)=>{let i=r||this.options.modelLoaderType;if(!i)throw new Error("[String3D] Model loader type not provided");return e.createModelLoader(i)}}}createOrGetContainer(){if(this.options.container instanceof HTMLElement)return this.applyContainerStyles(this.options.container),this.options.container;if(typeof this.options.container=="string"){let r=document.getElementById(this.options.container);if(r)return this.applyContainerStyles(r),r}let e=document.createElement("div");return e.id="string-3d-canvas",this.applyContainerStyles(e),document.body.insertBefore(e,document.body.firstChild),e}applyContainerStyles(e){Object.assign(e.style,{position:"fixed",left:"0",top:"0",width:"100vw",height:"100lvh",zIndex:String(this.options.zIndex),pointerEvents:"none"})}onObjectConnected(e){this.isLoading.has(e.id)||!this.scene||(this.isLoading.set(e.id,!0),this.scene.createFromElement(e),this.useDirtySync&&e.htmlElement&&(this.observeElement(e.htmlElement),this.markDirty(e.htmlElement)),this.options.hideHTML&&e.htmlElement&&(e.htmlElement.style.opacity="0",e.htmlElement.style.pointerEvents="none"))}onFrame(e){if(!this.renderer||!this.scene||!this.camera||!this.synchronizer)return;let r=this.transformWorker?.takeLastResult();r&&r.frameId===this.lastSubmittedVersion&&r.frameId>=this.domVersion&&(this.workerHasResult=!0,this.applyWorkerResults(r.results));let i=this.useDirtySync?this.dirtyElements:null,s=!i||i.size===0,n=this.transformWorker;if(n?.isReady()&&!n.isPending()){let l=[];if(this.workerObjectMap.clear(),this.scene.rootObjects.forEach(o=>{this.collectWorkerInputs(o,{scale:1},s,i,l)}),l.length>0){let o=this.domVersion;this.lastSubmittedVersion=o,n.submit(l,this.buildWorkerCameraData(),o)}}this.scene.rootObjects.forEach(l=>{this.syncRecursive(l.el,l,{scale:1},s,i)});let a=this.collectFilterTargets(performance.now(),s,i);this.renderer.render(this.scene,this.camera,a),this.useDirtySync&&this.dirtyElements.clear()}syncRecursive(e,r,i,s,n){if(!this.synchronizer||!e)return;let a=s||!n||n.has(e),l=i;if(a){let c=this.synchronizer.syncElement(e,r,i);c&&typeof c.scale=="number"&&(this.lastSyncData.set(r,c),l=c)}else{let c=this.lastSyncData.get(r);c&&(l=c)}let o=s||a;r.children.forEach(c=>this.syncRecursive(c.el,c,l,o,n))}injectCSS(){if(document.getElementById("string-3d-styles"))return;let e=document.createElement("style");e.id="string-3d-styles",e.textContent=`
|
|
135
248
|
@property --translate-x { syntax: "<number>"; inherits: false; initial-value: 0; }
|
|
136
249
|
@property --translate-y { syntax: "<number>"; inherits: false; initial-value: 0; }
|
|
137
250
|
@property --translate-z { syntax: "<number>"; inherits: false; initial-value: 0; }
|
|
@@ -143,11 +256,12 @@ self.onmessage = async (event) => {
|
|
|
143
256
|
@property --scale-y { syntax: "<number>"; inherits: false; initial-value: 1; }
|
|
144
257
|
@property --scale-z { syntax: "<number>"; inherits: false; initial-value: 1; }
|
|
145
258
|
@property --opacity { syntax: "<number>"; inherits: false; initial-value: 1; }
|
|
259
|
+
@property --filter { syntax: "*"; inherits: false; initial-value: none; }
|
|
146
260
|
|
|
147
261
|
[string-3d] {
|
|
148
262
|
--translate-x: 0; --translate-y: 0; --translate-z: 0;
|
|
149
263
|
--rotate-x: 0; --rotate-y: 0; --rotate-z: 0;
|
|
150
|
-
--scale: 1; --scale-x: 1; --scale-y: 1; --scale-z: 1;--opacity: 1;
|
|
264
|
+
--scale: 1; --scale-x: 1; --scale-y: 1; --scale-z: 1;--opacity: 1; --filter: none;
|
|
151
265
|
transform-style: preserve-3d;
|
|
152
266
|
}
|
|
153
267
|
|
|
@@ -159,5 +273,5 @@ self.onmessage = async (event) => {
|
|
|
159
273
|
rotateZ(calc(var(--rotate-z) * 1deg))
|
|
160
274
|
scale3d(calc(var(--scale) * var(--scale-x)), calc(var(--scale) * var(--scale-y)), calc(var(--scale) * var(--scale-z)));
|
|
161
275
|
}
|
|
162
|
-
`,document.head.appendChild(t)}registerTypedProperties(){let t=globalThis.CSS;if(!t?.registerProperty)return;[{name:"--translate-x",initialValue:"0"},{name:"--translate-y",initialValue:"0"},{name:"--translate-z",initialValue:"0"},{name:"--rotate-x",initialValue:"0"},{name:"--rotate-y",initialValue:"0"},{name:"--rotate-z",initialValue:"0"},{name:"--scale",initialValue:"1"},{name:"--scale-x",initialValue:"1"},{name:"--scale-y",initialValue:"1"},{name:"--scale-z",initialValue:"1"},{name:"--opacity",initialValue:"1"}].forEach(({name:i,initialValue:s})=>{try{t.registerProperty({name:i,syntax:"<number>",inherits:!1,initialValue:s})}catch{}})}setupObservers(){typeof ResizeObserver<"u"&&(this.resizeObserver=new ResizeObserver(t=>{t.forEach(r=>{r.target instanceof HTMLElement&&this.markDirty(r.target)})})),typeof MutationObserver<"u"&&(this.mutationObserver=new MutationObserver(t=>{t.forEach(r=>{r.target instanceof HTMLElement&&this.markDirty(r.target)})}))}setupScrollListeners(){window.addEventListener("scroll",this.onScrollBound,{passive:!0}),window.addEventListener("resize",this.onScrollBound,{passive:!0}),window.visualViewport&&(window.visualViewport.addEventListener("scroll",this.onScrollBound,{passive:!0}),window.visualViewport.addEventListener("resize",this.onScrollBound,{passive:!0}))}removeScrollListeners(){window.removeEventListener("scroll",this.onScrollBound),window.removeEventListener("resize",this.onScrollBound),window.visualViewport&&(window.visualViewport.removeEventListener("scroll",this.onScrollBound),window.visualViewport.removeEventListener("resize",this.onScrollBound))}handleScroll(){this.useDirtySync&&this.markAllDirty()}observeElement(t){this.observedElements.has(t)||(this.observedElements.add(t),this.resizeObserver?.observe(t),this.mutationObserver?.observe(t,{attributes:!0,attributeFilter:["style","class","string-3d","string-3d-model-fit","string-3d-model-scale","string-3d-cast-shadow","string-3d-receive-shadow","string-3d-opacity","string-3d-target"]}))}observeSceneElements(){this.scene&&this.scene.rootObjects.forEach(t=>{this.observeRecursive(t)})}observeRecursive(t){t.el instanceof HTMLElement&&this.observeElement(t.el),t.children.forEach(r=>this.observeRecursive(r))}markDirty(t){this.dirtyElements.add(t),this.domVersion+=1}markAllDirty(){this.observedElements.forEach(t=>this.dirtyElements.add(t)),this.domVersion+=1}readNumberStyle(t,r,i){let n=t.computedStyleMap?.()?.get?.(r);if(n!==void 0){if(typeof n=="number")return n;if(typeof n=="string"){let c=Number.parseFloat(n);if(!Number.isNaN(c))return c}if(n&&typeof n=="object"){let c=n.value;if(typeof c=="number")return c;if(typeof c=="string"){let d=Number.parseFloat(c);if(!Number.isNaN(d))return d}}}let l=getComputedStyle(t).getPropertyValue(r),h=Number.parseFloat(l);return Number.isNaN(h)?i:h}buildWorkerCameraData(){return{mode:this.camera.getMode(),width:this.renderer.width,height:this.renderer.height,cameraZ:this.camera.getPositionZ(),fov:this.camera.getPerspectiveFov(),aspect:this.renderer.width/this.renderer.height}}collectWorkerInputs(t,r,i,s,n){if(!this.synchronizer||!t.el)return;let o=t.el,l=i||!s||s.has(o),h=r;if(t.type.endsWith("Light")){l&&this.synchronizer.syncElement(o,t,r);return}if(l){let d=o.getBoundingClientRect(),f=o.offsetWidth||d.width,y=o.offsetHeight||d.height,v=this.readNumberStyle(o,"--translate-z",0),g=this.readNumberStyle(o,"--scale",1),m=this.readNumberStyle(o,"--scale-z",1),M=this.readNumberStyle(o,"--rotate-x",0),u=this.readNumberStyle(o,"--rotate-y",0),w=this.readNumberStyle(o,"--rotate-z",0),p=this.readNumberStyle(o,"--opacity",NaN);t.type!=="group"&&C.applyVisualProps(o,t,p);let b,E,S,T;if(t.type==="model"){let O=t.getOriginalBoundingBox().getSize(this.engine.createVector3());b=O.x,E=O.y;let $=parseFloat(o.getAttribute("string-3d-model-scale")||"1");S=Number.isFinite($)?$:1,T=(o.getAttribute("string-3d-model-fit")||"contain").toLowerCase().trim()}let D=t.type==="group"?g:g*r.scale;this.lastSyncData.set(t,{scale:D}),h={scale:D},this.workerObjectMap.set(t.id,{object:t,el:o}),n.push({id:t.id,type:t.type,rectLeft:d.left,rectTop:d.top,rectWidth:f,rectHeight:y,translateZ:v,scale:g,scaleZ:m,rotateX:M,rotateY:u,rotateZ:w,parentScale:r.scale,modelSizeX:b,modelSizeY:E,modelScale:S,fitMode:T})}else{let d=this.lastSyncData.get(t);d&&(h=d)}let c=i||l;t.children.forEach(d=>{this.collectWorkerInputs(d,h,c,s,n)})}applyWorkerResults(t){this.engine&&t.forEach(r=>{let i=this.workerObjectMap.get(r.id);if(!i)return;let s=i.object;s.position=this.engine.createVector3(r.posX,r.posY,r.posZ),s.rotation=this.engine.createEuler(r.rotX,r.rotY,r.rotZ,"XYZ"),s.scale=this.engine.createVector3(r.scaleX,r.scaleY,r.scaleZ),s.type==="group"&&s.object.updateMatrixWorld(!0)})}destroy(){this.renderer?.destroy(),this.scene?.destroy(),this.isLoading.clear(),this.transformWorker?.destroy(),this.transformWorker=null,this.removeScrollListeners(),this.resizeObserver?.disconnect(),this.mutationObserver?.disconnect(),this.observedElements.clear(),this.dirtyElements.clear(),this.workerObjectMap.clear(),this.lastSyncData=new WeakMap,document.getElementById("string-3d-styles")?.remove(),this.canvasContainer?.id==="string-3d-canvas"&&this.canvasContainer.remove(),super.destroy()}};j.provider=null;var G=j;var B=class{constructor(e,t={}){this.THREE=e,this.loaders=t}createVector3(e=0,t=0,r=0){return new this.THREE.Vector3(e,t,r)}createVector2(e=0,t=0){return new this.THREE.Vector2(e,t)}createQuaternion(e=0,t=0,r=0,i=1){return new this.THREE.Quaternion(e,t,r,i)}createEuler(e=0,t=0,r=0,i="XYZ"){return new this.THREE.Euler(e,t,r,i)}createMatrix4(){return new this.THREE.Matrix4}createBox3(e,t){return new this.THREE.Box3(e,t)}createScene(){return new this.THREE.Scene}createRenderer(e){let t=new this.THREE.WebGLRenderer(e);return t.outputEncoding=this.THREE.sRGBEncoding,t}createPerspectiveCamera(e=45,t=1,r=.1,i=2e3){return new this.THREE.PerspectiveCamera(e,t,r,i)}createOrthographicCamera(e,t,r,i,s=.1,n=1e4){return new this.THREE.OrthographicCamera(e,t,r,i,s,n)}createGroup(){return new this.THREE.Group}createMesh(e,t){return new this.THREE.Mesh(e,t)}createBoxGeometry(e,t,r){return new this.THREE.BoxGeometry(e,t,r)}createSphereGeometry(e,t=32,r=32){return new this.THREE.SphereGeometry(e,t,r)}createPlaneGeometry(e,t){return new this.THREE.PlaneGeometry(e,t)}createCylinderGeometry(e,t,r,i=32){return new this.THREE.CylinderGeometry(e,t,r,i)}createMeshBasicMaterial(e){return new this.THREE.MeshBasicMaterial(e)}createMeshStandardMaterial(e){return new this.THREE.MeshStandardMaterial(e)}createPointLight(e,t=1,r=0,i=2){return new this.THREE.PointLight(e,t,r,i)}createSpotLight(e,t=1,r=0,i=Math.PI/3,s=0,n=1){return new this.THREE.SpotLight(e,t,r,i,s,n)}createHemisphereLight(e,t,r=1){return new this.THREE.HemisphereLight(e,t,r)}createAmbientLight(e,t=1){return new this.THREE.AmbientLight(e,t)}createDirectionalLight(e,t=1){return new this.THREE.DirectionalLight(e,t)}createTextureLoader(){return new this.THREE.TextureLoader}createModelLoader(e){let t=this.loaders[e];if(!t)throw new Error(`[ThreeJSEngine] Model loader "${e}" not registered`);return new t}degToRad(e){return this.THREE.MathUtils.degToRad(e)}radToDeg(e){return this.THREE.MathUtils.radToDeg(e)}computeBoundingBoxRecursively(e){let t=new this.THREE.Box3,r=!1;return e.traverse&&e.traverse(i=>{if(i.visible&&i.geometry){typeof i.geometry.computeBoundingBox=="function"&&i.geometry.computeBoundingBox();let s=i.geometry.boundingBox;if(s){let n=s.clone().applyMatrix4(i.matrixWorld);t.union(n),r=!0}}}),r?t:new this.THREE.Box3}},Z=class{constructor(e,t={}){this.engine=new B(e,t)}getEngine(){return this.engine}getName(){return"Three.js"}};return le(ge);})();
|
|
276
|
+
`,document.head.appendChild(e)}registerTypedProperties(){let e=globalThis.CSS;if(!e?.registerProperty)return;[{name:"--translate-x",initialValue:"0"},{name:"--translate-y",initialValue:"0"},{name:"--translate-z",initialValue:"0"},{name:"--rotate-x",initialValue:"0"},{name:"--rotate-y",initialValue:"0"},{name:"--rotate-z",initialValue:"0"},{name:"--scale",initialValue:"1"},{name:"--scale-x",initialValue:"1"},{name:"--scale-y",initialValue:"1"},{name:"--scale-z",initialValue:"1"},{name:"--opacity",initialValue:"1"},{name:"--filter",initialValue:"none"}].forEach(({name:i,initialValue:s})=>{try{e.registerProperty({name:i,syntax:i==="--filter"?"*":"<number>",inherits:!1,initialValue:s})}catch{}})}setupObservers(){typeof ResizeObserver<"u"&&(this.resizeObserver=new ResizeObserver(e=>{e.forEach(r=>{r.target instanceof HTMLElement&&this.markDirty(r.target)})})),typeof MutationObserver<"u"&&(this.mutationObserver=new MutationObserver(e=>{e.forEach(r=>{r.target instanceof HTMLElement&&this.markDirty(r.target)})}))}setupScrollListeners(){window.addEventListener("scroll",this.onScrollBound,{passive:!0}),window.addEventListener("resize",this.onScrollBound,{passive:!0}),window.visualViewport&&(window.visualViewport.addEventListener("scroll",this.onScrollBound,{passive:!0}),window.visualViewport.addEventListener("resize",this.onScrollBound,{passive:!0}))}removeScrollListeners(){window.removeEventListener("scroll",this.onScrollBound),window.removeEventListener("resize",this.onScrollBound),window.visualViewport&&(window.visualViewport.removeEventListener("scroll",this.onScrollBound),window.visualViewport.removeEventListener("resize",this.onScrollBound))}handleScroll(){this.useDirtySync&&this.markAllDirty()}observeElement(e){this.observedElements.has(e)||(this.observedElements.add(e),this.resizeObserver?.observe(e),this.mutationObserver?.observe(e,{attributes:!0,attributeFilter:["style","class","string-3d","string-3d-model-fit","string-3d-model-scale","string-3d-cast-shadow","string-3d-receive-shadow","string-3d-opacity","string-3d-target"]}))}observeSceneElements(){this.scene&&this.scene.rootObjects.forEach(e=>{this.observeRecursive(e)})}observeRecursive(e){e.el instanceof HTMLElement&&this.observeElement(e.el),e.children.forEach(r=>this.observeRecursive(r))}markDirty(e){this.dirtyElements.add(e),this.domVersion+=1}markAllDirty(){this.observedElements.forEach(e=>this.dirtyElements.add(e)),this.domVersion+=1}readNumberStyle(e,r,i){let n=e.computedStyleMap?.()?.get?.(r);if(n!==void 0){if(typeof n=="number")return n;if(typeof n=="string"){let c=Number.parseFloat(n);if(!Number.isNaN(c))return c}if(n&&typeof n=="object"){let c=n.value;if(typeof c=="number")return c;if(typeof c=="string"){let p=Number.parseFloat(c);if(!Number.isNaN(p))return p}}}let l=getComputedStyle(e).getPropertyValue(r),o=Number.parseFloat(l);return Number.isNaN(o)?i:o}readFilterRaw(e){let r=e.computedStyleMap?.(),i="",s=r?.get?.("--filter");if(s!==void 0){if(typeof s=="string")i=s;else if(s&&typeof s=="object"){let n=s.value;typeof n=="string"&&(i=n)}}return i||(i=getComputedStyle(e).getPropertyValue("--filter")||""),i=i.trim(),i}parseFilterChain(e){let r=[],i=[],s=u=>{let d=u.trim().toLowerCase().match(/^(-?\d*\.?\d+)(px)?$/);if(!d)return null;let f=Number.parseFloat(d[1]);return Number.isFinite(f)?f:null},n=u=>{let g=u.trim().toLowerCase();if(!g)return null;if(g.endsWith("%")){let f=Number.parseFloat(g.slice(0,-1));return Number.isFinite(f)?f/100:null}let d=Number.parseFloat(g);return Number.isFinite(d)?d:null},a=u=>{let g=u.trim().toLowerCase();if(!g)return null;if(g.endsWith("rad")){let v=Number.parseFloat(g.slice(0,-3));return Number.isFinite(v)?v:null}let d=g.endsWith("deg")?g.slice(0,-3):g,f=Number.parseFloat(d);return Number.isFinite(f)?f*Math.PI/180:null},l=u=>{let g=u.split(",").map(v=>v.trim()),d=s(g[0]||"");if(d===null)return null;let f=g[1]?n(g[1]):null;return{intensity:Math.max(0,d),threshold:f===null?.8:Math.max(0,Math.min(1,f))}},o=(u,g,d=!1)=>{let f=s(u);return f===null?(r.push(`[String3D] Invalid ${g} value "${u}".`),null):!d&&f<=0?(r.push(`[String3D] ${g} must be > 0.`),null):f},c=(u,g)=>{let d=n(u);return d===null?(r.push(`[String3D] Invalid ${g} value "${u}".`),null):d},p=/([a-zA-Z-]+)\(([^)]*)\)/g,m;for(;m=p.exec(e);){let u=m[1].toLowerCase(),g=(m[2]||"").trim();if(u==="blur"){let d=o(g,"blur",!0);d!==null&&i.push({type:"blur",amount:d})}else if(u==="pixel"||u==="pixelate"){let d=o(g,"pixel",!0);d!==null&&i.push({type:"pixel",size:d})}else if(u==="bloom"){let d=l(g);d?i.push({type:"bloom",...d}):r.push(`[String3D] Invalid bloom value "${g}".`)}else if(u==="brightness"){let d=c(g,"brightness");d!==null&&i.push({type:"brightness",amount:Math.max(0,d)})}else if(u==="contrast"){let d=c(g,"contrast");d!==null&&i.push({type:"contrast",amount:Math.max(0,d)})}else if(u==="saturate"){let d=c(g,"saturate");d!==null&&i.push({type:"saturate",amount:Math.max(0,d)})}else if(u==="grayscale"){let d=c(g,"grayscale");d!==null&&i.push({type:"grayscale",amount:Math.max(0,Math.min(1,d))})}else if(u==="sepia"){let d=c(g,"sepia");d!==null&&i.push({type:"sepia",amount:Math.max(0,Math.min(1,d))})}else if(u==="invert"){let d=c(g,"invert");d!==null&&i.push({type:"invert",amount:Math.max(0,Math.min(1,d))})}else if(u==="hue-rotate"){let d=a(g);d!==null?i.push({type:"hue-rotate",angle:d}):r.push(`[String3D] Invalid hue-rotate value "${g}".`)}else if(u){let d=R.get(u);if(d){let f=d.parse?d.parse(g):{};f===null?r.push(`[String3D] Invalid custom filter "${u}" args "${g}".`):i.push({type:"custom",name:u,uniforms:f})}else r.push(`[String3D] Unknown filter "${u}".`)}}return i.length===0&&r.push("[String3D] No valid filters parsed from --filter."),{effects:i,warnings:r}}warnFilterIssues(e,r,i){i.length===0||this.filterWarnings.get(e)===r||(i.forEach(n=>console.warn(n,e)),this.filterWarnings.set(e,r))}readFilterChain(e,r,i){let s=this.filterStates.get(e);if(!i&&s)return s.animating?this.sampleTransition(s,r):s.effects;let n=this.readFilterRaw(e);if(!n||n==="none"){if(s){if(s.animating&&s.clearOnComplete){let f=this.sampleTransition(s,r);return s.animating?f:(this.filterStates.delete(e),null)}let{duration:u,delay:g,easing:d}=this.getFilterTransition(e);if(u<=0&&s.lastDuration>0&&(u=s.lastDuration,g=s.lastDelay,d=s.lastEasing),u>0){let f=this.makeZeroChain(s.effects);return s.from=s.effects,s.to=f,s.startTime=r+g,s.duration=u,s.easing=d,s.animating=!0,s.clearOnComplete=!0,s.lastDuration=u,s.lastDelay=g,s.lastEasing=d,this.sampleTransition(s,r)}}return this.filterStates.delete(e),null}let{effects:a,warnings:l}=this.parseFilterChain(n);if(this.warnFilterIssues(e,n,l),a.length===0)return null;let o=this.filterStates.get(e);if(!o){let{duration:u,delay:g,easing:d}=this.getFilterTransition(e);if(u>0){let f=this.makeZeroChain(a),v={raw:n,effects:a,animating:!0,from:f,to:a,startTime:r+g,duration:u,easing:d,clearOnComplete:!1,lastDuration:u,lastDelay:g,lastEasing:d};return v.effectsKey=this.stringifyFilterChain(a),this.filterStates.set(e,v),this.sampleTransition(v,r)}return this.filterStates.set(e,{raw:n,effects:a,animating:!1,from:a,to:a,startTime:0,duration:0,easing:f=>f,clearOnComplete:!1,lastDuration:0,lastDelay:0,lastEasing:f=>f,effectsKey:this.stringifyFilterChain(a)}),a}if(o.raw===n){if(o.animating){let u=this.sampleTransition(o,r);return!o.animating&&o.clearOnComplete?(this.filterStates.delete(e),null):u}return o.effects}o.pendingEffects=void 0,o.pendingRaw=void 0;let{duration:c,delay:p,easing:m}=this.getFilterTransition(e);if(c<=0&&o.lastDuration>0&&(c=o.lastDuration,p=o.lastDelay,m=o.lastEasing),c>0){let u=this.canInterpolate(o.effects,a),g=o.animating?this.getCurrentChain(o,r):o.effects;if(!u&&this.isZeroChain(a))return o.pendingRaw=n,o.pendingEffects=a,o.raw=n,o.effects=g,o.from=g,o.to=this.makeZeroChain(g),o.startTime=r+p,o.duration=c,o.easing=m,o.animating=!0,o.clearOnComplete=!1,o.lastDuration=c,o.lastDelay=p,o.lastEasing=m,o.effectsKey=this.stringifyFilterChain(a),this.sampleTransition(o,r);let d=u?g:this.makeZeroChain(a);return o.raw=n,o.effects=a,o.from=d,o.to=a,o.startTime=r+p,o.duration=c,o.easing=m,o.animating=!0,o.clearOnComplete=!1,o.lastDuration=c,o.lastDelay=p,o.lastEasing=m,o.effectsKey=this.stringifyFilterChain(a),this.sampleTransition(o,r)}return o.raw=n,o.effects=a,o.animating=!1,o.clearOnComplete=!1,o.effectsKey=this.stringifyFilterChain(a),a}collectFilterTargets(e,r,i){if(!this.scene)return[];let s=[],n=a=>{let l=a.el;if(l){let o=!this.useDirtySync||!i||i.has(l)||this.filterStates.get(l)?.animating===!0,c=this.readFilterChain(l,e,o);if(c&&c.length>0){let p=!this.useDirtySync||!i||i.has(l)||this.filterStates.get(l)?.animating===!0,m=this.filterStates.get(l)?.effectsKey||this.stringifyFilterChain(c);s.push({object:a,effects:c,effectsKey:m,dirty:p});return}}a.children.forEach(o=>n(o))};return this.scene.rootObjects.forEach(a=>n(a)),s}stringifyFilterChain(e){return e.map(i=>{if(i.type==="blur")return`blur:${i.amount}`;if(i.type==="pixel")return`pixel:${i.size}`;if(i.type==="bloom")return`bloom:${i.intensity},${i.threshold}`;if(i.type==="brightness")return`brightness:${i.amount}`;if(i.type==="contrast")return`contrast:${i.amount}`;if(i.type==="saturate")return`saturate:${i.amount}`;if(i.type==="grayscale")return`grayscale:${i.amount}`;if(i.type==="sepia")return`sepia:${i.amount}`;if(i.type==="invert")return`invert:${i.amount}`;if(i.type==="hue-rotate")return`hue-rotate:${i.angle}`;if(i.type==="custom"){let s=Object.keys(i.uniforms||{}).sort().map(n=>`${n}=${i.uniforms[n]}`).join(",");return`custom:${i.name}:${s}`}return"unknown"}).join("|")}getFilterTransition(e){let r=getComputedStyle(e),i=this.splitTransitionList(r.transitionProperty),s=this.splitTransitionList(r.transitionDuration),n=this.splitTransitionList(r.transitionDelay),a=this.splitTransitionList(r.transitionTimingFunction),l=this.findTransitionIndex(i,"--filter");if(l===-1){let m=this.parseTransitionShorthand(r.transition),u=m.get("--filter")||m.get("all");return u||{duration:0,delay:0,easing:g=>g}}let o=this.parseTime(s[l]||s[s.length-1]||"0s"),c=this.parseTime(n[l]||n[n.length-1]||"0s"),p=a[l]||a[a.length-1]||"linear";return{duration:o,delay:c,easing:this.parseEasing(p)}}splitTransitionList(e){let r=[],i="",s=0;for(let n=0;n<e.length;n+=1){let a=e[n];a==="("&&(s+=1),a===")"&&(s=Math.max(0,s-1)),a===","&&s===0?(r.push(i.trim()),i=""):i+=a}return i.trim()&&r.push(i.trim()),r.length>0?r:["all"]}findTransitionIndex(e,r){let i=e.map(n=>n.trim().toLowerCase()),s=i.indexOf(r);return s===-1&&(s=i.indexOf("all")),s}parseTime(e){let r=e.trim().toLowerCase();if(r.endsWith("ms")){let s=Number.parseFloat(r.slice(0,-2));return Number.isFinite(s)?s:0}if(r.endsWith("s")){let s=Number.parseFloat(r.slice(0,-1));return Number.isFinite(s)?s*1e3:0}let i=Number.parseFloat(r);return Number.isFinite(i)?i:0}parseTransitionShorthand(e){let r=new Map;return this.splitTransitionList(e).forEach(s=>{if(!s)return;let n=s.trim().split(/\s+(?![^()]*\))/g),a="",l="",o="",c="";n.forEach(p=>{let m=p.toLowerCase();m.endsWith("ms")||m.endsWith("s")||/^[0-9.]+$/.test(m)?l?o||(o=m):l=m:m.startsWith("cubic-bezier")||m.startsWith("steps")||m==="linear"||m==="ease"||m==="ease-in"||m==="ease-out"||m==="ease-in-out"?c=p:a||(a=p)}),a&&r.set(a.trim().toLowerCase(),{duration:this.parseTime(l||"0s"),delay:this.parseTime(o||"0s"),easing:this.parseEasing(c||"linear")})}),r}parseEasing(e){let r=e.trim().toLowerCase();if(r==="linear")return i=>i;if(r==="ease")return this.cubicBezier(.25,.1,.25,1);if(r==="ease-in")return this.cubicBezier(.42,0,1,1);if(r==="ease-out")return this.cubicBezier(0,0,.58,1);if(r==="ease-in-out")return this.cubicBezier(.42,0,.58,1);if(r.startsWith("cubic-bezier")){let i=r.match(/cubic-bezier\(([^)]+)\)/);if(i){let s=i[1].split(",").map(n=>Number.parseFloat(n.trim()));if(s.length===4&&s.every(n=>Number.isFinite(n)))return this.cubicBezier(s[0],s[1],s[2],s[3])}}return i=>i}cubicBezier(e,r,i,s){let n=o=>{let c=1-o;return 3*c*c*o*e+3*c*o*o*i+o*o*o},a=o=>{let c=1-o;return 3*c*c*o*r+3*c*o*o*s+o*o*o},l=o=>{let c=o;for(let p=0;p<5;p+=1){let m=n(c)-o,u=3*(1-c)*(1-c)*e+6*(1-c)*c*(i-e)+3*c*c*(1-i);if(Math.abs(m)<1e-5||u===0)break;c-=m/u}return c};return o=>{let c=Math.min(1,Math.max(0,o)),p=l(c);return Math.min(1,Math.max(0,a(p)))}}canInterpolate(e,r){return e.length!==r.length?!1:e.every((i,s)=>{let n=r[s];if(i.type!==n.type)return!1;if(i.type==="custom"&&n.type==="custom"){if(i.name!==n.name)return!1;let a=Object.keys(i.uniforms||{}),l=Object.keys(n.uniforms||{});return a.length!==l.length?!1:a.every(o=>o in n.uniforms&&this.isNumeric(i.uniforms[o]))}return!0})}makeZeroChain(e){return e.map(r=>{switch(r.type){case"blur":return{type:"blur",amount:0};case"pixel":return{type:"pixel",size:0};case"bloom":return{type:"bloom",intensity:0,threshold:r.threshold};case"brightness":return{type:"brightness",amount:1};case"contrast":return{type:"contrast",amount:1};case"saturate":return{type:"saturate",amount:1};case"grayscale":return{type:"grayscale",amount:0};case"sepia":return{type:"sepia",amount:0};case"invert":return{type:"invert",amount:0};case"hue-rotate":return{type:"hue-rotate",angle:0};case"custom":{let i={};return Object.entries(r.uniforms||{}).forEach(([s,n])=>{i[s]=this.isNumeric(n)?0:n}),{type:"custom",name:r.name,uniforms:i}}default:return r}})}sampleTransition(e,r){if(!e.animating)return e.effects;if(r<e.startTime)return e.from;let i=r-e.startTime,s=Math.max(1,e.duration),n=Math.min(1,Math.max(0,i/s)),a=e.easing(n),l=this.interpolateChain(e.from,e.to,a);return n>=1&&(e.animating=!1,e.from=e.to,e.pendingEffects&&e.pendingRaw===e.raw?(e.effects=e.pendingEffects,e.raw=e.pendingRaw||e.raw,e.pendingEffects=void 0,e.pendingRaw=void 0):e.pendingEffects&&(e.pendingEffects=void 0,e.pendingRaw=void 0)),l}getCurrentChain(e,r){if(!e.animating)return e.effects;if(r<e.startTime)return e.from;let i=r-e.startTime,s=Math.max(1,e.duration),n=Math.min(1,Math.max(0,i/s)),a=e.easing(n);return this.interpolateChain(e.from,e.to,a)}interpolateChain(e,r,i){return this.canInterpolate(e,r)?e.map((s,n)=>this.interpolateEffect(s,r[n],i)):r}interpolateEffect(e,r,i){let s=(n,a)=>n+(a-n)*i;if(e.type==="blur"&&r.type==="blur")return{type:"blur",amount:s(e.amount,r.amount)};if(e.type==="pixel"&&r.type==="pixel")return{type:"pixel",size:s(e.size,r.size)};if(e.type==="bloom"&&r.type==="bloom")return{type:"bloom",intensity:s(e.intensity,r.intensity),threshold:s(e.threshold,r.threshold)};if(e.type==="brightness"&&r.type==="brightness")return{type:"brightness",amount:s(e.amount,r.amount)};if(e.type==="contrast"&&r.type==="contrast")return{type:"contrast",amount:s(e.amount,r.amount)};if(e.type==="saturate"&&r.type==="saturate")return{type:"saturate",amount:s(e.amount,r.amount)};if(e.type==="grayscale"&&r.type==="grayscale")return{type:"grayscale",amount:s(e.amount,r.amount)};if(e.type==="sepia"&&r.type==="sepia")return{type:"sepia",amount:s(e.amount,r.amount)};if(e.type==="invert"&&r.type==="invert")return{type:"invert",amount:s(e.amount,r.amount)};if(e.type==="hue-rotate"&&r.type==="hue-rotate")return{type:"hue-rotate",angle:s(e.angle,r.angle)};if(e.type==="custom"&&r.type==="custom"&&e.name===r.name){let n={};return Object.entries(r.uniforms||{}).forEach(([a,l])=>{let o=e.uniforms?.[a];this.isNumeric(o)&&this.isNumeric(l)?n[a]=s(o,l):n[a]=l}),{type:"custom",name:r.name,uniforms:n}}return r}isNumeric(e){return typeof e=="number"&&Number.isFinite(e)}isZeroChain(e){return e.every(r=>{switch(r.type){case"blur":return r.amount<=0;case"pixel":return r.size<=0;case"bloom":return r.intensity<=0;case"brightness":return r.amount===1;case"contrast":return r.amount===1;case"saturate":return r.amount===1;case"grayscale":return r.amount===0;case"sepia":return r.amount===0;case"invert":return r.amount===0;case"hue-rotate":return r.angle===0;case"custom":return!1;default:return!1}})}buildWorkerCameraData(){return{mode:this.camera.getMode(),width:this.renderer.width,height:this.renderer.height,cameraZ:this.camera.getPositionZ(),fov:this.camera.getPerspectiveFov(),aspect:this.renderer.width/this.renderer.height}}collectWorkerInputs(e,r,i,s,n){if(!this.synchronizer||!e.el)return;let a=e.el,l=i||!s||s.has(a),o=r;if(e.type.endsWith("Light")){l&&this.synchronizer.syncElement(a,e,r);return}if(l){let p=a.getBoundingClientRect(),m=a.offsetWidth||p.width,u=a.offsetHeight||p.height,g=this.readNumberStyle(a,"--translate-z",0),d=this.readNumberStyle(a,"--scale",1),f=this.readNumberStyle(a,"--scale-z",1),v=this.readNumberStyle(a,"--rotate-x",0),b=this.readNumberStyle(a,"--rotate-y",0),M=this.readNumberStyle(a,"--rotate-z",0),y=this.readNumberStyle(a,"--opacity",NaN);e.type!=="group"&&k.applyVisualProps(a,e,y);let w,x,S,C;if(e.type==="model"){let I=e.getOriginalBoundingBox().getSize(this.engine.createVector3());w=I.x,x=I.y;let U=parseFloat(a.getAttribute("string-3d-model-scale")||"1");S=Number.isFinite(U)?U:1,C=(a.getAttribute("string-3d-model-fit")||"contain").toLowerCase().trim()}let P=e.type==="group"?d:d*r.scale;this.lastSyncData.set(e,{scale:P}),o={scale:P},this.workerObjectMap.set(e.id,{object:e,el:a}),n.push({id:e.id,type:e.type,rectLeft:p.left,rectTop:p.top,rectWidth:m,rectHeight:u,translateZ:g,scale:d,scaleZ:f,rotateX:v,rotateY:b,rotateZ:M,parentScale:r.scale,modelSizeX:w,modelSizeY:x,modelScale:S,fitMode:C})}else{let p=this.lastSyncData.get(e);p&&(o=p)}let c=i||l;e.children.forEach(p=>{this.collectWorkerInputs(p,o,c,s,n)})}applyWorkerResults(e){this.engine&&e.forEach(r=>{let i=this.workerObjectMap.get(r.id);if(!i)return;let s=i.object;s.position=this.engine.createVector3(r.posX,r.posY,r.posZ),s.rotation=this.engine.createEuler(r.rotX,r.rotY,r.rotZ,"XYZ"),s.scale=this.engine.createVector3(r.scaleX,r.scaleY,r.scaleZ),s.type==="group"&&s.object.updateMatrixWorld(!0)})}destroy(){this.renderer?.destroy(),this.scene?.destroy(),this.isLoading.clear(),this.transformWorker?.destroy(),this.transformWorker=null,this.removeScrollListeners(),this.resizeObserver?.disconnect(),this.mutationObserver?.disconnect(),this.observedElements.clear(),this.dirtyElements.clear(),this.workerObjectMap.clear(),this.lastSyncData=new WeakMap,document.getElementById("string-3d-styles")?.remove(),this.canvasContainer?.id==="string-3d-canvas"&&this.canvasContainer.remove(),super.destroy()}};j.provider=null;var G=j;var $=class{constructor(t,e={}){this.THREE=t,this.loaders=e}createVector3(t=0,e=0,r=0){return new this.THREE.Vector3(t,e,r)}createVector2(t=0,e=0){return new this.THREE.Vector2(t,e)}createQuaternion(t=0,e=0,r=0,i=1){return new this.THREE.Quaternion(t,e,r,i)}createEuler(t=0,e=0,r=0,i="XYZ"){return new this.THREE.Euler(t,e,r,i)}createMatrix4(){return new this.THREE.Matrix4}createBox3(t,e){return new this.THREE.Box3(t,e)}createScene(){return new this.THREE.Scene}createRenderer(t){let e=new this.THREE.WebGLRenderer(t);return e.outputEncoding=this.THREE.sRGBEncoding,e}createPerspectiveCamera(t=45,e=1,r=.1,i=2e3){return new this.THREE.PerspectiveCamera(t,e,r,i)}createOrthographicCamera(t,e,r,i,s=.1,n=1e4){return new this.THREE.OrthographicCamera(t,e,r,i,s,n)}createGroup(){return new this.THREE.Group}createMesh(t,e){return new this.THREE.Mesh(t,e)}createBoxGeometry(t,e,r){return new this.THREE.BoxGeometry(t,e,r)}createSphereGeometry(t,e=32,r=32){return new this.THREE.SphereGeometry(t,e,r)}createPlaneGeometry(t,e){return new this.THREE.PlaneGeometry(t,e)}createCylinderGeometry(t,e,r,i=32){return new this.THREE.CylinderGeometry(t,e,r,i)}createMeshBasicMaterial(t){return new this.THREE.MeshBasicMaterial(t)}createMeshStandardMaterial(t){return new this.THREE.MeshStandardMaterial(t)}createShaderMaterial(t){return new this.THREE.ShaderMaterial(t)}createPointLight(t,e=1,r=0,i=2){return new this.THREE.PointLight(t,e,r,i)}createSpotLight(t,e=1,r=0,i=Math.PI/3,s=0,n=1){return new this.THREE.SpotLight(t,e,r,i,s,n)}createHemisphereLight(t,e,r=1){return new this.THREE.HemisphereLight(t,e,r)}createAmbientLight(t,e=1){return new this.THREE.AmbientLight(t,e)}createDirectionalLight(t,e=1){return new this.THREE.DirectionalLight(t,e)}createTextureLoader(){return new this.THREE.TextureLoader}createModelLoader(t){let e=this.loaders[t];if(!e)throw new Error(`[ThreeJSEngine] Model loader "${t}" not registered`);return new e}createRenderTarget(t,e,r={}){let i={minFilter:this.THREE.LinearFilter,magFilter:this.THREE.LinearFilter,format:this.THREE.RGBAFormat,depthBuffer:!0,stencilBuffer:!1};return new this.THREE.WebGLRenderTarget(t,e,{...i,...r})}degToRad(t){return this.THREE.MathUtils.degToRad(t)}radToDeg(t){return this.THREE.MathUtils.radToDeg(t)}computeBoundingBoxRecursively(t){let e=new this.THREE.Box3,r=!1;return t.traverse&&t.traverse(i=>{if(i.visible&&i.geometry){typeof i.geometry.computeBoundingBox=="function"&&i.geometry.computeBoundingBox();let s=i.geometry.boundingBox;if(s){let n=s.clone().applyMatrix4(i.matrixWorld);e.union(n),r=!0}}}),r?e:new this.THREE.Box3}},Q=class{constructor(t,e={}){this.engine=new $(t,e)}getEngine(){return this.engine}getName(){return"Three.js"}};return ue(be);})();
|
|
163
277
|
//# sourceMappingURL=index.js.map
|