-
Notifications
You must be signed in to change notification settings - Fork 15
/
Sparks.js
71 lines (64 loc) · 1.99 KB
/
Sparks.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import * as THREE from 'three';
import React, { useRef, useMemo } from 'react';
import { useFrame } from '@react-three/fiber';
import Random from 'canvas-sketch-util/random';
const radiusVariance = () => Random.range(0.2, 1);
function SparkLine({ curve, width, color, speed }) {
const material = useRef();
useFrame(() => {
material.current.uniforms.dashOffset.value -= speed;
});
return (
<mesh>
<meshLine attach="geometry" points={curve} />
<meshLineMaterial
ref={material}
transparent
depthTest={false}
lineWidth={width}
color={color}
dashArray={0.1}
dashRatio={0.95}
/>
</mesh>
);
}
export function Sparks({ count, colors, radius = 10 }) {
const lines = useMemo(
() =>
new Array(count).fill().map((_, index) => {
const pos = new THREE.Vector3(
Math.sin(0) * radius * radiusVariance(),
Math.cos(0) * radius * radiusVariance(),
Math.sin(0) * Math.cos(0) * radius * radiusVariance()
);
const points = new Array(30).fill().map((_, index) => {
const angle = (index / 20) * Math.PI * 2;
return pos
.add(
new THREE.Vector3(
Math.sin(angle) * radius * radiusVariance(),
Math.cos(angle) * radius * radiusVariance(),
Math.sin(angle) * Math.cos(angle) * radius * radiusVariance()
)
)
.clone();
});
const curve = new THREE.CatmullRomCurve3(points).getPoints(1000);
return {
color: colors[parseInt(colors.length * Math.random(), 10)],
width: Math.max(0.1, (0.2 * index) / 10),
speed: Math.max(0.001, 0.004 * Math.random()),
curve,
};
}),
[count, colors, radius]
);
return (
<group position={[-radius * 2, -radius, -10]} scale={[1, 1.3, 1]}>
{lines.map((props, index) => (
<SparkLine key={index} {...props} />
))}
</group>
);
}