@@ -458,21 +458,60 @@ class SoundEditor extends React.Component {
458
458
}
459
459
460
460
handleModifyMenu ( ) {
461
+ const playURI = `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI0OSIgaGVpZ2h0PSI1MiIgdmlld0JveD0iLTUgMCA0OSA0OCI+PHBhdGggZmlsbD0iI0ZGRiIgZD0iTTM1LjUwOCAxOS4zNzRjNC4yNTkgMi41NTYgNC4yNTIgNi43MDIgMCA5LjI1NEwxMi43MTIgNDIuMzA1Yy00LjI1OCAyLjU1NS03LjcxLjU5Ny03LjcxLTQuMzhWMTAuMDc3YzAtNC45NzMgMy40NTgtNi45MyA3LjcxLTQuMzh6Ii8+PC9zdmc+` ;
462
+ const stopURI = `data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI1MiIgaGVpZ2h0PSI1MiIgdmlld0JveD0iMCAwIDUyIDUyIj48cmVjdCBmaWxsPSIjRkZGIiB3aWR0aD0iNDQiIGhlaWdodD0iNDQiIHJ4PSI0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0IDQpIi8+PC9zdmc+` ;
463
+
464
+ const genSliderDiv = ( title , params ) => {
465
+ const div = document . createElement ( "div" ) ;
466
+ div . style = "margin: 0 10px 0 5px;width: 40px;display: flex;flex-direction: column;align-items: center;" ;
467
+
468
+ const label = document . createElement ( "div" ) ;
469
+ label . style = "text-align: center;width: 40px;font-size: 12px;font-weight: bold;" ;
470
+ label . textContent = title ;
471
+
472
+ const slider = document . createElement ( "input" ) ;
473
+ slider . style = "transform: rotate(270deg);height: 40px;width: 120px;margin: 45px 10px;" ;
474
+ slider . type = "range" ;
475
+ slider . min = params . min ;
476
+ slider . max = params . max ;
477
+ slider . step = params . step ;
478
+ slider . value = params . value ;
479
+
480
+ const input = document . createElement ( "input" ) ;
481
+ input . style = "text-align: center;width: 40px;border: solid 1px gray;border-radius: 10px;" ;
482
+ input . type = "number" ; { min : - 360 , max : 360 , step : 1 , value : 0 }
483
+ input . min = params . min ;
484
+ input . max = params . max ;
485
+ input . step = params . step ;
486
+ input . value = params . value ;
487
+
488
+ div . append ( label , slider , input ) ;
489
+ return div ;
490
+ } ;
491
+
461
492
// get selected audio
462
493
const bufferSelection = this . getSelectionBuffer ( ) ;
463
494
// for preview
464
495
const audio = new AudioContext ( ) ;
465
496
const gainNode = audio . createGain ( ) ;
466
497
gainNode . gain . value = 1 ;
467
498
gainNode . connect ( audio . destination ) ;
499
+
468
500
// create inputs before menu so we can get the value easier
469
- const pitch = document . createElement ( "input" ) ;
470
- const volume = document . createElement ( "input" ) ;
501
+ const pitchDiv = genSliderDiv (
502
+ "pitch" , { min : - 360 , max : 360 , step : 1 , value : 0 }
503
+ ) ;
504
+ const volumeDiv = genSliderDiv (
505
+ "volume" , { min : 0 , max : 2 , step : 0.01 , value : 1 }
506
+ ) ;
507
+ const pitchParts = pitchDiv . children ;
508
+ const volumeParts = volumeDiv . children ;
471
509
const menu = this . displayPopup ( "Modify Sound" , 200 , 280 , "Apply" , "Cancel" , ( ) => {
472
510
// accepted
473
511
audio . close ( ) ;
474
- const truePitch = isNaN ( Number ( pitch . value ) ) ? 0 : Number ( pitch . value ) ;
475
- const trueVolume = isNaN ( Number ( volume . value ) ) ? 0 : Number ( volume . value ) ;
512
+ const pitch = pitchParts [ 1 ] . value , volume = volumeParts [ 2 ] . value ;
513
+ const truePitch = isNaN ( Number ( pitch ) ) ? 0 : Number ( pitch ) ;
514
+ const trueVolume = isNaN ( Number ( volume ) ) ? 0 : Number ( volume ) ;
476
515
this . handleEffect ( {
477
516
pitch : truePitch * 10 ,
478
517
volume : trueVolume
@@ -482,110 +521,70 @@ class SoundEditor extends React.Component {
482
521
audio . close ( ) ;
483
522
// we dont need to do anything else
484
523
} ) ;
485
- menu . textarea . style = "position: relative;display: flex;justify-content: flex-end;flex-direction: row;height: calc(100% - (3.125em + 2.125em + 16px));align-items: center;" ;
486
- // set pitch stuff
487
- pitch . type = "range" ;
488
- pitch . classList . add ( confirmStyles . verticalSlider ) ;
489
- pitch . style = "position: absolute;left: -40px;top: 80px;" ;
490
- pitch . value = 0 ;
491
- pitch . min = - 360 ;
492
- pitch . max = 360 ;
493
- pitch . step = 1 ;
494
- // set volume stuff
495
- volume . type = "range" ;
496
- volume . classList . add ( confirmStyles . verticalSlider ) ;
497
- volume . style = "position: absolute;left: 0px;top: 80px;" ;
498
- volume . value = 1 ;
499
- volume . min = 0 ;
500
- volume . max = 2 ;
501
- volume . step = 0.01 ;
502
- menu . textarea . append ( pitch ) ;
503
- menu . textarea . append ( volume ) ;
504
- const labelPitch = document . createElement ( "p" ) ;
505
- const labelVolume = document . createElement ( "p" ) ;
506
- labelPitch . style = "text-align: center;width: 35px;font-size: 12px;position: absolute;left: 7.5px;top: 3.5px;" ;
507
- labelVolume . style = "text-align: center;width: 35px;font-size: 12px;position: absolute;left: 47.5px;top: 3.5px;" ;
508
- labelPitch . innerHTML = "Pitch" ;
509
- labelVolume . innerHTML = "Volume" ;
510
- menu . textarea . append ( labelPitch ) ;
511
- menu . textarea . append ( labelVolume ) ;
512
- const valuePitch = document . createElement ( "input" ) ;
513
- const valueVolume = document . createElement ( "input" ) ;
514
- valuePitch . style = "text-align: center;width: 35px;font-size: 12px;position: absolute;left: 4px;top: 152.5px;" ;
515
- valueVolume . style = "text-align: center;width: 35px;font-size: 12px;position: absolute;left: 44px;top: 152.5px;" ;
516
- valuePitch . value = 0 ;
517
- valueVolume . value = 100 ;
518
- valuePitch . min = - 360 ;
519
- valuePitch . max = 360 ;
520
- valuePitch . step = 1 ;
521
- valueVolume . min = 0 ;
522
- valueVolume . max = 200 ;
523
- valueVolume . step = 1 ;
524
- valuePitch . type = "number" ;
525
- valueVolume . type = "number" ;
526
- menu . textarea . append ( valuePitch ) ;
527
- menu . textarea . append ( valueVolume ) ;
524
+
525
+ menu . textarea . style = "margin: 0 10px 0 10px;position: relative;display: flex;justify-content: flex-end;flex-direction: row;height: calc(100% - (3.125em + 2.125em + 16px));align-items: center;" ;
526
+ menu . textarea . append ( pitchDiv , volumeDiv ) ;
527
+
528
528
const previewButton = document . createElement ( "button" ) ;
529
- previewButton . style = "font-weight: bold;color: white;border-radius: 1000px ;width: 46px;margin-right: 28px;height: 46px;border-style: none;background: #00c3ff;" ;
530
- previewButton . innerHTML = "Play" ;
529
+ previewButton . style = "border-radius: 100%;padding: 5px ;width: 46px;margin-right: 28px;height: 46px;border-style: none;background: #00c3ff;" ;
530
+ previewButton . innerHTML = `<img draggable="false" style="max-width: 100%;max-height: 100%" src=" ${ playURI } ">` ;
531
531
menu . textarea . append ( previewButton ) ;
532
- // playing audio
532
+
533
+ // preview functionality
533
534
// create an audio buffer using the selection
534
535
const properBuffer = audio . createBuffer ( 1 , bufferSelection . samples . length , bufferSelection . sampleRate ) ;
535
536
properBuffer . getChannelData ( 0 ) . set ( bufferSelection . samples ) ;
536
- // button functionality
537
- let bufferSource ;
538
- let audioPlaying = false ;
537
+
538
+ let bufferSource , audioPlaying = false ;
539
539
function play ( ) {
540
540
bufferSource = audio . createBufferSource ( ) ;
541
541
bufferSource . connect ( gainNode ) ;
542
542
bufferSource . buffer = properBuffer ;
543
543
bufferSource . start ( 0 ) ;
544
544
bufferSource . detune . value = pitch . value * 10 ;
545
- previewButton . innerHTML = "Stop" ;
545
+ previewButton . innerHTML = `<img draggable="false" style="max-width: 100%;max-height: 100%" src=" ${ stopURI } ">` ;
546
546
audioPlaying = true ;
547
547
bufferSource . onended = ( ) => {
548
- previewButton . innerHTML = "Play" ;
548
+ previewButton . firstChild . src = playURI ;
549
549
audioPlaying = false ;
550
550
}
551
551
}
552
552
function stop ( ) {
553
553
bufferSource . stop ( ) ;
554
- previewButton . innerHTML = "Play" ;
554
+ previewButton . firstChild . src = stopURI ;
555
555
audioPlaying = false ;
556
556
}
557
557
previewButton . onclick = ( ) => {
558
- if ( audioPlaying ) {
559
- return stop ( ) ;
560
- }
561
- play ( ) ;
562
- }
563
- // updates
564
- pitch . onchange = ( updateValue ) => {
565
- if ( updateValue !== false ) {
566
- valuePitch . value = Number ( pitch . value ) ;
567
- } ;
568
- if ( ! bufferSource ) return ;
569
- bufferSource . detune . value = pitch . value * 10 ;
558
+ if ( audioPlaying ) stop ( ) ;
559
+ else play ( ) ;
570
560
}
571
- pitch . oninput = pitch . onchange ;
572
- volume . onchange = ( updateValue ) => {
573
- gainNode . gain . value = volume . value ;
574
- if ( updateValue === false ) return ;
575
- valueVolume . value = Number ( volume . value ) * 100 ;
561
+
562
+ // slider/number updates
563
+ const pSlider = pitchParts [ 1 ] ;
564
+ const pNumber = pitchParts [ 2 ] ;
565
+ pSlider . onchange = ( updateValue ) => {
566
+ if ( updateValue !== false ) pNumber . value = Number ( pSlider . value ) ;
567
+ if ( bufferSource ) bufferSource . detune . value = pSlider . value * 10 ;
576
568
}
577
- volume . oninput = volume . onchange ;
578
- // value changes
579
- valuePitch . onchange = ( ) => {
580
- pitch . value = valuePitch . value ;
581
- pitch . onchange ( false ) ;
569
+ pSlider . oninput = pSlider . onchange ;
570
+ pNumber . onchange = ( ) => {
571
+ pSlider . value = pNumber . value ;
572
+ pSlider . onchange ( false ) ;
582
573
} ;
583
- valuePitch . oninput = valuePitch . onchange ;
584
- valueVolume . onchange = ( ) => {
585
- volume . value = valueVolume . value / 100 ;
586
- volume . onchange ( false ) ;
574
+ pNumber . oninput = pNumber . onchange ;
575
+
576
+ const vSlider = volumeParts [ 1 ] ;
577
+ const vNumber = volumeParts [ 2 ] ;
578
+ vSlider . onchange = ( updateValue ) => {
579
+ gainNode . gain . value = vSlider . value ;
580
+ if ( updateValue !== false ) vNumber . value = Number ( vSlider . value ) * 100 ;
581
+ }
582
+ vSlider . oninput = vSlider . onchange ;
583
+ vNumber . onchange = ( ) => {
584
+ vSlider . value = vNumber . value / 100 ;
585
+ vSlider . onchange ( false ) ;
587
586
} ;
588
- valueVolume . oninput = valueVolume . onchange ;
587
+ vNumber . oninput = vNumber . onchange ;
589
588
}
590
589
handleFormatMenu ( ) {
591
590
const sampleRates = [
0 commit comments