hz-particles 1.3.0 → 1.4.1

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 CHANGED
@@ -19,10 +19,9 @@ export function Scene() {
19
19
  }
20
20
  ```
21
21
 
22
- <!-- TODO: fill in the real public URLs (see PR / message) -->
23
- - **Prompt FX generator / editor:** https://YOUR-SITE
24
- - **Live demo:** https://YOUR-SITE/demo
25
- - **Docs:** https://YOUR-SITE/docs
22
+ - **Prompt FX generator / editor:** https://particles.hole.zone/editor
23
+ - **Gallery (live WebGPU previews):** https://particles.hole.zone/discover
24
+ - **Docs:** https://particles.hole.zone/docs
26
25
  - **NPM:** https://www.npmjs.com/package/hz-particles
27
26
 
28
27
  ## Why hz-particles?
@@ -59,6 +58,10 @@ HZ editor (manual or prompt) → preset (JSON / .hzfx) → faithful WebGPU r
59
58
  frustum, hemisphere, disc, annulus, arc, spiral, polygon, `cubeSurface`, `sphereSurface`,
60
59
  `boxFrame`, and more
61
60
  - **Real-time physics** — gravity, attractors, drag, velocity, lifetime
61
+ - **Particle orientation modes** — `billboard` (fixed/random/velocity-aligned), `oriented` (a fixed
62
+ world angle via Euler `orientX/Y/Z`), and `cylindrical` (upright, faces the camera horizontally)
63
+ - **Keyframe animation** — animate per-system parameters over time with curves + easing
64
+ (`keyframes` + `keyframesEnabled`), driven by the unified clock; per-emitter `startAt` sequencing
62
65
  - **Serialized presets** — self-contained `.hzfx` binary package (textures + GLB inlined) or plain JSON
63
66
  - **3D object support** — static 3D objects alongside particle systems
64
67
 
@@ -296,6 +299,11 @@ Presets are plain `SceneData`. A few key per-system fields:
296
299
  | `bloom` | `boolean` | Enable bloom glow on particles |
297
300
  | `gravity` | `number` | Gravity strength applied to particles |
298
301
  | `damping` | `number` | Velocity damping factor (0 = no drag, 1 = full stop) |
302
+ | `rotationMode` | `string` | Particle orientation: `fixed` / `random` / `velocity` (billboard), `oriented` (fixed world angle), `cylindrical` (upright, camera-facing) |
303
+ | `orientX` / `orientY` / `orientZ` | `number` | Euler angles (radians) for `rotationMode: 'oriented'` |
304
+ | `keyframesEnabled` | `boolean` | Enable keyframe animation of system parameters over time |
305
+ | `keyframes` | `object` | Per-parameter keyframe tracks (value + curve/easing) applied via the clock |
306
+ | `startAt` | `number` | Delay (seconds) before this emitter starts, for relative sequencing |
299
307
  | `emissionTrailEnabled` | `boolean` | Enable particle trail rendering |
300
308
  | `emissionTrailDuration` | `number` | How long trail segments persist (seconds) |
301
309
  | `emissionTrailWidth` | `number` | Width of the emission trail |
@@ -469,9 +477,8 @@ Also exported for advanced usage:
469
477
  Generate effects from a prompt — or build them by hand — in the HZ editor, then export a preset and
470
478
  render it with this package.
471
479
 
472
- <!-- TODO: replace with the public editor URL -->
473
- - Hosted editor & prompt FX generator: https://YOUR-SITE
474
- - Local: `http://localhost:8110/editor` (run `docker-compose up` from the repo root)
480
+ - Hosted editor & prompt FX generator: https://particles.hole.zone/editor
481
+ - Browse the community gallery (live previews): https://particles.hole.zone/discover
475
482
 
476
483
  The editor provides real-time configuration, emitter-shape tuning, GLB import + animation control, a
477
484
  preset library, and `JSON` / `.hzfx` export.
@@ -487,4 +494,4 @@ preset library, and `JSON` / `.hzfx` export.
487
494
 
488
495
  MIT License — see [LICENSE](LICENSE).
489
496
 
490
- Copyright (c) 2025 HZ
497
+ Copyright (c) 2025-2026 HZ
@@ -1,4 +1,4 @@
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=`
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(r){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(r){for(const s in r)if(s!=="default"){const e=Object.getOwnPropertyDescriptor(r,s);Object.defineProperty(t,s,e.get?e:{enumerable:!0,get:()=>r[s]})}}return t.default=r,Object.freeze(t)}const p=Y(Q);function J(r,t){if(t===1)return r;const s=(e,u)=>e!=null?e*t:u*t;return{...r,systems:r.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:r,positionRef:t,position:s=[0,0,0],scale:e=1,active:u=!0,renderPriority:w=1,noOcclusion:I=!1,respectReducedMotion:z=!0}){const R=c.useRef(null),g=c.useRef(null),T=c.useRef(!1),C=c.useRef(0),y=c.useRef(u);y.current=u;const P=c.useRef(s);P.current=s;const H=c.useRef(!1),q=c.useMemo(()=>e&&e!==1?J(r,e):r,[r,e]),V=i=>t?i.addMovingEmitter(q,{getPosition:()=>{const o=t.current;return y.current&&o?[o.x,o.y,o.z]:null}}):i.addEmitter(q,P.current);return c.useEffect(()=>{var l,m;const i=R.current;if(!i)return;let o=!1;return(m=(l=g.current)==null?void 0:l.remove)==null||m.call(l),g.current=null,V(i).then(d=>{var A;o?(A=d==null?void 0:d.remove)==null||A.call(d):g.current=d}),()=>{o=!0}},[q]),c.useEffect(()=>{var l;if(typeof window>"u"||!window.matchMedia)return;const i=window.matchMedia("(prefers-reduced-motion: reduce)"),o=()=>{H.current=i.matches};return o(),(l=i.addEventListener)==null||l.call(i,"change",o),()=>{var m;return(m=i.removeEventListener)==null?void 0:m.call(i,"change",o)}},[]),c.useEffect(()=>()=>{var i,o,l,m;(o=(i=g.current)==null?void 0:i.remove)==null||o.call(i),(m=(l=R.current)==null?void 0:l.destroy)==null||m.call(l),R.current=null,g.current=null,T.current=!1},[]),Z.useFrame(i=>{var n,f;i.gl.render(i.scene,i.camera);const o=performance.now(),l=C.current?Math.min(.05,(o-C.current)/1e3):.016;C.current=o;const m=i.gl,d=m.backend,A=(d==null?void 0:d.context)||((f=(n=m.domElement)==null?void 0:n.getContext)==null?void 0:f.call(n,"webgpu"));!R.current&&!T.current&&(d!=null&&d.device)&&A&&(T.current=!0,X.initHzFxOverlay({device:d.device,context:A,canvas:m.domElement},{getSceneDepth:I?()=>null:X.makeThreeSceneDepth(m)}).then(h=>(R.current=h,V(h))).then(h=>{g.current=h}).catch(h=>console.error("[HZFaithfulFX] init failed:",h)));const D=R.current;if(D){const h=i.camera;D.setCamera(h.projectionMatrix.elements,h.matrixWorldInverse.elements,h.position),z&&H.current||D.render(l)}},w),null}const ee=`
2
2
  attribute vec4 aColor;
3
3
  varying vec4 vColor;
4
4
  void main() {
@@ -10,4 +10,4 @@ varying vec4 vColor;
10
10
  void main() {
11
11
  gl_FragColor = vColor;
12
12
  }
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;
13
+ `;function ne({positionRef:r,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:R=!0}){const{camera:g}=Z.useThree(),T=c.useRef(null),C=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:H,indexBuf:q}=c.useMemo(()=>{const A=u*2,D=new Float32Array(A*3),n=new Float32Array(A*4),f=new p.BufferGeometry,h=new p.BufferAttribute(D,3);h.setUsage(p.DynamicDrawUsage),f.setAttribute("position",h);const x=new p.BufferAttribute(n,4);x.setUsage(p.DynamicDrawUsage),f.setAttribute("aColor",x);const b=(u-1)*6,v=new Uint32Array(b);for(let O=0;O<u-1;O++){const a=O*2,M=O*6;v[M]=a,v[M+1]=a+1,v[M+2]=a+2,v[M+3]=a+1,v[M+4]=a+3,v[M+5]=a+2}const E=new p.BufferAttribute(v,1);return f.setIndex(E),f.setDrawRange(0,0),{geometry:f,posAttr:h,colorAttr:x,indexBuf:E}},[u]),V=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,[]),l=c.useMemo(()=>new p.Vector3,[]),m=c.useMemo(()=>new p.Vector3(0,1,0),[]),d=c.useMemo(()=>new p.Vector3,[]);return Z.useFrame((A,D)=>{if(!T.current)return;const n=C.current;if(n.elapsed+=D,!R){n.count=0,n.head=0,n.lastPos.set(1/0,1/0,1/0),y.setDrawRange(0,0);return}const f=r.current;if(!f)return;if(n.lastPos.distanceTo(f)>=w){const a=(n.head+n.count)%u;n.positions[a*3]=f.x,n.positions[a*3+1]=f.y,n.positions[a*3+2]=f.z,n.times[a]=n.elapsed,n.count<u?n.count++:n.head=(n.head+1)%u,n.lastPos.copy(f)}for(;n.count>0;){const a=n.head;if(n.elapsed-n.times[a]>t)n.head=(n.head+1)%u,n.count--;else break}if(n.count<2){y.setDrawRange(0,0);return}const x=P.array,b=H.array;let v=null;const E=n.count;for(let a=0;a<E;a++){const M=(n.head+a)%u,j=n.positions[M*3],B=n.positions[M*3+1],U=n.positions[M*3+2],_=1-(n.elapsed-n.times[M])/t;if(a<E-1){const W=(n.head+a+1)%u;i.set(n.positions[W*3]-j,n.positions[W*3+1]-B,n.positions[W*3+2]-U);const N=i.length();N>1e-6?i.divideScalar(N):v&&i.copy(v)}else v&&i.copy(v);l.set(g.position.x-j,g.position.y-B,g.position.z-U),o.crossVectors(i,l);let L=o.length();L<1e-6&&(d.crossVectors(i,m),o.copy(d),L=o.length(),L<1e-6&&(o.set(1,0,0),L=1)),o.divideScalar(L);const F=s*_,G=I*_*_,S=a*2;x[S*3]=j+o.x*F,x[S*3+1]=B+o.y*F,x[S*3+2]=U+o.z*F,x[(S+1)*3]=j-o.x*F,x[(S+1)*3+1]=B-o.y*F,x[(S+1)*3+2]=U-o.z*F,b[S*4]=e[0],b[S*4+1]=e[1],b[S*4+2]=e[2],b[S*4+3]=G,b[(S+1)*4]=e[0],b[(S+1)*4+1]=e[1],b[(S+1)*4+2]=e[2],b[(S+1)*4+3]=G,v=v||new p.Vector3,v.copy(i)}const O=(E-1)*6;y.setDrawRange(0,O),P.needsUpdate=!0,H.needsUpdate=!0}),K.jsx("mesh",{ref:T,geometry:y,material:V,frustumCulled:!1,renderOrder:101,visible:R})}function k(r){return Math.abs(Math.sin(r*12.9898)*43758.5453)%1}function re(r){const t=Math.sin(r*54321.67)*43758.5453%1;return t<0?t+1:t}function ie(r,t,s,e){if(s<=0)return 0;const u=t/s;let w=r.particleSize??.5;if(r.randomSize){const z=r.minSize??.1,R=r.maxSize??.5;w=z+(R-z)*re(s)}const I=Math.max(.01,Math.min(10,r.sizeLifetimeSpeed??1));if(r.fadeSizeEnabled&&(w*=1-Math.pow(u,1/I)),r.increaseSizeEnabled&&(w*=1+Math.pow(u,1/I)),r.pulseEnabled){const z=r.pulseAmplitude??.5,R=r.pulseFrequency??1,T=(r.pulsePhaseRandom??0)*k(e)*Math.PI*2;w*=1+z*Math.sin(t*R*Math.PI*2+T)}return Math.max(0,w)}function oe(r,t,s,e){if(s<=0)return 0;let u=r.opacity??1;const w=t/s;if(r.fadeEnabled&&(u*=Math.max(0,1-w)),r.pulseEnabled&&r.pulseOpacity){const I=r.pulseAmplitude??.5,z=r.pulseFrequency??1,g=(r.pulsePhaseRandom??0)*k(e)*Math.PI*2;u*=Math.max(0,1+I*Math.sin(t*z*Math.PI*2+g))}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;
@@ -4,106 +4,107 @@ import { initHzFxOverlay as Q, makeThreeSceneDepth as Y } from "hz-particles";
4
4
  import { fetchPreset as he } from "hz-particles";
5
5
  import { jsx as $ } from "react/jsx-runtime";
6
6
  import * as s from "three";
7
- function ee(r, t) {
8
- if (t === 1) return r;
9
- const v = (e, a) => e != null ? e * t : a * t;
7
+ function ee(r, n) {
8
+ if (n === 1) return r;
9
+ const S = (e, a) => e != null ? e * n : a * n;
10
10
  return {
11
11
  ...r,
12
12
  systems: r.systems.map((e) => ({
13
13
  ...e,
14
14
  // Particle visual size
15
- particleSize: v(e.particleSize, 0.5),
16
- minSize: e.minSize != null ? e.minSize * t : void 0,
17
- maxSize: e.maxSize != null ? e.maxSize * t : void 0,
15
+ particleSize: S(e.particleSize, 0.5),
16
+ minSize: e.minSize != null ? e.minSize * n : void 0,
17
+ maxSize: e.maxSize != null ? e.maxSize * n : void 0,
18
18
  // Speed
19
- particleSpeed: (e.particleSpeed ?? 1) * t,
20
- minSpeed: e.minSpeed != null ? e.minSpeed * t : void 0,
21
- maxSpeed: e.maxSpeed != null ? e.maxSpeed * t : void 0,
19
+ particleSpeed: (e.particleSpeed ?? 1) * n,
20
+ minSpeed: e.minSpeed != null ? e.minSpeed * n : void 0,
21
+ maxSpeed: e.maxSpeed != null ? e.maxSpeed * n : void 0,
22
22
  // Emission shape dimensions
23
- cubeLength: e.cubeLength != null ? e.cubeLength * t : void 0,
24
- outerLength: e.outerLength != null ? e.outerLength * t : void 0,
25
- innerLength: e.innerLength != null ? e.innerLength * t : void 0,
26
- outerRadius: e.outerRadius != null ? e.outerRadius * t : void 0,
27
- innerRadius: e.innerRadius != null ? e.innerRadius * t : void 0,
28
- squareSize: e.squareSize != null ? e.squareSize * t : void 0,
29
- squareInnerSize: e.squareInnerSize != null ? e.squareInnerSize * t : void 0,
30
- circleInnerRadius: e.circleInnerRadius != null ? e.circleInnerRadius * t : void 0,
31
- circleOuterRadius: e.circleOuterRadius != null ? e.circleOuterRadius * t : void 0,
32
- cylinderInnerRadius: e.cylinderInnerRadius != null ? e.cylinderInnerRadius * t : void 0,
33
- cylinderOuterRadius: e.cylinderOuterRadius != null ? e.cylinderOuterRadius * t : void 0,
34
- cylinderHeight: e.cylinderHeight != null ? e.cylinderHeight * t : void 0,
23
+ cubeLength: e.cubeLength != null ? e.cubeLength * n : void 0,
24
+ outerLength: e.outerLength != null ? e.outerLength * n : void 0,
25
+ innerLength: e.innerLength != null ? e.innerLength * n : void 0,
26
+ outerRadius: e.outerRadius != null ? e.outerRadius * n : void 0,
27
+ innerRadius: e.innerRadius != null ? e.innerRadius * n : void 0,
28
+ squareSize: e.squareSize != null ? e.squareSize * n : void 0,
29
+ squareInnerSize: e.squareInnerSize != null ? e.squareInnerSize * n : void 0,
30
+ circleInnerRadius: e.circleInnerRadius != null ? e.circleInnerRadius * n : void 0,
31
+ circleOuterRadius: e.circleOuterRadius != null ? e.circleOuterRadius * n : void 0,
32
+ cylinderInnerRadius: e.cylinderInnerRadius != null ? e.cylinderInnerRadius * n : void 0,
33
+ cylinderOuterRadius: e.cylinderOuterRadius != null ? e.cylinderOuterRadius * n : void 0,
34
+ cylinderHeight: e.cylinderHeight != null ? e.cylinderHeight * n : void 0,
35
35
  // Trail
36
- emissionTrailWidth: (e.emissionTrailWidth ?? 0.3) * t,
37
- emissionTrailDuration: (e.emissionTrailDuration ?? 1) * t,
38
- emissionTrailMinDistance: e.emissionTrailMinDistance != null ? e.emissionTrailMinDistance * t : void 0,
39
- emissionTrailShapeAmplitude: e.emissionTrailShapeAmplitude != null ? e.emissionTrailShapeAmplitude * t : void 0
36
+ emissionTrailWidth: (e.emissionTrailWidth ?? 0.3) * n,
37
+ emissionTrailDuration: (e.emissionTrailDuration ?? 1) * n,
38
+ emissionTrailMinDistance: e.emissionTrailMinDistance != null ? e.emissionTrailMinDistance * n : void 0,
39
+ emissionTrailShapeAmplitude: e.emissionTrailShapeAmplitude != null ? e.emissionTrailShapeAmplitude * n : void 0
40
40
  }))
41
41
  };
42
42
  }
43
43
  function de({
44
44
  preset: r,
45
- positionRef: t,
46
- position: v = [0, 0, 0],
45
+ positionRef: n,
46
+ position: S = [0, 0, 0],
47
47
  scale: e = 1,
48
48
  active: a = !0,
49
- renderPriority: x = 1,
49
+ renderPriority: g = 1,
50
50
  noOcclusion: T = !1,
51
- respectReducedMotion: z = !0
51
+ respectReducedMotion: x = !0
52
52
  }) {
53
- const p = I(null), S = I(null), D = I(!1), L = I(0), C = I(a);
53
+ const h = I(null), R = I(null), D = I(!1), V = I(0), C = I(a);
54
54
  C.current = a;
55
- const V = I(v);
56
- V.current = v;
57
- const H = I(!1), B = b(
55
+ const H = I(S);
56
+ H.current = S;
57
+ const O = I(!1), U = b(
58
58
  () => e && e !== 1 ? ee(r, e) : r,
59
59
  [r, e]
60
- ), U = (i) => t ? i.addMovingEmitter(B, {
60
+ ), q = (i) => n ? i.addMovingEmitter(U, {
61
61
  getPosition: () => {
62
- const o = t.current;
62
+ const o = n.current;
63
63
  return C.current && o ? [o.x, o.y, o.z] : null;
64
64
  }
65
- }) : i.addEmitter(B, V.current);
65
+ }) : i.addEmitter(U, H.current);
66
66
  return X(() => {
67
- var d, m;
68
- const i = p.current;
67
+ var c, l;
68
+ const i = h.current;
69
69
  if (!i) return;
70
70
  let o = !1;
71
- return (m = (d = S.current) == null ? void 0 : d.remove) == null || m.call(d), S.current = null, U(i).then((c) => {
72
- var M;
73
- o ? (M = c == null ? void 0 : c.remove) == null || M.call(c) : S.current = c;
71
+ return (l = (c = R.current) == null ? void 0 : c.remove) == null || l.call(c), R.current = null, q(i).then((d) => {
72
+ var A;
73
+ o ? (A = d == null ? void 0 : d.remove) == null || A.call(d) : R.current = d;
74
74
  }), () => {
75
75
  o = !0;
76
76
  };
77
- }, [B]), X(() => {
78
- var d;
77
+ }, [U]), X(() => {
78
+ var c;
79
79
  if (typeof window > "u" || !window.matchMedia) return;
80
80
  const i = window.matchMedia("(prefers-reduced-motion: reduce)"), o = () => {
81
- H.current = i.matches;
81
+ O.current = i.matches;
82
82
  };
83
- return o(), (d = i.addEventListener) == null || d.call(i, "change", o), () => {
84
- var m;
85
- return (m = i.removeEventListener) == null ? void 0 : m.call(i, "change", o);
83
+ return o(), (c = i.addEventListener) == null || c.call(i, "change", o), () => {
84
+ var l;
85
+ return (l = i.removeEventListener) == null ? void 0 : l.call(i, "change", o);
86
86
  };
87
87
  }, []), X(() => () => {
88
- var i, o, d, m;
89
- (o = (i = S.current) == null ? void 0 : i.remove) == null || o.call(i), (m = (d = p.current) == null ? void 0 : d.destroy) == null || m.call(d), p.current = null, S.current = null, D.current = !1;
88
+ var i, o, c, l;
89
+ (o = (i = R.current) == null ? void 0 : i.remove) == null || o.call(i), (l = (c = h.current) == null ? void 0 : c.destroy) == null || l.call(c), h.current = null, R.current = null, D.current = !1;
90
90
  }, []), J((i) => {
91
+ var t, p;
91
92
  i.gl.render(i.scene, i.camera);
92
- const o = performance.now(), d = L.current ? Math.min(0.05, (o - L.current) / 1e3) : 0.016;
93
- L.current = o;
94
- const m = i.gl, c = m.backend;
95
- !p.current && !D.current && (c != null && c.device) && (c != null && c.context) && (D.current = !0, Q(
96
- { device: c.device, context: c.context, canvas: m.domElement },
97
- { getSceneDepth: T ? () => null : Y(m) }
98
- ).then((f) => (p.current = f, U(f))).then((f) => {
99
- S.current = f;
100
- }).catch((f) => console.error("[HZFaithfulFX] init failed:", f)));
101
- const M = p.current;
102
- if (M) {
103
- const f = i.camera;
104
- M.setCamera(f.projectionMatrix.elements, f.matrixWorldInverse.elements, f.position), z && H.current || M.render(d);
93
+ const o = performance.now(), c = V.current ? Math.min(0.05, (o - V.current) / 1e3) : 0.016;
94
+ V.current = o;
95
+ const l = i.gl, d = l.backend, A = (d == null ? void 0 : d.context) || ((p = (t = l.domElement) == null ? void 0 : t.getContext) == null ? void 0 : p.call(t, "webgpu"));
96
+ !h.current && !D.current && (d != null && d.device) && A && (D.current = !0, Q(
97
+ { device: d.device, context: A, canvas: l.domElement },
98
+ { getSceneDepth: T ? () => null : Y(l) }
99
+ ).then((m) => (h.current = m, q(m))).then((m) => {
100
+ R.current = m;
101
+ }).catch((m) => console.error("[HZFaithfulFX] init failed:", m)));
102
+ const E = h.current;
103
+ if (E) {
104
+ const m = i.camera;
105
+ E.setCamera(m.projectionMatrix.elements, m.matrixWorldInverse.elements, m.position), x && O.current || E.render(c);
105
106
  }
106
- }, x), null;
107
+ }, g), null;
107
108
  }
108
109
  const te = (
109
110
  /* glsl */
@@ -126,102 +127,102 @@ void main() {
126
127
  );
127
128
  function se({
128
129
  positionRef: r,
129
- duration: t = 1,
130
- width: v = 0.3,
130
+ duration: n = 1,
131
+ width: S = 0.3,
131
132
  color: e = [1, 1, 1],
132
133
  maxPoints: a = 256,
133
- minDistance: x = 0.05,
134
+ minDistance: g = 0.05,
134
135
  opacity: T = 1,
135
- blending: z = s.AdditiveBlending,
136
- visible: p = !0
136
+ blending: x = s.AdditiveBlending,
137
+ visible: h = !0
137
138
  }) {
138
- const { camera: S } = N(), D = I(null), L = I({
139
+ const { camera: R } = N(), D = I(null), V = I({
139
140
  positions: new Float32Array(a * 3),
140
141
  times: new Float32Array(a),
141
142
  head: 0,
142
143
  count: 0,
143
144
  lastPos: new s.Vector3(1 / 0, 1 / 0, 1 / 0),
144
145
  elapsed: 0
145
- }), { geometry: C, posAttr: V, colorAttr: H, indexBuf: B } = b(() => {
146
- const M = a * 2, f = new Float32Array(M * 3), n = new Float32Array(M * 4), R = new s.BufferGeometry(), q = new s.BufferAttribute(f, 3);
147
- q.setUsage(s.DynamicDrawUsage), R.setAttribute("position", q);
148
- const g = new s.BufferAttribute(n, 4);
149
- g.setUsage(s.DynamicDrawUsage), R.setAttribute("aColor", g);
150
- const A = (a - 1) * 6, l = new Uint32Array(A);
151
- for (let F = 0; F < a - 1; F++) {
152
- const u = F * 2, w = F * 6;
153
- l[w] = u, l[w + 1] = u + 1, l[w + 2] = u + 2, l[w + 3] = u + 1, l[w + 4] = u + 3, l[w + 5] = u + 2;
146
+ }), { geometry: C, posAttr: H, colorAttr: O, indexBuf: U } = b(() => {
147
+ const A = a * 2, E = new Float32Array(A * 3), t = new Float32Array(A * 4), p = new s.BufferGeometry(), m = new s.BufferAttribute(E, 3);
148
+ m.setUsage(s.DynamicDrawUsage), p.setAttribute("position", m);
149
+ const z = new s.BufferAttribute(t, 4);
150
+ z.setUsage(s.DynamicDrawUsage), p.setAttribute("aColor", z);
151
+ const M = (a - 1) * 6, f = new Uint32Array(M);
152
+ for (let y = 0; y < a - 1; y++) {
153
+ const u = y * 2, w = y * 6;
154
+ f[w] = u, f[w + 1] = u + 1, f[w + 2] = u + 2, f[w + 3] = u + 1, f[w + 4] = u + 3, f[w + 5] = u + 2;
154
155
  }
155
- const E = new s.BufferAttribute(l, 1);
156
- return R.setIndex(E), R.setDrawRange(0, 0), { geometry: R, posAttr: q, colorAttr: g, indexBuf: E };
157
- }, [a]), U = b(() => new s.ShaderMaterial({
156
+ const F = new s.BufferAttribute(f, 1);
157
+ return p.setIndex(F), p.setDrawRange(0, 0), { geometry: p, posAttr: m, colorAttr: z, indexBuf: F };
158
+ }, [a]), q = b(() => new s.ShaderMaterial({
158
159
  vertexShader: te,
159
160
  fragmentShader: ne,
160
161
  transparent: !0,
161
162
  depthWrite: !1,
162
163
  side: s.DoubleSide,
163
- blending: z
164
- }), [z]), i = b(() => new s.Vector3(), []), o = b(() => new s.Vector3(), []), d = b(() => new s.Vector3(), []), m = b(() => new s.Vector3(0, 1, 0), []), c = b(() => new s.Vector3(), []);
165
- return J((M, f) => {
164
+ blending: x
165
+ }), [x]), i = b(() => new s.Vector3(), []), o = b(() => new s.Vector3(), []), c = b(() => new s.Vector3(), []), l = b(() => new s.Vector3(0, 1, 0), []), d = b(() => new s.Vector3(), []);
166
+ return J((A, E) => {
166
167
  if (!D.current) return;
167
- const n = L.current;
168
- if (n.elapsed += f, !p) {
169
- n.count = 0, n.head = 0, n.lastPos.set(1 / 0, 1 / 0, 1 / 0), C.setDrawRange(0, 0);
168
+ const t = V.current;
169
+ if (t.elapsed += E, !h) {
170
+ t.count = 0, t.head = 0, t.lastPos.set(1 / 0, 1 / 0, 1 / 0), C.setDrawRange(0, 0);
170
171
  return;
171
172
  }
172
- const R = r.current;
173
- if (!R) return;
174
- if (n.lastPos.distanceTo(R) >= x) {
175
- const u = (n.head + n.count) % a;
176
- n.positions[u * 3] = R.x, n.positions[u * 3 + 1] = R.y, n.positions[u * 3 + 2] = R.z, n.times[u] = n.elapsed, n.count < a ? n.count++ : n.head = (n.head + 1) % a, n.lastPos.copy(R);
173
+ const p = r.current;
174
+ if (!p) return;
175
+ if (t.lastPos.distanceTo(p) >= g) {
176
+ const u = (t.head + t.count) % a;
177
+ t.positions[u * 3] = p.x, t.positions[u * 3 + 1] = p.y, t.positions[u * 3 + 2] = p.z, t.times[u] = t.elapsed, t.count < a ? t.count++ : t.head = (t.head + 1) % a, t.lastPos.copy(p);
177
178
  }
178
- for (; n.count > 0; ) {
179
- const u = n.head;
180
- if (n.elapsed - n.times[u] > t)
181
- n.head = (n.head + 1) % a, n.count--;
179
+ for (; t.count > 0; ) {
180
+ const u = t.head;
181
+ if (t.elapsed - t.times[u] > n)
182
+ t.head = (t.head + 1) % a, t.count--;
182
183
  else
183
184
  break;
184
185
  }
185
- if (n.count < 2) {
186
+ if (t.count < 2) {
186
187
  C.setDrawRange(0, 0);
187
188
  return;
188
189
  }
189
- const g = V.array, A = H.array;
190
- let l = null;
191
- const E = n.count;
192
- for (let u = 0; u < E; u++) {
193
- const w = (n.head + u) % a, P = n.positions[w * 3], W = n.positions[w * 3 + 1], j = n.positions[w * 3 + 2], Z = 1 - (n.elapsed - n.times[w]) / t;
194
- if (u < E - 1) {
195
- const _ = (n.head + u + 1) % a;
190
+ const z = H.array, M = O.array;
191
+ let f = null;
192
+ const F = t.count;
193
+ for (let u = 0; u < F; u++) {
194
+ const w = (t.head + u) % a, P = t.positions[w * 3], W = t.positions[w * 3 + 1], j = t.positions[w * 3 + 2], Z = 1 - (t.elapsed - t.times[w]) / n;
195
+ if (u < F - 1) {
196
+ const _ = (t.head + u + 1) % a;
196
197
  i.set(
197
- n.positions[_ * 3] - P,
198
- n.positions[_ * 3 + 1] - W,
199
- n.positions[_ * 3 + 2] - j
198
+ t.positions[_ * 3] - P,
199
+ t.positions[_ * 3 + 1] - W,
200
+ t.positions[_ * 3 + 2] - j
200
201
  );
201
202
  const k = i.length();
202
- k > 1e-6 ? i.divideScalar(k) : l && i.copy(l);
203
- } else l && i.copy(l);
204
- d.set(
205
- S.position.x - P,
206
- S.position.y - W,
207
- S.position.z - j
208
- ), o.crossVectors(i, d);
209
- let O = o.length();
210
- O < 1e-6 && (c.crossVectors(i, m), o.copy(c), O = o.length(), O < 1e-6 && (o.set(1, 0, 0), O = 1)), o.divideScalar(O);
211
- const y = v * Z, G = T * Z * Z, h = u * 2;
212
- g[h * 3] = P + o.x * y, g[h * 3 + 1] = W + o.y * y, g[h * 3 + 2] = j + o.z * y, g[(h + 1) * 3] = P - o.x * y, g[(h + 1) * 3 + 1] = W - o.y * y, g[(h + 1) * 3 + 2] = j - o.z * y, A[h * 4] = e[0], A[h * 4 + 1] = e[1], A[h * 4 + 2] = e[2], A[h * 4 + 3] = G, A[(h + 1) * 4] = e[0], A[(h + 1) * 4 + 1] = e[1], A[(h + 1) * 4 + 2] = e[2], A[(h + 1) * 4 + 3] = G, l = l || new s.Vector3(), l.copy(i);
203
+ k > 1e-6 ? i.divideScalar(k) : f && i.copy(f);
204
+ } else f && i.copy(f);
205
+ c.set(
206
+ R.position.x - P,
207
+ R.position.y - W,
208
+ R.position.z - j
209
+ ), o.crossVectors(i, c);
210
+ let B = o.length();
211
+ B < 1e-6 && (d.crossVectors(i, l), o.copy(d), B = o.length(), B < 1e-6 && (o.set(1, 0, 0), B = 1)), o.divideScalar(B);
212
+ const L = S * Z, G = T * Z * Z, v = u * 2;
213
+ z[v * 3] = P + o.x * L, z[v * 3 + 1] = W + o.y * L, z[v * 3 + 2] = j + o.z * L, z[(v + 1) * 3] = P - o.x * L, z[(v + 1) * 3 + 1] = W - o.y * L, z[(v + 1) * 3 + 2] = j - o.z * L, M[v * 4] = e[0], M[v * 4 + 1] = e[1], M[v * 4 + 2] = e[2], M[v * 4 + 3] = G, M[(v + 1) * 4] = e[0], M[(v + 1) * 4 + 1] = e[1], M[(v + 1) * 4 + 2] = e[2], M[(v + 1) * 4 + 3] = G, f = f || new s.Vector3(), f.copy(i);
213
214
  }
214
- const F = (E - 1) * 6;
215
- C.setDrawRange(0, F), V.needsUpdate = !0, H.needsUpdate = !0;
215
+ const y = (F - 1) * 6;
216
+ C.setDrawRange(0, y), H.needsUpdate = !0, O.needsUpdate = !0;
216
217
  }), /* @__PURE__ */ $(
217
218
  "mesh",
218
219
  {
219
220
  ref: D,
220
221
  geometry: C,
221
- material: U,
222
+ material: q,
222
223
  frustumCulled: !1,
223
224
  renderOrder: 101,
224
- visible: p
225
+ visible: h
225
226
  }
226
227
  );
227
228
  }
@@ -229,31 +230,31 @@ function K(r) {
229
230
  return Math.abs(Math.sin(r * 12.9898) * 43758.5453) % 1;
230
231
  }
231
232
  function re(r) {
232
- const t = Math.sin(r * 54321.67) * 43758.5453 % 1;
233
- return t < 0 ? t + 1 : t;
233
+ const n = Math.sin(r * 54321.67) * 43758.5453 % 1;
234
+ return n < 0 ? n + 1 : n;
234
235
  }
235
- function le(r, t, v, e) {
236
- if (v <= 0) return 0;
237
- const a = t / v;
238
- let x = r.particleSize ?? 0.5;
236
+ function le(r, n, S, e) {
237
+ if (S <= 0) return 0;
238
+ const a = n / S;
239
+ let g = r.particleSize ?? 0.5;
239
240
  if (r.randomSize) {
240
- const z = r.minSize ?? 0.1, p = r.maxSize ?? 0.5;
241
- x = z + (p - z) * re(v);
241
+ const x = r.minSize ?? 0.1, h = r.maxSize ?? 0.5;
242
+ g = x + (h - x) * re(S);
242
243
  }
243
244
  const T = Math.max(0.01, Math.min(10, r.sizeLifetimeSpeed ?? 1));
244
- if (r.fadeSizeEnabled && (x *= 1 - Math.pow(a, 1 / T)), r.increaseSizeEnabled && (x *= 1 + Math.pow(a, 1 / T)), r.pulseEnabled) {
245
- const z = r.pulseAmplitude ?? 0.5, p = r.pulseFrequency ?? 1, D = (r.pulsePhaseRandom ?? 0) * K(e) * Math.PI * 2;
246
- x *= 1 + z * Math.sin(t * p * Math.PI * 2 + D);
245
+ if (r.fadeSizeEnabled && (g *= 1 - Math.pow(a, 1 / T)), r.increaseSizeEnabled && (g *= 1 + Math.pow(a, 1 / T)), r.pulseEnabled) {
246
+ const x = r.pulseAmplitude ?? 0.5, h = r.pulseFrequency ?? 1, D = (r.pulsePhaseRandom ?? 0) * K(e) * Math.PI * 2;
247
+ g *= 1 + x * Math.sin(n * h * Math.PI * 2 + D);
247
248
  }
248
- return Math.max(0, x);
249
+ return Math.max(0, g);
249
250
  }
250
- function pe(r, t, v, e) {
251
- if (v <= 0) return 0;
251
+ function pe(r, n, S, e) {
252
+ if (S <= 0) return 0;
252
253
  let a = r.opacity ?? 1;
253
- const x = t / v;
254
- if (r.fadeEnabled && (a *= Math.max(0, 1 - x)), r.pulseEnabled && r.pulseOpacity) {
255
- const T = r.pulseAmplitude ?? 0.5, z = r.pulseFrequency ?? 1, S = (r.pulsePhaseRandom ?? 0) * K(e) * Math.PI * 2;
256
- a *= Math.max(0, 1 + T * Math.sin(t * z * Math.PI * 2 + S));
254
+ const g = n / S;
255
+ if (r.fadeEnabled && (a *= Math.max(0, 1 - g)), r.pulseEnabled && r.pulseOpacity) {
256
+ const T = r.pulseAmplitude ?? 0.5, x = r.pulseFrequency ?? 1, R = (r.pulsePhaseRandom ?? 0) * K(e) * Math.PI * 2;
257
+ a *= Math.max(0, 1 + T * Math.sin(n * x * Math.PI * 2 + R));
257
258
  }
258
259
  return Math.max(0, Math.min(1, a));
259
260
  }