11import * as d3 from 'd3'
2- import { forwardRef , useEffect , useImperativeHandle , useRef } from 'react'
2+ import { forwardRef , useEffect , useImperativeHandle , useMemo , useRef } from 'react'
33import { useResizeObserver } from '../../../lib/hooks/useResizeObserver'
44import { cn , validValue } from '../../../lib/utils'
55import { 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