Search code examples
javascriptvue.jshtml5-audio

Trying to fadein/fadeout html5 audio file vuejs / vanilla js


Goal:

  • Audio fades in and out on first play/pause toggle, need to have it toggling sound continually

Issue

  • Second time toggle audio cuts and skips

HTML

<div class="music-player">
    <audio
      ref="audio"
      src="@/assets/audio/bg-music.ogg"
      preload
      loop
      id="audio"
      muted
    ></audio>
    <div @click="toggleSound()" class="toggle-sound"></div>
</div>

JS - UPDATED

methods: {
  toggleSound() {
    let backgroundAudio = this.$refs.audio;

    //Fade In
    if (
      !document.querySelector(".toggle-sound").classList.contains("paused")
    ) {
      console.log("fading in");
      let actualVolumeFadeIn = 0;
      document.querySelector(".toggle-sound").classList.add("paused");
      clearInterval(fadeInInterval);
      let fadeInInterval = setInterval(function() {
        actualVolumeFadeIn = (parseFloat(actualVolumeFadeIn) + 0.1).toFixed(
        1
      );
        if (actualVolumeFadeIn <= 1) {
          backgroundAudio.volume = actualVolumeFadeIn;
        } else {
          backgroundAudio.play();
        }
      }, 100);
      return false;
    }

    //Fade Out
    if (
      document.querySelector(".toggle-sound").classList.contains("paused")
    ) {
      console.log("fading out");
      let actualVolumeFadeOut = backgroundAudio.volume;
      clearInterval(fadeOutInterval);
      let fadeOutInterval = setInterval(function() {
      actualVolumeFadeOut = (parseFloat(actualVolumeFadeOut) - 0.1).toFixed(
        1
      );
        if (actualVolumeFadeOut >= 0) {
          backgroundAudio.volume = actualVolumeFadeOut;
        } else {
          document.querySelector(".toggle-sound").classList.remove("paused");
          backgroundAudio.pause();
        }
        }, 100);
        return false;
      }
    },
  }

Solution

  • I managed to get it working:

    HTML

    <audio
      ref="audio"
      src="@/assets/audio/bg-music.ogg"
      preload
      loop
      id="audio"
      muted
    ></audio>
    <div
      @click="toggleSound()"
      class="toggle-sound"
      v-bind:class="this.state.backgroundAudioState"
    ></div>
    

    JS

    data: () => ({
      ...
      state: {
        backgroundAudioState: "paused",
      },
    }),
    methods: {
      toggleSound() {
        let backgroundAudio = this.$refs.audio;
        let actualVolumeFadeOut = backgroundAudio.volume;
        let actualVolumeFadeIn = 0;
    
        //Fade In
        if (this.state.backgroundAudioState === "paused") {
          console.log("fading in");
          this.state.backgroundAudioState = "playing";
          clearInterval(fadeInInterval);
          let fadeInInterval = setInterval(function() {
            actualVolumeFadeIn = (parseFloat(actualVolumeFadeIn) + 0.1).toFixed(1);
            if (actualVolumeFadeIn <= 1) {
              backgroundAudio.volume = actualVolumeFadeIn;
            } else {
              backgroundAudio.play();
            }
          }, 100);
          return false;
        }
    
        //Fade Out
        if (this.state.backgroundAudioState === "playing") {
          console.log("fading out");
          this.state.backgroundAudioState = "paused";
          
          let fadeOutInterval = setInterval(function() {
            actualVolumeFadeOut = (parseFloat(actualVolumeFadeOut) - 0.1).toFixed(1);
            if (actualVolumeFadeOut >= 0) {
              backgroundAudio.volume = actualVolumeFadeOut;
            } else {
              backgroundAudio.pause();
              clearInterval(fadeOutInterval);
            }
          }, 100);
          return false;
        }
      },
    }