Skip to content

Commit 38d2705

Browse files
committed
opt(LFO): add optimize hook to generate data
1 parent 517ccbc commit 38d2705

2 files changed

Lines changed: 19 additions & 30 deletions

File tree

  • example/src/components/visualizaion
  • packages/components/visualization/LFO

example/src/components/visualizaion/EchoLFO.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const EchoLFO = () => {
2929

3030
React.useEffect(() => {
3131
autoFilter.current?.set({
32-
frequency: frequency * 10,
32+
frequency: frequency,
3333
})
3434

3535
osc.current?.set({

packages/components/visualization/LFO/LFO.tsx

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as d3 from 'd3'
2-
import { forwardRef, useEffect, useImperativeHandle, useRef } from 'react'
2+
import { forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react'
33
import { useResizeObserver } from '../../../lib/hooks/useResizeObserver'
44
import { cn, validValue } from '../../../lib/utils'
55
import { LFOProps, LFORef } from './types'
@@ -34,7 +34,6 @@ export const LFO = forwardRef<LFORef, LFOProps>((props, ref) => {
3434
const LFORef = useRef<LFORef | null>(null)
3535
const xScale = useRef<d3.ScaleLinear<number, number> | null>(null)
3636
const yScale = useRef<d3.ScaleLinear<number, number> | null>(null)
37-
const delayInSeconds = delay / 1000
3837

3938
useImperativeHandle(ref, () => LFORef.current as LFORef)
4039

@@ -86,6 +85,7 @@ export const LFO = forwardRef<LFORef, LFOProps>((props, ref) => {
8685
}
8786

8887
// Draw the delay line
88+
const delayInSeconds = delay / 1000
8989
if (delay > 0) {
9090
svg
9191
.append('circle')
@@ -107,13 +107,13 @@ export const LFO = forwardRef<LFORef, LFOProps>((props, ref) => {
107107
let data: DataItem[] = []
108108
switch (type) {
109109
case 'sine':
110-
data = generateSineWaveData(svg)
110+
data = generateSineWaveData
111111
break
112112
case 'square':
113-
data = generateSquareWaveData(svg)
113+
data = generateSquareWaveData
114114
break
115115
case 'triangle':
116-
data = generateTriangleWaveData(svg)
116+
data = generateTriangleWaveData
117117
break
118118
default:
119119
break
@@ -134,46 +134,37 @@ export const LFO = forwardRef<LFORef, LFOProps>((props, ref) => {
134134
.attr('transform', `translate(${delayInSeconds * width}, 0)`)
135135
}
136136

137-
const generateSineWaveData = (
138-
svg: d3.Selection<d3.BaseType, unknown, null, undefined>,
139-
): { x: number; y: number }[] => {
140-
if (type !== 'sine' || !svg) return []
137+
const generateSineWaveData = useMemo((): { x: number; y: number }[] => {
138+
if (type !== 'sine') return []
141139

142-
const data = d3.range(0, 1, 0.001).map((x) => {
140+
return d3.range(0, 1, 0.001).map((x) => {
143141
const adjustedX = x * 2 * Math.PI * frequency
144142
const y = Math.sin(adjustedX) * amplitude * 0.5 + 0.5
145143
return { x, y }
146144
})
145+
}, [type, frequency, amplitude])
147146

148-
return data
149-
}
150-
151-
const generateSquareWaveData = (
152-
svg: d3.Selection<d3.BaseType, unknown, null, undefined>,
153-
): DataItem[] => {
154-
if (type !== 'square' || !svg) return []
147+
const generateSquareWaveData = useMemo((): DataItem[] => {
148+
if (type !== 'square') return []
155149

156150
const centerY = 0.5
157151
const halfHeight = centerY * amplitude
158-
const data = [{ x: 0, y: centerY }].concat(
152+
153+
return [{ x: 0, y: centerY }].concat(
159154
d3.range(0, 1, 0.001).map((x) => {
160155
const adjustedX = x * 2 * Math.PI * frequency
161156
const y =
162157
Math.floor(adjustedX / Math.PI) % 2 === 0 ? centerY + halfHeight : centerY - halfHeight
163158
return { x, y }
164159
}),
165160
)
161+
}, [type, frequency, amplitude])
166162

167-
return data
168-
}
169-
170-
const generateTriangleWaveData = (
171-
svg: d3.Selection<d3.BaseType, unknown, null, undefined>,
172-
): DataItem[] => {
173-
if (type !== 'triangle' || !svg) return []
163+
const generateTriangleWaveData = useMemo((): DataItem[] => {
164+
if (type !== 'triangle') return []
174165

175166
const centerY = 0.5
176-
const data = d3.range(0, 1, 0.001).map((x) => {
167+
return d3.range(0, 1, 0.001).map((x) => {
177168
// Adjust the phase so that the waveform starts in the middle of the rising segment
178169
// and ensure that the starting point is at the center of the Y-axis
179170
// By mapping the x value to the corresponding position in a cycle,
@@ -187,9 +178,7 @@ export const LFO = forwardRef<LFORef, LFOProps>((props, ref) => {
187178
y = y - amplitude / 2 + centerY
188179
return { x, y }
189180
})
190-
191-
return data
192-
}
181+
}, [type, frequency, amplitude])
193182

194183
const { base, svg } = useStyle()
195184

0 commit comments

Comments
 (0)