hz-particles 1.0.15 → 1.3.0
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/README.md +277 -209
- package/dist-lib/hz-particles-r3f.cjs +3 -3
- package/dist-lib/hz-particles-r3f.d.ts +24 -17
- package/dist-lib/hz-particles-r3f.mjs +207 -432
- package/dist-lib/hz-particles.cjs +120 -22
- package/dist-lib/hz-particles.d.ts +145 -6
- package/dist-lib/hz-particles.mjs +4040 -3019
- package/package.json +5 -4
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const je=require("react/jsx-runtime"),a=require("react"),Ze=require("@react-three/fiber"),Ut=require("three"),Je=require("hz-particles");function Ot(i){const n=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(i){for(const I in i)if(I!=="default"){const e=Object.getOwnPropertyDescriptor(i,I);Object.defineProperty(n,I,e.get?e:{enumerable:!0,get:()=>i[I]})}}return n.default=i,Object.freeze(n)}const l=Ot(Ut);function $e(i){return Math.abs(Math.sin(i*12.9898)*43758.5453)%1}function Bt(i){const n=Math.sin(i*54321.67)*43758.5453%1;return n<0?n+1:n}function wt(i,n,I,e){if(I<=0)return 0;const y=n/I;let N=i.particleSize??.5;if(i.randomSize){const G=i.minSize??.1,Y=i.maxSize??.5;N=G+(Y-G)*Bt(I)}const $=Math.max(.01,Math.min(10,i.sizeLifetimeSpeed??1));if(i.fadeSizeEnabled&&(N*=1-Math.pow(y,1/$)),i.increaseSizeEnabled&&(N*=1+Math.pow(y,1/$)),i.pulseEnabled){const G=i.pulseAmplitude??.5,Y=i.pulseFrequency??1,ae=(i.pulsePhaseRandom??0)*$e(e)*Math.PI*2;N*=1+G*Math.sin(n*Y*Math.PI*2+ae)}return Math.max(0,N)}function Rt(i,n,I,e){if(I<=0)return 0;let y=i.opacity??1;const N=n/I;if(i.fadeEnabled&&(y*=Math.max(0,1-N)),i.pulseEnabled&&i.pulseOpacity){const $=i.pulseAmplitude??.5,G=i.pulseFrequency??1,ne=(i.pulsePhaseRandom??0)*$e(e)*Math.PI*2;y*=Math.max(0,1+$*Math.sin(n*G*Math.PI*2+ne))}return Math.max(0,Math.min(1,y))}function Tt(i,n){if(n===1)return i;const I=(e,y)=>e!=null?e*n:y*n;return{...i,systems:i.systems.map(e=>({...e,particleSize:I(e.particleSize,.5),minSize:e.minSize!=null?e.minSize*n:void 0,maxSize:e.maxSize!=null?e.maxSize*n:void 0,particleSpeed:(e.particleSpeed??1)*n,minSpeed:e.minSpeed!=null?e.minSpeed*n:void 0,maxSpeed:e.maxSpeed!=null?e.maxSpeed*n:void 0,cubeLength:e.cubeLength!=null?e.cubeLength*n:void 0,outerLength:e.outerLength!=null?e.outerLength*n:void 0,innerLength:e.innerLength!=null?e.innerLength*n:void 0,outerRadius:e.outerRadius!=null?e.outerRadius*n:void 0,innerRadius:e.innerRadius!=null?e.innerRadius*n:void 0,squareSize:e.squareSize!=null?e.squareSize*n:void 0,squareInnerSize:e.squareInnerSize!=null?e.squareInnerSize*n:void 0,circleInnerRadius:e.circleInnerRadius!=null?e.circleInnerRadius*n:void 0,circleOuterRadius:e.circleOuterRadius!=null?e.circleOuterRadius*n:void 0,cylinderInnerRadius:e.cylinderInnerRadius!=null?e.cylinderInnerRadius*n:void 0,cylinderOuterRadius:e.cylinderOuterRadius!=null?e.cylinderOuterRadius*n:void 0,cylinderHeight:e.cylinderHeight!=null?e.cylinderHeight*n:void 0,emissionTrailWidth:(e.emissionTrailWidth??.3)*n,emissionTrailDuration:(e.emissionTrailDuration??1)*n,emissionTrailMinDistance:e.emissionTrailMinDistance!=null?e.emissionTrailMinDistance*n:void 0,emissionTrailShapeAmplitude:e.emissionTrailShapeAmplitude!=null?e.emissionTrailShapeAmplitude*n:void 0}))}}function Ht(i){let n=0;for(const I of i.systems)n+=I.maxParticles??1e4;return n}function Lt({preset:i,position:n,positionRef:I,autoPlay:e=!0,visible:y=!0,scale:N=1,resetKey:$=0,onComplete:G}){var Be;const[Y,ne]=a.useState(typeof i=="string"?null:i);a.useEffect(()=>{typeof i=="string"?(ne(null),Je.fetchPreset(i).then(ne).catch(d=>{console.error("[HZParticlesFX] Failed to fetch preset:",d)})):ne(i)},[i]);const{camera:ae,gl:ke}=Ze.useThree(),de=a.useRef(null);if(!de.current){const d=(Be=ke.backend)==null?void 0:Be.device;d&&(de.current=d)}const Ie=de.current,De=a.useRef(null),he=a.useRef(null),Ce=a.useRef(!1),B=a.useRef(!1),h=a.useMemo(()=>Y?Tt(Y,N):null,[Y,N]),Ue=a.useMemo(()=>(h==null?void 0:h.systems.every(d=>d.emissionTrailEnabled))??!1,[h]),Ne=a.useMemo(()=>h?h.systems.every(d=>d.emissionTrailEnabled)?1:Ht(h):0,[h]),_e=a.useMemo(()=>n?n instanceof l.Vector3?n.clone():new l.Vector3(...n):new l.Vector3(0,0,0),[n]),ge=a.useMemo(()=>(h==null?void 0:h.systems.some(d=>d.emissionTrailEnabled))??!1,[h]),Oe=a.useMemo(()=>new l.PlaneGeometry(1,1),[]),r=a.useMemo(()=>{const d=document.createElement("canvas");d.width=64,d.height=64;const A=d.getContext("2d");A.clearRect(0,0,64,64);const w=A.createRadialGradient(32,32,0,32,32,32);w.addColorStop(0,"rgba(255,255,255,1)"),w.addColorStop(.7,"rgba(255,255,255,1)"),w.addColorStop(1,"rgba(255,255,255,0)"),A.fillStyle=w,A.beginPath(),A.arc(32,32,32,0,Math.PI*2),A.fill();const R=new l.CanvasTexture(d);R.flipY=!1;const _=new l.MeshBasicMaterial({color:16777215,transparent:!0,depthWrite:!1,alphaTest:.01,map:R,vertexColors:!0,side:l.DoubleSide,blending:l.NormalBlending});return _.needsUpdate=!0,_},[]),C=a.useRef(null);a.useEffect(()=>{if(!h)return;const d=h.systems.find(w=>!w.emissionTrailEnabled&&w.textureEnabled&&w.textureImageData);if(!d){C.current&&r.map!==C.current&&(r.map=C.current,r.needsUpdate=!0);return}C.current||(C.current=r.map);const A=new Image;return A.onload=()=>{const w=new l.Texture(A);w.needsUpdate=!0,r.map=w,r.needsUpdate=!0},A.src=d.textureImageData,()=>{r.map&&r.map!==C.current&&r.map.dispose()}},[h,r]);const ye=64,X=a.useRef(null),Z=a.useRef(0),M=512,re=a.useRef({buf:new Float32Array(M*6),head:0,count:0,elapsed:0}),{trailGeo:se,trailPosAttr:z,trailColAttr:H}=a.useMemo(()=>{const A=8*ye*6,w=new Float32Array(A*3),R=new Float32Array(A*3),_=new l.BufferGeometry,pe=new l.BufferAttribute(w,3);pe.setUsage(l.DynamicDrawUsage),_.setAttribute("position",pe);const xe=new l.BufferAttribute(R,3);return xe.setUsage(l.DynamicDrawUsage),_.setAttribute("color",xe),_.setDrawRange(0,0),{trailGeo:_,trailPosAttr:pe,trailColAttr:xe}},[]),Ee=a.useMemo(()=>new l.MeshBasicMaterial({color:16777215,vertexColors:!0,transparent:!0,depthWrite:!1,side:l.DoubleSide,blending:l.NormalBlending}),[]);a.useEffect(()=>{if(!Ie||!h)return;const d=new Je.ParticleSystemManager(Ie);return he.current=d,B.current=!1,d.replaceSystems(h).then(()=>{e&&y&&(d.respawnAllSystems(),B.current=!0)}).catch(A=>{console.error("[HZParticlesFX] replaceSystems FAILED:",A)}),()=>{typeof d.destroy=="function"&&d.destroy(),he.current=null}},[Ie,h]),a.useEffect(()=>{const d=he.current;d&&e&&y&&!B.current&&(d.respawnAllSystems(),B.current=!0,Ce.current=!1)},[e,y]);const fe=a.useRef(null),Me=a.useRef($);a.useEffect(()=>{if($===Me.current)return;Me.current=$;const d=re.current;d.head=0,d.count=0,d.elapsed=0,se.setDrawRange(0,0),fe.current=null;const A=he.current;A&&(A.respawnAllSystems(),B.current=!0,Ce.current=!1)},[$]);const Ye=a.useMemo(()=>new l.Matrix4,[]),me=a.useMemo(()=>new l.Vector3,[]),K=a.useMemo(()=>new l.Vector3,[]),ie=a.useMemo(()=>new l.Quaternion,[]),Se=a.useMemo(()=>new l.Vector3,[]),V=a.useMemo(()=>new l.Vector3(0,0,1),[]),Ve=a.useMemo(()=>new l.Color,[]);return Ze.useFrame((d,A)=>{var et;if(!y||!De.current||!he.current)return;const w=he.current,R=(I==null?void 0:I.current)??_e,_=A>1?A/1e3:A,pe=fe.current,xe=pe&&_>0,At=xe?(R.x-pe.x)/_:0,Pt=xe?(R.y-pe.y)/_:0,It=xe?(R.z-pe.z)/_:0;fe.current={x:R.x,y:R.y,z:R.z};for(const{system:s,config:u}of w.particleSystems)u.emissionTrailEnabled?(s.setSimulationTransform({position:[R.x,R.y,R.z],velocity:[At,Pt,It]}),u.emissionTranslationX=0,u.emissionTranslationY=0,u.emissionTranslationZ=0):(u.emissionTranslationX=R.x,u.emissionTranslationY=R.y,u.emissionTranslationZ=R.z);w.updateAllSystems(_);for(const{system:s}of w.particleSystems)s.readbackAndProcessParticles();if(ge){const s=re.current;s.elapsed+=_;let u=0,E=0;const U=(et=w.particleSystems.find(({config:L})=>L.emissionTrailEnabled))==null?void 0:et.config;if(U){const L=U.emissionTrailShape??"straight";if(L!=="straight"){const O=U.emissionTrailShapeAmplitude??.1,ce=U.emissionTrailShapeFrequency??4,te=2*Math.PI*ce*s.elapsed;L==="zigzag"?u=O*Math.sign(Math.sin(te)):L==="sine"?u=O*Math.sin(te):L==="spiral"&&(u=O*Math.sin(te),E=O*Math.cos(te))}}const ee=s.head*6;s.buf[ee]=R.x,s.buf[ee+1]=R.y,s.buf[ee+2]=R.z,s.buf[ee+3]=s.elapsed,s.buf[ee+4]=u,s.buf[ee+5]=E,s.head=(s.head+1)%M,s.count<M&&s.count++}const be=De.current;let ve=0;for(let s=0;s<w.particleSystems.length;s++){const{system:u,config:E}=w.particleSystems[s];if(E.emissionTrailEnabled)continue;const U=u.particleData,ee=u.activeParticles;if(!(!U||ee<=0))for(let L=0;L<ee;L++){const O=L*8,ce=U[O+0],te=U[O+1],D=U[O+2];let ze=U[O+3],we=U[O+4],Q=U[O+5];const Re=U[O+6],oe=U[O+7];if(Re>=oe||oe<=0)continue;const x=Re/oe;if(E.colorTransitionEnabled){const F=E.startColor??[1,0,0],le=E.endColor??[0,0,1];ze=F[0]+(le[0]-F[0])*x,we=F[1]+(le[1]-F[1])*x,Q=F[2]+(le[2]-F[2])*x}const Te=E.bloomIntensity??1;ze=Math.min(1,ze*Te),we=Math.min(1,we*Te),Q=Math.min(1,Q*Te);const Ae=Rt(E,Re,oe,L);ze*=Ae,we*=Ae,Q*=Ae;const J=wt(E,Re,oe,L);if(!(J<=0)){if(me.set(ce,te,D),K.subVectors(ae.position,me).normalize(),ie.setFromUnitVectors(V,K),E.velocityStretchEnabled&&u.particleVelocities){const F=L*4,le=u.particleVelocities[F],Fe=u.particleVelocities[F+1],q=u.particleVelocities[F+2],ue=Math.sqrt(le*le+Fe*Fe+q*q);if(ue>.001){const Qe=E.velocityStretchFactor??1,W=J*(1+ue*Qe);Se.set(J,W,1),K.set(le,Fe,q).normalize(),ie.setFromUnitVectors(V,K);const o=(W-J)*.5;me.addScaledVector(K,o)}else Se.set(J,J,1)}else Se.set(J,J,1);Ye.compose(me,ie,Se),be.setMatrixAt(ve,Ye),Ve.setRGB(ze,we,Q),be.setColorAt(ve,Ve),ve++}}}be.count=ve,be.visible=ve>0,ve>0&&(be.instanceMatrix.needsUpdate=!0,be.instanceColor&&(be.instanceColor.needsUpdate=!0));const Ke=ve>0||w.particleSystems.some(({system:s})=>s.emitting||s.activeParticles>0);if(Ce.current&&!Ke&&(B.current=!1,G==null||G()),Ce.current=Ke,ge&&X.current){const s=z.array,u=H.array;let E=0;const U=ae.position.x,ee=ae.position.y,L=ae.position.z;for(let ce=0;ce<w.particleSystems.length;ce++){const{system:te,config:D}=w.particleSystems[ce];if(!D.emissionTrailEnabled||!te.emitting&&te.activeParticles<=0)continue;const ze=D.emissionTrailDuration??1,we=D.emissionTrailWidth??.3,Q=D.bloomIntensity??1,Re=we*.5,oe=re.current,x=oe.buf,Te=oe.count,Ae=oe.head,J=oe.elapsed;if(Te<2)continue;const F=((Ae-Te)%M+M)%M,le=J-x[F*6+3],Fe=Math.min(ze,le);if(Fe<.001)continue;const q=D.colorTransitionEnabled?D.startColor??[1,1,1]:D.particleColor??[1,1,1],ue=D.colorTransitionEnabled?D.endColor??[1,1,1]:q,Qe=(t,c)=>{const g=J-t;for(let f=0;f<Te-1;f++){const b=((Ae-1-f)%M+M)%M,P=((Ae-2-f)%M+M)%M,j=x[b*6+3],T=x[P*6+3];if(g>=T&&g<=j){const p=j!==T?(g-T)/(j-T):0;c[0]=x[P*6]+(x[b*6]-x[P*6])*p,c[1]=x[P*6+1]+(x[b*6+1]-x[P*6+1])*p,c[2]=x[P*6+2]+(x[b*6+2]-x[P*6+2])*p,c[3]=x[P*6+4]+(x[b*6+4]-x[P*6+4])*p,c[4]=x[P*6+5]+(x[b*6+5]-x[P*6+5])*p;return}}c[0]=x[F*6],c[1]=x[F*6+1],c[2]=x[F*6+2],c[3]=x[F*6+4],c[4]=x[F*6+5]},W=Math.max(1,Math.min(ye,D.emissionTrailSegments??8)),o=[R.x,R.y,R.z],He=D.emissionTrailShape??"straight",We=[];{const t=D.emissionTrailShapeAmplitude??.1,c=D.emissionTrailShapeFrequency??4,g=2*Math.PI*c*J;let f=0,b=0;He==="zigzag"?f=t*Math.sign(Math.sin(g)):He==="sine"?f=t*Math.sin(g):He==="spiral"&&(f=t*Math.sin(g),b=t*Math.cos(g)),We.push(f,b)}const qe=[0,0,0,0,0];for(let t=1;t<=W;t++){const c=t/W*Fe;Qe(c,qe),o.push(qe[0],qe[1],qe[2]),We.push(qe[3],qe[4])}const tt=o[0]-o[W*3],nt=o[1]-o[W*3+1],rt=o[2]-o[W*3+2];if(tt*tt+nt*nt+rt*rt<1e-6)continue;let st=0,it=0,ot=0;const Pe=[],Ge=[];for(let t=0;t<=W;t++){let c,g,f;t===0?(c=o[3]-o[0],g=o[4]-o[1],f=o[5]-o[2]):t===W?(c=o[t*3]-o[(t-1)*3],g=o[t*3+1]-o[(t-1)*3+1],f=o[t*3+2]-o[(t-1)*3+2]):(c=o[(t+1)*3]-o[(t-1)*3],g=o[(t+1)*3+1]-o[(t-1)*3+1],f=o[(t+1)*3+2]-o[(t-1)*3+2]);let b=Math.sqrt(c*c+g*g+f*f);b<1e-8&&(c=0,g=0,f=1,b=1),c/=b,g/=b,f/=b,Ge.push(c,g,f);const P=U-o[t*3],j=ee-o[t*3+1],T=L-o[t*3+2];let p=g*T-f*j,S=f*P-c*T,v=c*j-g*P,k=Math.sqrt(p*p+S*S+v*v);k<1e-8&&(p=-f,S=0,v=c,k=Math.sqrt(p*p+S*S+v*v)),k<1e-8&&(p=0,S=1,v=0,k=1),p/=k,S/=k,v/=k,t>0&&p*st+S*it+v*ot<0&&(p=-p,S=-S,v=-v),st=p,it=S,ot=v,Pe.push(p,S,v)}if(He!=="straight")for(let t=1;t<=W;t++){const c=We[t*2],g=We[t*2+1];if(Math.abs(c)<1e-8&&Math.abs(g)<1e-8)continue;const f=t*3,b=Ge[f],P=Ge[f+1],j=Ge[f+2];let T=-j,p=0,S=b,v=Math.sqrt(T*T+S*S);if(v<1e-6&&(T=0,p=j,S=-P,v=Math.sqrt(T*T+p*p+S*S),v<1e-6&&(T=1,p=0,S=0,v=1)),T/=v,p/=v,S/=v,He==="spiral"){const k=P*S-j*p,Le=j*T-b*S,Xe=b*p-P*T;o[f]+=T*c+k*g,o[f+1]+=p*c+Le*g,o[f+2]+=S*c+Xe*g}else o[f]+=T*c,o[f+1]+=p*c,o[f+2]+=S*c}for(let t=0;t<W;t++){const c=t/W,g=(t+1)/W,f=Re*(1-c),b=Re*(1-g),P=(1-c)*(1-c),j=(1-g)*(1-g),T=Math.min(1,(q[0]+(ue[0]-q[0])*c)*Q)*P,p=Math.min(1,(q[1]+(ue[1]-q[1])*c)*Q)*P,S=Math.min(1,(q[2]+(ue[2]-q[2])*c)*Q)*P,v=Math.min(1,(q[0]+(ue[0]-q[0])*g)*Q)*j,k=Math.min(1,(q[1]+(ue[1]-q[1])*g)*Q)*j,Le=Math.min(1,(q[2]+(ue[2]-q[2])*g)*Q)*j,Xe=o[t*3],at=o[t*3+1],ct=o[t*3+2],lt=o[(t+1)*3],ut=o[(t+1)*3+1],dt=o[(t+1)*3+2],ft=Pe[t*3],mt=Pe[t*3+1],pt=Pe[t*3+2],ht=Pe[(t+1)*3],gt=Pe[(t+1)*3+1],yt=Pe[(t+1)*3+2],Dt=Xe+ft*f,Ct=at+mt*f,Et=ct+pt*f,Mt=Xe-ft*f,St=at-mt*f,xt=ct-pt*f,bt=lt+ht*b,vt=ut+gt*b,zt=dt+yt*b,Vt=lt-ht*b,Ft=ut-gt*b,qt=dt-yt*b,m=E*3;s[m]=Dt,s[m+1]=Ct,s[m+2]=Et,u[m]=T,u[m+1]=p,u[m+2]=S,s[m+3]=Mt,s[m+4]=St,s[m+5]=xt,u[m+3]=T,u[m+4]=p,u[m+5]=S,s[m+6]=bt,s[m+7]=vt,s[m+8]=zt,u[m+6]=v,u[m+7]=k,u[m+8]=Le,s[m+9]=Mt,s[m+10]=St,s[m+11]=xt,u[m+9]=T,u[m+10]=p,u[m+11]=S,s[m+12]=Vt,s[m+13]=Ft,s[m+14]=qt,u[m+12]=v,u[m+13]=k,u[m+14]=Le,s[m+15]=bt,s[m+16]=vt,s[m+17]=zt,u[m+15]=v,u[m+16]=k,u[m+17]=Le,E+=6}}const O=Z.current;if(E<O){const ce=E*3,te=O*3;for(let D=ce;D<te;D++)s[D]=0,u[D]=0}Z.current=E,se.setDrawRange(0,E),z.needsUpdate=!0,H.needsUpdate=!0}}),Y?je.jsxs(je.Fragment,{children:[je.jsx("instancedMesh",{ref:d=>{De.current=d,d&&(d.count=0,d.visible=!Ue)},args:[Oe,r,Ne],frustumCulled:!1,renderOrder:100,visible:y&&!Ue}),ge&&je.jsx("mesh",{ref:X,geometry:se,material:Ee,frustumCulled:!1,renderOrder:99,visible:y})]}):null}const jt=`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c=require("react"),Z=require("@react-three/fiber"),X=require("hz-particles"),K=require("react/jsx-runtime"),Q=require("three");function Y(n){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(n){for(const s in n)if(s!=="default"){const e=Object.getOwnPropertyDescriptor(n,s);Object.defineProperty(t,s,e.get?e:{enumerable:!0,get:()=>n[s]})}}return t.default=n,Object.freeze(t)}const p=Y(Q);function J(n,t){if(t===1)return n;const s=(e,u)=>e!=null?e*t:u*t;return{...n,systems:n.systems.map(e=>({...e,particleSize:s(e.particleSize,.5),minSize:e.minSize!=null?e.minSize*t:void 0,maxSize:e.maxSize!=null?e.maxSize*t:void 0,particleSpeed:(e.particleSpeed??1)*t,minSpeed:e.minSpeed!=null?e.minSpeed*t:void 0,maxSpeed:e.maxSpeed!=null?e.maxSpeed*t:void 0,cubeLength:e.cubeLength!=null?e.cubeLength*t:void 0,outerLength:e.outerLength!=null?e.outerLength*t:void 0,innerLength:e.innerLength!=null?e.innerLength*t:void 0,outerRadius:e.outerRadius!=null?e.outerRadius*t:void 0,innerRadius:e.innerRadius!=null?e.innerRadius*t:void 0,squareSize:e.squareSize!=null?e.squareSize*t:void 0,squareInnerSize:e.squareInnerSize!=null?e.squareInnerSize*t:void 0,circleInnerRadius:e.circleInnerRadius!=null?e.circleInnerRadius*t:void 0,circleOuterRadius:e.circleOuterRadius!=null?e.circleOuterRadius*t:void 0,cylinderInnerRadius:e.cylinderInnerRadius!=null?e.cylinderInnerRadius*t:void 0,cylinderOuterRadius:e.cylinderOuterRadius!=null?e.cylinderOuterRadius*t:void 0,cylinderHeight:e.cylinderHeight!=null?e.cylinderHeight*t:void 0,emissionTrailWidth:(e.emissionTrailWidth??.3)*t,emissionTrailDuration:(e.emissionTrailDuration??1)*t,emissionTrailMinDistance:e.emissionTrailMinDistance!=null?e.emissionTrailMinDistance*t:void 0,emissionTrailShapeAmplitude:e.emissionTrailShapeAmplitude!=null?e.emissionTrailShapeAmplitude*t:void 0}))}}function $({preset:n,positionRef:t,position:s=[0,0,0],scale:e=1,active:u=!0,renderPriority:w=1,noOcclusion:I=!1,respectReducedMotion:z=!0}){const f=c.useRef(null),S=c.useRef(null),T=c.useRef(!1),F=c.useRef(0),y=c.useRef(u);y.current=u;const P=c.useRef(s);P.current=s;const C=c.useRef(!1),L=c.useMemo(()=>e&&e!==1?J(n,e):n,[n,e]),q=i=>t?i.addMovingEmitter(L,{getPosition:()=>{const o=t.current;return y.current&&o?[o.x,o.y,o.z]:null}}):i.addEmitter(L,P.current);return c.useEffect(()=>{var d,h;const i=f.current;if(!i)return;let o=!1;return(h=(d=S.current)==null?void 0:d.remove)==null||h.call(d),S.current=null,q(i).then(l=>{var x;o?(x=l==null?void 0:l.remove)==null||x.call(l):S.current=l}),()=>{o=!0}},[L]),c.useEffect(()=>{var d;if(typeof window>"u"||!window.matchMedia)return;const i=window.matchMedia("(prefers-reduced-motion: reduce)"),o=()=>{C.current=i.matches};return o(),(d=i.addEventListener)==null||d.call(i,"change",o),()=>{var h;return(h=i.removeEventListener)==null?void 0:h.call(i,"change",o)}},[]),c.useEffect(()=>()=>{var i,o,d,h;(o=(i=S.current)==null?void 0:i.remove)==null||o.call(i),(h=(d=f.current)==null?void 0:d.destroy)==null||h.call(d),f.current=null,S.current=null,T.current=!1},[]),Z.useFrame(i=>{i.gl.render(i.scene,i.camera);const o=performance.now(),d=F.current?Math.min(.05,(o-F.current)/1e3):.016;F.current=o;const h=i.gl,l=h.backend;!f.current&&!T.current&&(l!=null&&l.device)&&(l!=null&&l.context)&&(T.current=!0,X.initHzFxOverlay({device:l.device,context:l.context,canvas:h.domElement},{getSceneDepth:I?()=>null:X.makeThreeSceneDepth(h)}).then(v=>(f.current=v,q(v))).then(v=>{S.current=v}).catch(v=>console.error("[HZFaithfulFX] init failed:",v)));const x=f.current;if(x){const v=i.camera;x.setCamera(v.projectionMatrix.elements,v.matrixWorldInverse.elements,v.position),z&&C.current||x.render(d)}},w),null}const ee=`
|
|
2
2
|
attribute vec4 aColor;
|
|
3
3
|
varying vec4 vColor;
|
|
4
4
|
void main() {
|
|
5
5
|
vColor = aColor;
|
|
6
6
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
|
7
7
|
}
|
|
8
|
-
`,
|
|
8
|
+
`,te=`
|
|
9
9
|
varying vec4 vColor;
|
|
10
10
|
void main() {
|
|
11
11
|
gl_FragColor = vColor;
|
|
12
12
|
}
|
|
13
|
-
`;function
|
|
13
|
+
`;function ne({positionRef:n,duration:t=1,width:s=.3,color:e=[1,1,1],maxPoints:u=256,minDistance:w=.05,opacity:I=1,blending:z=p.AdditiveBlending,visible:f=!0}){const{camera:S}=Z.useThree(),T=c.useRef(null),F=c.useRef({positions:new Float32Array(u*3),times:new Float32Array(u),head:0,count:0,lastPos:new p.Vector3(1/0,1/0,1/0),elapsed:0}),{geometry:y,posAttr:P,colorAttr:C,indexBuf:L}=c.useMemo(()=>{const x=u*2,v=new Float32Array(x*3),r=new Float32Array(x*4),M=new p.BufferGeometry,V=new p.BufferAttribute(v,3);V.setUsage(p.DynamicDrawUsage),M.setAttribute("position",V);const b=new p.BufferAttribute(r,4);b.setUsage(p.DynamicDrawUsage),M.setAttribute("aColor",b);const A=(u-1)*6,m=new Uint32Array(A);for(let E=0;E<u-1;E++){const a=E*2,g=E*6;m[g]=a,m[g+1]=a+1,m[g+2]=a+2,m[g+3]=a+1,m[g+4]=a+3,m[g+5]=a+2}const D=new p.BufferAttribute(m,1);return M.setIndex(D),M.setDrawRange(0,0),{geometry:M,posAttr:V,colorAttr:b,indexBuf:D}},[u]),q=c.useMemo(()=>new p.ShaderMaterial({vertexShader:ee,fragmentShader:te,transparent:!0,depthWrite:!1,side:p.DoubleSide,blending:z}),[z]),i=c.useMemo(()=>new p.Vector3,[]),o=c.useMemo(()=>new p.Vector3,[]),d=c.useMemo(()=>new p.Vector3,[]),h=c.useMemo(()=>new p.Vector3(0,1,0),[]),l=c.useMemo(()=>new p.Vector3,[]);return Z.useFrame((x,v)=>{if(!T.current)return;const r=F.current;if(r.elapsed+=v,!f){r.count=0,r.head=0,r.lastPos.set(1/0,1/0,1/0),y.setDrawRange(0,0);return}const M=n.current;if(!M)return;if(r.lastPos.distanceTo(M)>=w){const a=(r.head+r.count)%u;r.positions[a*3]=M.x,r.positions[a*3+1]=M.y,r.positions[a*3+2]=M.z,r.times[a]=r.elapsed,r.count<u?r.count++:r.head=(r.head+1)%u,r.lastPos.copy(M)}for(;r.count>0;){const a=r.head;if(r.elapsed-r.times[a]>t)r.head=(r.head+1)%u,r.count--;else break}if(r.count<2){y.setDrawRange(0,0);return}const b=P.array,A=C.array;let m=null;const D=r.count;for(let a=0;a<D;a++){const g=(r.head+a)%u,j=r.positions[g*3],B=r.positions[g*3+1],U=r.positions[g*3+2],_=1-(r.elapsed-r.times[g])/t;if(a<D-1){const W=(r.head+a+1)%u;i.set(r.positions[W*3]-j,r.positions[W*3+1]-B,r.positions[W*3+2]-U);const N=i.length();N>1e-6?i.divideScalar(N):m&&i.copy(m)}else m&&i.copy(m);d.set(S.position.x-j,S.position.y-B,S.position.z-U),o.crossVectors(i,d);let H=o.length();H<1e-6&&(l.crossVectors(i,h),o.copy(l),H=o.length(),H<1e-6&&(o.set(1,0,0),H=1)),o.divideScalar(H);const O=s*_,G=I*_*_,R=a*2;b[R*3]=j+o.x*O,b[R*3+1]=B+o.y*O,b[R*3+2]=U+o.z*O,b[(R+1)*3]=j-o.x*O,b[(R+1)*3+1]=B-o.y*O,b[(R+1)*3+2]=U-o.z*O,A[R*4]=e[0],A[R*4+1]=e[1],A[R*4+2]=e[2],A[R*4+3]=G,A[(R+1)*4]=e[0],A[(R+1)*4+1]=e[1],A[(R+1)*4+2]=e[2],A[(R+1)*4+3]=G,m=m||new p.Vector3,m.copy(i)}const E=(D-1)*6;y.setDrawRange(0,E),P.needsUpdate=!0,C.needsUpdate=!0}),K.jsx("mesh",{ref:T,geometry:y,material:q,frustumCulled:!1,renderOrder:101,visible:f})}function k(n){return Math.abs(Math.sin(n*12.9898)*43758.5453)%1}function re(n){const t=Math.sin(n*54321.67)*43758.5453%1;return t<0?t+1:t}function ie(n,t,s,e){if(s<=0)return 0;const u=t/s;let w=n.particleSize??.5;if(n.randomSize){const z=n.minSize??.1,f=n.maxSize??.5;w=z+(f-z)*re(s)}const I=Math.max(.01,Math.min(10,n.sizeLifetimeSpeed??1));if(n.fadeSizeEnabled&&(w*=1-Math.pow(u,1/I)),n.increaseSizeEnabled&&(w*=1+Math.pow(u,1/I)),n.pulseEnabled){const z=n.pulseAmplitude??.5,f=n.pulseFrequency??1,T=(n.pulsePhaseRandom??0)*k(e)*Math.PI*2;w*=1+z*Math.sin(t*f*Math.PI*2+T)}return Math.max(0,w)}function oe(n,t,s,e){if(s<=0)return 0;let u=n.opacity??1;const w=t/s;if(n.fadeEnabled&&(u*=Math.max(0,1-w)),n.pulseEnabled&&n.pulseOpacity){const I=n.pulseAmplitude??.5,z=n.pulseFrequency??1,S=(n.pulsePhaseRandom??0)*k(e)*Math.PI*2;u*=Math.max(0,1+I*Math.sin(t*z*Math.PI*2+S))}return Math.max(0,Math.min(1,u))}Object.defineProperty(exports,"fetchPreset",{enumerable:!0,get:()=>X.fetchPreset});exports.HZFaithfulFX=$;exports.HZTrailRibbon=ne;exports.computeParticleOpacity=oe;exports.computeParticleSize=ie;exports.particleHash=k;exports.scalePreset=J;
|
|
@@ -2,26 +2,33 @@ import type { SceneData, ParticleSystemConfig } from 'hz-particles';
|
|
|
2
2
|
import type { RefObject } from 'react';
|
|
3
3
|
import type { Vector3 } from 'three';
|
|
4
4
|
|
|
5
|
-
export interface
|
|
6
|
-
/** Preset SceneData (loaded from JSON or inline)
|
|
7
|
-
preset: SceneData
|
|
8
|
-
/**
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
autoPlay?: boolean;
|
|
14
|
-
/** Toggle visibility (default true). */
|
|
15
|
-
visible?: boolean;
|
|
16
|
-
/** Scale multiplier for particle size and speed (default 1). */
|
|
5
|
+
export interface HZFaithfulFXProps {
|
|
6
|
+
/** Preset SceneData (loaded from JSON or inline). */
|
|
7
|
+
preset: SceneData;
|
|
8
|
+
/** Moving emitter (e.g. a ball trail): the overlay reads this ref each frame. */
|
|
9
|
+
positionRef?: RefObject<Vector3 | null>;
|
|
10
|
+
/** Static emitter world position (used when `positionRef` is omitted). */
|
|
11
|
+
position?: [number, number, number];
|
|
12
|
+
/** Uniform scale applied to the preset (sizes, speeds, emission, trail). */
|
|
17
13
|
scale?: number;
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
|
|
14
|
+
/** When false, a moving emitter pauses (no new trail). Default true. */
|
|
15
|
+
active?: boolean;
|
|
16
|
+
/** `useFrame` priority. This component DRIVES rendering, so keep it > 0. Default 1. */
|
|
17
|
+
renderPriority?: number;
|
|
18
|
+
/** Skip scene-depth occlusion (particles never hidden behind geometry). */
|
|
19
|
+
noOcclusion?: boolean;
|
|
20
|
+
/** Respect the user's `prefers-reduced-motion` setting by freezing the FX. Default true. */
|
|
21
|
+
respectReducedMotion?: boolean;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
/**
|
|
25
|
+
* Engine-FAITHFUL R3F component: runs the real hz-particles overlay inline on three's
|
|
26
|
+
* WebGPURenderer (shader shapes, noise, per-system blending, multi-pass bloom, faithful
|
|
27
|
+
* trails) — what you design in the editor is exactly what renders. It DRIVES rendering
|
|
28
|
+
* (its `useFrame` calls `gl.render` itself). If your host owns its own render loop, use
|
|
29
|
+
* `initHzFxOverlay()` + `makeThreeSceneDepth()` directly instead.
|
|
30
|
+
*/
|
|
31
|
+
export declare function HZFaithfulFX(props: HZFaithfulFXProps): JSX.Element;
|
|
25
32
|
|
|
26
33
|
export declare function scalePreset(preset: SceneData, scale: number): SceneData;
|
|
27
34
|
|