jqueryfunctionaudioclickfadeout

After audio loop smooth start/end, starting smooth another loop by click


What works :

On my page I have several buttons (by divs: b1, b2, b3) and when I click them, they fadeIn their own sound loop smoothly. If I click on the back home button, the played sound fadeOut smoothly. The audio tag is created dinamically.

My jQuery codes:

$(document).ready(function() {

var audioElement = document.createElement('audio');
audioElement.id       = 'audio-player';
audioElement.loop=true;
audioElement.addEventListener('ended', function() {
    this.currentTime = 0;
    this.play();
}, false);
audioElement.addEventListener('ended', function() {
    this.pause();
}, true);

$('.b1').click(function(){
    audioElement.src = 'media/jazzy.mp3';
    audioElement.play();
    fadeInAudio(audioElement, 1000);
});

$('.b2').click(function(){
    audioElement.src = 'media/violin.mp3';
    audioElement.play();
    fadeInAudio(audioElement, 1000);
});

$('.b3').click(function(){
    audioElement.src = 'media/esoteric.mp3';
    audioElement.play();
    fadeInAudio(audioElement, 1000);
});

$('.back-home').click(function(){
    fadeOutAudio(audioElement, 1000);
});

function fadeInAudio(audio, fadeTime){ 
    audio.volume = 0; // set volume to the minimum 
    var steps = 500;
    var stepTime = fadeTime/steps;
    var audioIncrement = parseFloat(audio.volume + ("0.00" + steps));

    var timer = setInterval(function(){
        audio.volume += audioIncrement;
        console.clear();
        console.log(audio.volume);

        if (audio.volume >= 0.99){ //if its already audible stop the loop
            console.clear();
            console.log("1");
            audio.volume = 1;
            clearInterval(timer);
        }
    }, stepTime);
}

function fadeOutAudio(audio, fadeTime){ 
    audio.volume = 1; // set volume to the maximum 
    var steps = 150;
    var stepTime = fadeTime/steps;
    var audioDecrement = audio.volume / steps;

    var timer = setInterval(function(){
        audio.volume -= audioDecrement;
        console.clear();
        console.log(audio.volume);

        if (audio.volume <= 0.03){ //if its already inaudible stop the loop
            console.clear();
            console.log("0");
            audio.volume = 0;
            audio.pause(); 
            clearInterval(timer);
        }
    }, stepTime);
}

});

Now I would like to give a loop of the home scene also (the initial visualisation on the same webpage, no url is changing), which means that with the same click function the current music must stop smoothly, the scene changes, and a new music must start smoothly. I tried to add the fadeOut effect on the click function, just before the play and fadeIn effect, but it does not work. With this method, the loops stop suddenly, the fadeIn/fadeOut effects disappear :

$('.b1').click(function(){
    fadeOutAudio(audioElement, 1000);
    audioElement.src = 'media/jazzy.mp3';
    audioElement.play();
    fadeInAudio(audioElement, 1000);
});
$('.back-home').click(function(){
    fadeOutAudio(audioElement, 1000);
    audioElement.src = 'media/home-loop.mp3';
    audioElement.play();
    fadeInAudio(audioElement, 1000);
});

I tried other methods also, like replace the scr, etc., but I am not able to resolve the problem. Certainly because I am not a professional, I do my personal website...


Solution

  • My problem was that the fadeIn effect was executed before the fadeOut effect. I found the callback function here: https://www.w3schools.com/jquery/jquery_callback.asp

    So my buttons codes should be :

    $('.b1').click(function(){
        fadeOutAudio(audioElement, 1000, function(){
            audioElement.src = 'media/jazzy.mp3';
            audioElement.play();
            fadeInAudio(audioElement, 1000);
        });
    });
    $('.back-home').click(function(){
        fadeOutAudio(audioElement, 1000, function(){
            audioElement.src = 'media/home-loop.mp3';
            audioElement.play();
            fadeInAudio(audioElement, 1000);
        });
    });
    

    Now, when I click a button, the music starts smoothly, and when I click to another one, the current music stops smoothly and starts a new music smoothly.