|
1 |
| -import React, { useRef, useState } from 'react'; |
| 1 | +import React, { useRef } from 'react'; |
2 | 2 | import * as THREE from 'three';
|
3 | 3 | import { useFrame } from '@react-three/fiber';
|
4 | 4 | import { lerp } from 'three/src/math/MathUtils';
|
5 | 5 |
|
6 | 6 | type Props = {
|
7 | 7 | radius: number;
|
| 8 | + index: number; |
8 | 9 | centerPos: number[];
|
9 |
| - mean: number; |
10 |
| - musicInput: number; |
11 | 10 | position: THREE.Vector3;
|
12 | 11 | theta: number;
|
13 | 12 | color: string;
|
| 13 | + meanRef: React.MutableRefObject<number>; |
| 14 | + dataArrayRef: React.MutableRefObject<Uint8Array | null>; |
14 | 15 | };
|
15 | 16 |
|
16 |
| -export default function Bar({ radius, centerPos, mean, musicInput, position, theta, color }: Props) { |
| 17 | +export default function Bar({ radius, index, centerPos, position, theta, color, meanRef, dataArrayRef }: Props) { |
17 | 18 | const barRef = useRef<THREE.Mesh>(null!);
|
18 |
| - const [height, setHeight] = useState(0); |
19 |
| - const [angle, setAngle] = useState<any>(theta); |
20 |
| - |
| 19 | + const heightRef = useRef(0); |
| 20 | + const angleRef = useRef(theta); |
21 | 21 | const radian = Math.PI / 180;
|
22 | 22 |
|
23 |
| - useFrame((_, delta) => { |
24 |
| - if (musicInput > height) { |
25 |
| - setHeight(musicInput); |
| 23 | + useFrame((_) => { |
| 24 | + if (!dataArrayRef.current) return; |
| 25 | + const mean = meanRef.current - 1; |
| 26 | + const frequency = dataArrayRef.current?.[index] / 128 - 1; |
| 27 | + const height = heightRef.current; |
| 28 | + |
| 29 | + if (frequency > height) { |
| 30 | + heightRef.current = frequency; |
26 | 31 | } else {
|
27 |
| - setHeight(height - height * 0.2); |
| 32 | + heightRef.current = height - height * 0.2; |
28 | 33 | }
|
29 |
| - |
30 |
| - const na = (angle + radian) % 360; |
31 |
| - setAngle(na); |
| 34 | + angleRef.current = (angleRef.current + radian) % 360; |
32 | 35 | const power = mean < 0 ? 0 : Math.round(mean * 10000) / 10000;
|
33 |
| - const nx = centerPos[0] + (radius + power * 500) * Math.cos(angle); |
34 |
| - const ny = centerPos[1] + height * height * 1200; |
35 |
| - const nz = centerPos[2] + (radius + power * 500) * Math.sin(angle); |
| 36 | + const nx = centerPos[0] + (radius + power * 500) * Math.cos(angleRef.current); |
| 37 | + const ny = centerPos[1] + heightRef.current * heightRef.current * 1200; |
| 38 | + const nz = centerPos[2] + (radius + power * 500) * Math.sin(angleRef.current); |
36 | 39 |
|
37 | 40 | barRef.current.position.x = lerp(barRef.current.position.x, nx, 0.02);
|
38 | 41 | barRef.current.position.y = lerp(barRef.current.position.y, ny, 0.03);
|
|
0 commit comments