@@ -19,8 +19,6 @@ if (typeof window !== 'undefined') {
19
19
});
20
20
}
21
21
22
-
23
-
24
22
interface BeamsProps {
25
23
beamWidth? : number ;
26
24
beamHeight? : number ;
@@ -42,7 +40,7 @@ const props = withDefaults(defineProps<BeamsProps>(), {
42
40
noiseIntensity: 1.75 ,
43
41
scale: 0.2 ,
44
42
rotation: 30 ,
45
- isMobile: false
43
+ isMobile: false ,
46
44
});
47
45
48
46
const containerRef = ref <HTMLDivElement | null >(null );
@@ -69,7 +67,7 @@ interface ExtendMaterialConfig {
69
67
fragmentHeader? : string ;
70
68
material? : any ;
71
69
}
72
-
70
+ // @ts-ignore
73
71
type ShaderWithDefines = THREE .ShaderLibShader & {
74
72
defines? : Record <string , string | number | boolean >;
75
73
};
@@ -158,21 +156,25 @@ float cnoise(vec3 P){
158
156
return 2.2 * n_xyz;
159
157
}
160
158
` ;
161
-
159
+ // @ts-ignore
162
160
function extendMaterial<T extends THREE .Material = THREE .Material >(
161
+ // @ts-ignore
163
162
BaseMaterial : new (params ? : THREE .MaterialParameters ) => T ,
164
- cfg : ExtendMaterialConfig
163
+ cfg : ExtendMaterialConfig ,
164
+ // @ts-ignore
165
165
): THREE .ShaderMaterial {
166
166
const physical = THREE .ShaderLib .physical as ShaderWithDefines ;
167
167
const { vertexShader : baseVert, fragmentShader : baseFrag, uniforms : baseUniforms } = physical ;
168
168
const baseDefines = physical .defines ?? {};
169
-
169
+ // @ts-ignore
170
170
const uniforms: Record <string , THREE .IUniform > = THREE .UniformsUtils .clone (baseUniforms );
171
171
172
172
const defaults = new BaseMaterial (cfg .material || {}) as T & {
173
+ // @ts-ignore
173
174
color? : THREE .Color ;
174
175
roughness? : number ;
175
176
metalness? : number ;
177
+ // @ts-ignore
176
178
envMap? : THREE .Texture ;
177
179
envMapIntensity? : number ;
178
180
};
@@ -183,19 +185,29 @@ function extendMaterial<T extends THREE.Material = THREE.Material>(
183
185
if (' envMap' in defaults ) uniforms .envMap .value = defaults .envMap ;
184
186
if (' envMapIntensity' in defaults ) uniforms .envMapIntensity .value = defaults .envMapIntensity ;
185
187
188
+ // @ts-ignore
186
189
Object .entries (cfg .uniforms ?? {}).forEach (([key , u ]) => {
187
190
uniforms [key ] =
188
191
u !== null && typeof u === ' object' && ' value' in u
189
- ? (u as THREE .IUniform <unknown >)
190
- : (() => { const uniform: THREE .IUniform <unknown > = { value: u }; return uniform ; })();
192
+ ? // @ts-ignore
193
+ (u as THREE .IUniform <unknown >)
194
+ : (() => {
195
+ // @ts-ignore
196
+
197
+ const uniform: THREE .IUniform <unknown > = { value: u };
198
+ return uniform ;
199
+ })();
191
200
});
192
201
193
202
let vert = ` ${cfg .header }\n ${cfg .vertexHeader ?? ' ' }\n ${baseVert } ` ;
194
203
let frag = ` ${cfg .header }\n ${cfg .fragmentHeader ?? ' ' }\n ${baseFrag } ` ;
204
+ // @ts-ignore
195
205
196
206
for (const [inc, code] of Object .entries (cfg .vertex ?? {})) {
197
207
vert = vert .replace (inc , ` ${inc }\n ${code } ` );
198
208
}
209
+ // @ts-ignore
210
+
199
211
for (const [inc, code] of Object .entries (cfg .fragment ?? {})) {
200
212
frag = frag .replace (inc , ` ${inc }\n ${code } ` );
201
213
}
@@ -206,7 +218,7 @@ function extendMaterial<T extends THREE.Material = THREE.Material>(
206
218
vertexShader: vert ,
207
219
fragmentShader: frag ,
208
220
lights: true ,
209
- fog: !! cfg .material ?.fog
221
+ fog: !! cfg .material ?.fog ,
210
222
});
211
223
212
224
return mat ;
@@ -217,7 +229,8 @@ function createStackedPlanesBufferGeometry(
217
229
width : number ,
218
230
height : number ,
219
231
spacing : number ,
220
- heightSegments : number
232
+ heightSegments : number ,
233
+ // @ts-ignore
221
234
): THREE .BufferGeometry {
222
235
const geometry = new THREE .BufferGeometry ();
223
236
const numVertices = n * (heightSegments + 1 ) * 2 ;
@@ -247,12 +260,12 @@ function createStackedPlanesBufferGeometry(
247
260
uvs .set ([uvXOffset , uvY + uvYOffset , uvXOffset + 1 , uvY + uvYOffset ], uvOffset );
248
261
249
262
if (j < heightSegments ) {
250
- const a = vertexOffset ;
251
- const b = vertexOffset + 1 ;
252
- const c = vertexOffset + 2 ;
253
- const d = vertexOffset + 3 ;
254
- indices .set ([a , b , c , c , b , d ], indexOffset );
255
- indexOffset += 6 ;
263
+ const a = vertexOffset ;
264
+ const b = vertexOffset + 1 ;
265
+ const c = vertexOffset + 2 ;
266
+ const d = vertexOffset + 3 ;
267
+ indices .set ([a , b , c , c , b , d ], indexOffset );
268
+ indexOffset += 6 ;
256
269
}
257
270
vertexOffset += 2 ;
258
271
uvOffset += 4 ;
@@ -298,14 +311,15 @@ const beamMaterial = computed(() =>
298
311
return normalize(cross(tangentZ, tangentX));
299
312
} ` ,
300
313
fragmentHeader: ' ' ,
314
+ // @ts-ignore
301
315
vertex: {
302
316
' #include <begin_vertex>' : ` transformed.z += getPos(transformed.xyz); ` ,
303
- ' #include <beginnormal_vertex>' : ` objectNormal = getNormal(position.xyz); `
317
+ ' #include <beginnormal_vertex>' : ` objectNormal = getNormal(position.xyz); ` ,
304
318
},
305
319
fragment: {
306
320
' #include <dithering_fragment>' : `
307
321
float randomNoise = noise(gl_FragCoord.xy);
308
- gl_FragColor.rgb -= randomNoise / 15. * uNoiseIntensity; `
322
+ gl_FragColor.rgb -= randomNoise / 15. * uNoiseIntensity; ` ,
309
323
},
310
324
material: { fog: true },
311
325
uniforms: {
@@ -316,9 +330,9 @@ const beamMaterial = computed(() =>
316
330
uSpeed: { shared: true , mixed: true , linked: true , value: props .speed },
317
331
envMapIntensity: 10 ,
318
332
uNoiseIntensity: props .noiseIntensity ,
319
- uScale: props .scale
320
- }
321
- })
333
+ uScale: props .scale ,
334
+ },
335
+ }),
322
336
);
323
337
324
338
const initThreeJS = () => {
@@ -349,6 +363,7 @@ const initThreeJS = () => {
349
363
350
364
directionalLight = new THREE .DirectionalLight (new THREE .Color (props .lightColor ), 1 );
351
365
directionalLight .position .set (0 , 3 , 10 );
366
+ // @ts-ignore
352
367
const shadowCamera = directionalLight .shadow .camera as THREE .OrthographicCamera ;
353
368
shadowCamera .top = 24 ;
354
369
shadowCamera .bottom = - 24 ;
@@ -450,12 +465,12 @@ watch(
450
465
props .speed ,
451
466
props .noiseIntensity ,
452
467
props .scale ,
453
- props .rotation
468
+ props .rotation ,
454
469
],
455
470
() => {
456
471
initThreeJS ();
457
472
},
458
- { deep: true }
473
+ { deep: true },
459
474
);
460
475
461
476
// 监听 isMobile 变化
@@ -464,7 +479,7 @@ watch(
464
479
() => {
465
480
controlAnimation ();
466
481
},
467
- { immediate: true }
482
+ { immediate: true },
468
483
);
469
484
470
485
onMounted (async () => {
@@ -493,20 +508,21 @@ onMounted(async () => {
493
508
}
494
509
495
510
// 设置滚动时的透明度变化:顶部时不透明度为1,向下滚动时降低到0.1
496
- gsap .fromTo (" .beams-container" ,
511
+ gsap .fromTo (
512
+ ' .beams-container' ,
497
513
{
498
514
opacity: 1 , // 初始状态:完全不透明
499
515
},
500
516
{
501
517
opacity: 0.1 , // 结束状态:几乎透明
502
518
scrollTrigger: {
503
- trigger: " body" , // 以整个页面作为触发器
504
- start: " top top" , // 从页面顶部开始
505
- end: " bottom top" , // 到页面底部结束
519
+ trigger: ' body' , // 以整个页面作为触发器
520
+ start: ' top top' , // 从页面顶部开始
521
+ end: ' bottom top' , // 到页面底部结束
506
522
scrub: true , // 跟随滚动
507
523
invalidateOnRefresh: true , // 刷新时重新计算
508
- }
509
- }
524
+ },
525
+ },
510
526
);
511
527
}
512
528
});
@@ -527,4 +543,3 @@ onUnmounted(() => {
527
543
z-index : -1 ; /* 确保在其他内容后面 */
528
544
}
529
545
</style >
530
-
0 commit comments