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 +15 -8
- package/dist-lib/hz-particles-r3f.cjs +2 -2
- package/dist-lib/hz-particles-r3f.mjs +141 -140
- package/dist-lib/hz-particles.cjs +64 -22
- package/dist-lib/hz-particles.d.ts +16 -1
- package/dist-lib/hz-particles.mjs +766 -761
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -19,10 +19,9 @@ export function Scene() {
|
|
|
19
19
|
}
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
- **
|
|
24
|
-
- **
|
|
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
|
-
|
|
473
|
-
-
|
|
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(
|
|
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:
|
|
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,
|
|
8
|
-
if (
|
|
9
|
-
const
|
|
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:
|
|
16
|
-
minSize: e.minSize != null ? e.minSize *
|
|
17
|
-
maxSize: e.maxSize != null ? e.maxSize *
|
|
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) *
|
|
20
|
-
minSpeed: e.minSpeed != null ? e.minSpeed *
|
|
21
|
-
maxSpeed: e.maxSpeed != null ? e.maxSpeed *
|
|
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 *
|
|
24
|
-
outerLength: e.outerLength != null ? e.outerLength *
|
|
25
|
-
innerLength: e.innerLength != null ? e.innerLength *
|
|
26
|
-
outerRadius: e.outerRadius != null ? e.outerRadius *
|
|
27
|
-
innerRadius: e.innerRadius != null ? e.innerRadius *
|
|
28
|
-
squareSize: e.squareSize != null ? e.squareSize *
|
|
29
|
-
squareInnerSize: e.squareInnerSize != null ? e.squareInnerSize *
|
|
30
|
-
circleInnerRadius: e.circleInnerRadius != null ? e.circleInnerRadius *
|
|
31
|
-
circleOuterRadius: e.circleOuterRadius != null ? e.circleOuterRadius *
|
|
32
|
-
cylinderInnerRadius: e.cylinderInnerRadius != null ? e.cylinderInnerRadius *
|
|
33
|
-
cylinderOuterRadius: e.cylinderOuterRadius != null ? e.cylinderOuterRadius *
|
|
34
|
-
cylinderHeight: e.cylinderHeight != null ? e.cylinderHeight *
|
|
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) *
|
|
37
|
-
emissionTrailDuration: (e.emissionTrailDuration ?? 1) *
|
|
38
|
-
emissionTrailMinDistance: e.emissionTrailMinDistance != null ? e.emissionTrailMinDistance *
|
|
39
|
-
emissionTrailShapeAmplitude: e.emissionTrailShapeAmplitude != null ? e.emissionTrailShapeAmplitude *
|
|
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:
|
|
46
|
-
position:
|
|
45
|
+
positionRef: n,
|
|
46
|
+
position: S = [0, 0, 0],
|
|
47
47
|
scale: e = 1,
|
|
48
48
|
active: a = !0,
|
|
49
|
-
renderPriority:
|
|
49
|
+
renderPriority: g = 1,
|
|
50
50
|
noOcclusion: T = !1,
|
|
51
|
-
respectReducedMotion:
|
|
51
|
+
respectReducedMotion: x = !0
|
|
52
52
|
}) {
|
|
53
|
-
const
|
|
53
|
+
const h = I(null), R = I(null), D = I(!1), V = I(0), C = I(a);
|
|
54
54
|
C.current = a;
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
const
|
|
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
|
-
),
|
|
60
|
+
), q = (i) => n ? i.addMovingEmitter(U, {
|
|
61
61
|
getPosition: () => {
|
|
62
|
-
const o =
|
|
62
|
+
const o = n.current;
|
|
63
63
|
return C.current && o ? [o.x, o.y, o.z] : null;
|
|
64
64
|
}
|
|
65
|
-
}) : i.addEmitter(
|
|
65
|
+
}) : i.addEmitter(U, H.current);
|
|
66
66
|
return X(() => {
|
|
67
|
-
var
|
|
68
|
-
const i =
|
|
67
|
+
var c, l;
|
|
68
|
+
const i = h.current;
|
|
69
69
|
if (!i) return;
|
|
70
70
|
let o = !1;
|
|
71
|
-
return (
|
|
72
|
-
var
|
|
73
|
-
o ? (
|
|
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
|
-
}, [
|
|
78
|
-
var
|
|
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
|
-
|
|
81
|
+
O.current = i.matches;
|
|
82
82
|
};
|
|
83
|
-
return o(), (
|
|
84
|
-
var
|
|
85
|
-
return (
|
|
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,
|
|
89
|
-
(o = (i =
|
|
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(),
|
|
93
|
-
|
|
94
|
-
const
|
|
95
|
-
!
|
|
96
|
-
{ device:
|
|
97
|
-
{ getSceneDepth: T ? () => null : Y(
|
|
98
|
-
).then((
|
|
99
|
-
|
|
100
|
-
}).catch((
|
|
101
|
-
const
|
|
102
|
-
if (
|
|
103
|
-
const
|
|
104
|
-
|
|
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
|
-
},
|
|
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:
|
|
130
|
-
width:
|
|
130
|
+
duration: n = 1,
|
|
131
|
+
width: S = 0.3,
|
|
131
132
|
color: e = [1, 1, 1],
|
|
132
133
|
maxPoints: a = 256,
|
|
133
|
-
minDistance:
|
|
134
|
+
minDistance: g = 0.05,
|
|
134
135
|
opacity: T = 1,
|
|
135
|
-
blending:
|
|
136
|
-
visible:
|
|
136
|
+
blending: x = s.AdditiveBlending,
|
|
137
|
+
visible: h = !0
|
|
137
138
|
}) {
|
|
138
|
-
const { camera:
|
|
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:
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
const
|
|
151
|
-
for (let
|
|
152
|
-
const u =
|
|
153
|
-
|
|
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
|
|
156
|
-
return
|
|
157
|
-
}, [a]),
|
|
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:
|
|
164
|
-
}), [
|
|
165
|
-
return J((
|
|
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
|
|
168
|
-
if (
|
|
169
|
-
|
|
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
|
|
173
|
-
if (!
|
|
174
|
-
if (
|
|
175
|
-
const u = (
|
|
176
|
-
|
|
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 (;
|
|
179
|
-
const u =
|
|
180
|
-
if (
|
|
181
|
-
|
|
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 (
|
|
186
|
+
if (t.count < 2) {
|
|
186
187
|
C.setDrawRange(0, 0);
|
|
187
188
|
return;
|
|
188
189
|
}
|
|
189
|
-
const
|
|
190
|
-
let
|
|
191
|
-
const
|
|
192
|
-
for (let u = 0; u <
|
|
193
|
-
const w = (
|
|
194
|
-
if (u <
|
|
195
|
-
const _ = (
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
|
|
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) :
|
|
203
|
-
} else
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
), o.crossVectors(i,
|
|
209
|
-
let
|
|
210
|
-
|
|
211
|
-
const
|
|
212
|
-
|
|
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
|
|
215
|
-
C.setDrawRange(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:
|
|
222
|
+
material: q,
|
|
222
223
|
frustumCulled: !1,
|
|
223
224
|
renderOrder: 101,
|
|
224
|
-
visible:
|
|
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
|
|
233
|
-
return
|
|
233
|
+
const n = Math.sin(r * 54321.67) * 43758.5453 % 1;
|
|
234
|
+
return n < 0 ? n + 1 : n;
|
|
234
235
|
}
|
|
235
|
-
function le(r,
|
|
236
|
-
if (
|
|
237
|
-
const a =
|
|
238
|
-
let
|
|
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
|
|
241
|
-
|
|
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 && (
|
|
245
|
-
const
|
|
246
|
-
|
|
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,
|
|
249
|
+
return Math.max(0, g);
|
|
249
250
|
}
|
|
250
|
-
function pe(r,
|
|
251
|
-
if (
|
|
251
|
+
function pe(r, n, S, e) {
|
|
252
|
+
if (S <= 0) return 0;
|
|
252
253
|
let a = r.opacity ?? 1;
|
|
253
|
-
const
|
|
254
|
-
if (r.fadeEnabled && (a *= Math.max(0, 1 -
|
|
255
|
-
const T = r.pulseAmplitude ?? 0.5,
|
|
256
|
-
a *= Math.max(0, 1 + T * Math.sin(
|
|
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
|
}
|