11import React , { useRef , useState , useEffect } from 'react' ;
2- import { useTheme } from '@material-ui/core/styles' ;
2+ import { useTheme , styled } from '@material-ui/core/styles' ;
33import { ipcRenderer } from 'electron' ;
44import { PlayArrow , Stop } from '@material-ui/icons' ;
5- import { Button , MenuItem , TextField , Typography , Paper } from '@material-ui/core' ;
5+ import { Button , MenuItem , TextField , Typography , Paper , Box , Slider } from '@material-ui/core' ;
66import ColorPicker from './ColorPicker' ;
77import useStore from '../store/store' ;
88import Effect , { effects } from '../effects' ;
99import Toggle from './Toggle' ;
1010import useVisualizerStyles from './Visualizer.styles' ;
1111
12- export default function VisualDemo ( {
12+
13+ const YZslider = styled ( Slider ) ( {
14+ color : 'white' ,
15+ height : 8 ,
16+ '& .MuiSlider-track' : {
17+ border : 'none' ,
18+ width : 0 ,
19+ } ,
20+ '& .MuiSlider-rail' : {
21+ border : 'none' ,
22+ width : 0 ,
23+ } ,
24+ '& .MuiSlider-thumb' : {
25+ height : 20 ,
26+ width : 20 ,
27+ marginLeft : - 9 ,
28+ backgroundColor : '#fff0' ,
29+ '&:focus, &:hover, &.Mui-active, &.Mui-focusVisible' : {
30+ boxShadow : 'inherit' ,
31+ } ,
32+ '&:before' : {
33+ content : '"⬍"' ,
34+ position : 'absolute' ,
35+ left : 0 ,
36+ top : - 8 ,
37+ width : 20 ,
38+ height : 20 ,
39+ fontSize : 30 ,
40+ color : '#444' ,
41+ } ,
42+ '&:after' : {
43+ top : 12 ,
44+ left : - 20 ,
45+ content : "" ,
46+ position : 'absolute' ,
47+ height : 10 ,
48+ width : '100vw' ,
49+ borderTop : '1px dashed #444' ,
50+ borderRadius : 0 ,
51+ right : 'unset' ,
52+ bottom : 'unset' ,
53+ } ,
54+ '&:hover' : {
55+ '&:after' : {
56+ borderColor : '#aaa'
57+ } ,
58+ '&:before' : {
59+ color : '#aaa'
60+ }
61+ }
62+ } ,
63+ } ) ;
64+
65+
66+ export default function Visualizer ( {
1367 frequencyBandArray,
1468 getFrequencyData,
1569 initializeAudioAnalyser,
@@ -33,9 +87,12 @@ export default function VisualDemo({
3387 const setBgColor = useStore ( state => state . setBgColor )
3488
3589 const [ activeFb , setActiveFb ] = useState ( - 1 )
90+ const [ activeRightFb , setActiveRightFb ] = useState ( - 1 )
3691 const [ playing , setPlaying ] = useState ( false )
3792 const [ flipped , setFlipped ] = useState ( false )
3893 const [ effect , setEffect ] = useState ( "BladePower" )
94+ const [ volume , setVolume ] = useState ( 0 )
95+ const [ innerVolume , setInnerVolume ] = useState ( 0 )
3996
4097 const settingColor = ( clr ) => {
4198 setColor ( clr )
@@ -49,21 +106,31 @@ export default function VisualDemo({
49106 refresh ( )
50107 }
51108 }
109+
52110 const settingFlipped = ( flp ) => {
53111 setFlipped ( flp )
54112 if ( playing ) {
55113 refresh ( )
56114 }
57115 }
58-
59- useEffect ( ( ) => {
116+ const settingActiveFb = ( act ) => {
117+ setActiveFb ( act )
60118 if ( playing ) {
61- setTimeout ( ( ) => {
62- initializeAudioAnalyser ( )
63- requestAnimationFrame ( runSpectrum )
64- } , 100 )
119+ refresh ( )
120+ }
121+ }
122+ const settingActiveRightFb = ( act ) => {
123+ setActiveRightFb ( act )
124+ if ( playing ) {
125+ refresh ( )
65126 }
66- } , [ color , bgColor , flipped ] )
127+ }
128+ const settingVolume = ( ) => {
129+ setInnerVolume ( volume )
130+ if ( playing ) {
131+ refresh ( )
132+ }
133+ }
67134
68135 function adjustFreqBandStyle ( newAmplitudeData ) {
69136 if ( audioContext . state === 'closed' ) {
@@ -90,7 +157,8 @@ export default function VisualDemo({
90157 pixel_count : device . pixel_count ,
91158 color,
92159 bgColor,
93- activeFb
160+ activeFb,
161+ volume : volume
94162 }
95163 } )
96164 // console.log(ledData)
@@ -102,8 +170,6 @@ export default function VisualDemo({
102170 }
103171 } ;
104172
105-
106-
107173 function runSpectrum ( ) {
108174 if ( audioContext . state === 'running' ) {
109175 getFrequencyData ( adjustFreqBandStyle )
@@ -117,6 +183,7 @@ export default function VisualDemo({
117183 initializeAudioAnalyser ( )
118184 requestAnimationFrame ( runSpectrum )
119185 }
186+
120187 function handleStopButtonClick ( ) {
121188 setPlaying ( false )
122189 ipcRenderer . send ( 'UDP-stop' )
@@ -133,15 +200,53 @@ export default function VisualDemo({
133200
134201 function handleFreqBandClick ( num ) {
135202 if ( activeFb === num ) {
136- setActiveFb ( - 1 )
203+ settingActiveFb ( - 1 )
204+ return
205+ }
206+ if ( activeRightFb > - 1 ) {
207+ if ( num > activeRightFb ) {
208+ settingActiveRightFb ( - 1 )
209+ settingActiveFb ( num )
210+ return
211+ }
212+ settingActiveFb ( num )
137213 } else {
138- setActiveFb ( num )
139- if ( playing ) {
140- handleStopButtonClick ( )
214+ settingActiveFb ( num )
215+ }
216+ }
217+
218+ function handleFreqBandRightClick ( num ) {
219+ if ( activeRightFb === num ) {
220+ settingActiveRightFb ( - 1 )
221+ return
222+ }
223+ if ( activeFb > - 1 ) {
224+ if ( activeFb > num ) {
225+ settingActiveRightFb ( num )
226+ settingActiveFb ( - 1 )
227+ return
141228 }
229+ settingActiveRightFb ( num )
230+ } else {
231+ settingActiveRightFb ( num )
142232 }
143233 }
144234
235+ function preventHorizontalKeyboardNavigation ( event ) {
236+ if ( event . key === 'ArrowLeft' || event . key === 'ArrowRight' ) {
237+ event . preventDefault ( ) ;
238+ }
239+ }
240+
241+ useEffect ( ( ) => {
242+ if ( playing ) {
243+ setTimeout ( ( ) => {
244+ initializeAudioAnalyser ( )
245+ requestAnimationFrame ( runSpectrum )
246+ } , 100 )
247+ }
248+ } , [ color , bgColor , flipped , innerVolume , activeFb , activeRightFb ] )
249+
145250 useEffect ( ( ) => {
146251 navigator . mediaDevices . enumerateDevices ( )
147252 . then ( function ( adevices ) {
@@ -212,26 +317,54 @@ export default function VisualDemo({
212317 < Toggle label = "Flip" value = { flipped } setValue = { settingFlipped } />
213318 </ div >
214319 </ div >
320+ < Box sx = { { height : 255 , position : 'absolute' , zIndex : 1 , pointerEvents : 'none' , top : 88 , left : 0 , right : 0 , paddingLeft : 16 , background : `linear-gradient(to top, #000c, #000c ${ volume } %, transparent ${ volume + 1 } %)` } } />
321+ < Box sx = { { height : 255 , position : 'absolute' , zIndex : 2 , top : 88 , left : 0 , paddingLeft : 16 } } >
322+ < YZslider
323+ orientation = "vertical"
324+ value = { volume }
325+ color = "inherit"
326+ onChange = { ( e , v ) => setVolume ( v ) }
327+ onChangeCommitted = { settingVolume }
328+ min = { 0 }
329+ max = { 100 }
330+ aria-label = "Temperature"
331+ onKeyDown = { preventHorizontalKeyboardNavigation }
332+ />
333+ </ Box >
215334 { ( activeFb === - 1 && effect === 'BladePower' ) &&
216335 < Typography variant = { "h3" } className = { classes . effectNote } >
217336 Please select a band at the bottom
218337 </ Typography >
219338 }
220- < div className = { `${ classes . flexContainer } ${ activeFb > - 1 ? 'selection-active' : '' } ` } >
339+ < div className = { `${ classes . flexContainer } ${ ( activeFb > - 1 || activeRightFb > - 1 ) ? 'selection-active' : '' } ` } >
221340 { frequencyBandArray . map ( ( num ) =>
222341 < div style = { { position : 'relative' } } key = { num } >
223342 < Paper
224- className = { `${ classes . frequencyBands } ${ activeFb === num ? 'selected' : '' } ` }
225- style = { { backgroundColor : `rgb(${ color . r } , ${ color . g } , ${ color . b } )` , padding : `calc(100vw / ${ ( console . log ( frequencyBandArray . length ) || frequencyBandArray . length ) * 4 } )` } }
343+ className = { `${ classes . frequencyBands } ${ ( activeFb > - 1 && activeRightFb > - 1 )
344+ ? ( ( activeFb <= num && activeRightFb >= num )
345+ ? 'selected'
346+ : '' )
347+ : ( activeFb === num || activeRightFb === num )
348+ ? 'selected'
349+ : '' } `}
350+ style = { { backgroundColor : `rgb(${ color . r } , ${ color . g } , ${ color . b } )` , padding : `calc(100vw / ${ ( frequencyBandArray . length ) * 4 } )` } }
226351 elevation = { 4 }
227352 id = { num }
228353 key = { num }
229354 onClick = { ( ) => handleFreqBandClick ( num ) }
355+ onContextMenu = { ( ) => handleFreqBandRightClick ( num ) }
230356 />
231357 < div
232- className = { `${ classes . frequencyBandsBg } ${ activeFb === num ? 'selected' : '' } ` }
233- style = { { backgroundColor : `rgb(${ bgColor . r } , ${ bgColor . g } , ${ bgColor . b } )` , padding : `calc(100vw / ${ ( console . log ( frequencyBandArray . length ) || frequencyBandArray . length ) * 4 } )` } }
358+ className = { `${ classes . frequencyBandsBg } ${ ( activeFb > - 1 && activeRightFb > - 1 )
359+ ? ( ( activeFb <= num && activeRightFb >= num )
360+ ? 'selected'
361+ : '' )
362+ : ( activeFb === num || activeRightFb === num )
363+ ? 'selected'
364+ : '' } `}
365+ style = { { backgroundColor : `rgb(${ bgColor . r } , ${ bgColor . g } , ${ bgColor . b } )` , padding : `calc(100vw / ${ frequencyBandArray . length * 4 } )` } }
234366 onClick = { ( ) => handleFreqBandClick ( num ) }
367+ onContextMenu = { ( ) => handleFreqBandRightClick ( num ) }
235368 />
236369 </ div >
237370 ) }
0 commit comments