P5.js Функция Draw () не работает должным образом в директиве AngularJS - PullRequest
0 голосов
/ 18 мая 2019

Я пытаюсь интегрировать библиотеку p5.js в мое приложение AngularJS, чтобы мой код выполнялся в директиве.

В моих простых файлах JavaScript я могу запустить метод draw () после импортаглобальная библиотека p5.

Мой оригинальный код (не проблема):

var mic
var playButton
var volHistory = []
var micIsOn = false

function setup(){
    createCanvas(400, 150)
    createButtons()
    mic = new p5.AudioIn()
}

function draw(){
    background(245)
    stroke(0, 109, 203) 

    //populate volHistory
    if(micIsOn){
        var vol = mic.getLevel()
        //check to see if array is empty, if it is empty we do not want to push 0 volume
        if(volHistory.length > 0 && vol > 0){
            volHistory.push(vol)
        //if recording has started, we can now take in vol
        } else if(vol > 0) {
            volHistory.push(vol)
            console.log(volHistory.length)
        }
    }

    //iterate through volHistory and draw
    fill(0, 109, 203)
    var barWidth = 2;
    var offsetWidth = 5;
    var offset = 5;
    for(var i = 0; i < volHistory.length; i++){
        var barHeight = map(volHistory[i], 0, 1, 1, height)
        rect(i + offset, (height/2.0) - (barHeight/2.0), barWidth, barHeight, 15);
        offset += offsetWidth;
    }

    //moves wavelength 1 index at a time and account for bar width and offset width
    if(volHistory.length * (offsetWidth + barWidth) > width){
        volHistory.splice(0, 1)
    }

    //draw vertical line
    stroke(250, 30, 100)
    line(volHistory.length + offset, 0, volHistory.length + offset, height) 
}

function createButtons(){
    playButton = createButton("<img style='width: 50px' src='playbutton.png'/>")
    playButton.mousePressed(toggleRecord)
    playButton.position(162, 50)
    playButton.style("background-color", color(0,0,0,0))
    playButton.style("border", 0)
}

//toggle recording of audio
function toggleRecord(){
    if(!micIsOn){
        mic.start()
        micIsOn = true
    } else {
        mic.stop()
        micIsOn = false
    }
}

Приведенный выше код позволяет мне создать визуализатор звука, который подключается к микрофону пользователя, рисуяхолст, который отображает уровень их звука.Выглядит примерно так: enter image description here

Однако, когда я пытаюсь использовать библиотеку в своей директиве Angular, я не могу заставить метод draw () работать так, как ожидается.Функция draw () не работает непрерывно, как вне директивы Angular.

Самое близкое, что я получил, чтобы заставить это работать, - это создание $watch для переменной, чтобы отследить, является ли пользователь записывающим пользователем,Если isRecording - true, я бы использовал setInterval для непрерывного вызова draw ().К сожалению, это кажется неправильным использованием метода draw (), так как он должен выполнять код внутри него непрерывно самостоятельно после первого выполнения.

Угловой код:

(function () {

    angular.module('icSdkPwp').directive('icAudioRecordingUpload', icAudioRecordingUpload);

    function icAudioRecordingUpload($stateSvc, $rS, $utilSvc) {
        return {
            scope: {
                model: '=',
                config: '=',
                updateState: '='
            },
            link: function ($s, e, a) {

                $s.hasRecording = false;
                $s.isRecording = false;
                $s.recordingPaused = false;
                $s.recordingProcessing = false;
                $s.volHistory = []
                $s.micIsOn = false
                $s.p5mic = null
                $s.playButton = null

            var gumStream;
            var rec;
            var input;

            var AudioContext = window.AudioContext || window.webkitAudioContext;
            var audioContext
            $s.startRecording = function(e) {
                if($s.recordingProcessing)
                    return;

                var constraints = { audio: true, video:false }
                setup()
                $s.isRecording = true;

                navigator.mediaDevices.getUserMedia(constraints)
                  .then(function(stream) {
                    audioContext = new AudioContext();
                    gumStream = stream;
                    input = audioContext.createMediaStreamSource(stream);
                    rec = new Recorder(input,{numChannels:2})
                    rec.record()

                }).catch(function(err) {
                    $s.isRecording = true;
                });
            }

           var redrawInt = null;
           $s.$watch("isRecording", function (n, o, s) {
                if(s.isRecording){
                    redrawInt = setInterval(function(){
                        draw()
                    },0);
                }
                else{
                    clearInterval(redrawInt);
                }

            });


            function setup(){
                createCanvas(400, 150)
                $s.p5mic = new p5.AudioIn()
                $s.p5mic.start()
                $s.micIsOn = true
                background(245)
            }

            function draw(){
                stroke(0, 109, 203) 

                //populate volHistory
                if($s.isRecording){
                    var vol = $s.p5mic.getLevel()
                    //check to see if array is empty, if it is empty we do not want to push 0 volume
                    if($s.volHistory.length > 0 && vol > 0){
                    $s.volHistory.push(vol)
                    //if recording has started, we can now take in vol
                    } else if(vol > 0) {
                        $s.volHistory.push(vol)
                    }
                }

                //iterate through volHistory and draw
                fill(0, 109, 203)
                var barWidth = 2;
                var offsetWidth = 5;
                var offset = 5;
                for(var i = 0; i < $s.volHistory.length; i++){
                    var barHeight = map($s.volHistory[i], 0, 1, 1, height)
                    rect(i + offset, (height/2.0) - (barHeight/2.0), barWidth, barHeight, 15);
                    offset += offsetWidth;
                }

                    //moves wavelength 1 index at a time and account for bar width and offset width
                if($s.volHistory.length * (offsetWidth + barWidth) > width){
                    $s.volHistory.splice(0, 1)
                }

                    //draw vertical line
                stroke(250, 30, 100)
                // debugger
                line($s.volHistory.length + offset, 0, $s.volHistory.length + offset, height) 
            }

        }
        };
    }

}());

Кнопка, которая вызывает startRecording (), инициируя процесс

<div class="IX_recordControls clearfix">
    <div class="rcrow row1">
        <div ng-click="recordingProcessing || startRecording($event)"
             ng-if="!hasRecording">
    </div>
</div>

Это дает мне действительно странный холст, который, я полагаю, ожидается, так как я не должен вызывать draw () так много разно я не могу найти способ заставить его вызывать один раз и работать непрерывно.

enter image description here

Это определенно похоже на проблему с областью действия, где ничья() метод не может выполнить свой собственный цикл.

...