Search code examples
javascriptjqueryhtmlcsssoundcloud

Jimdo: Stop animation when SoundCloud-Player song is over


With some help, I managed to create an animation for a SoundCloud player. When the play button is pressed a spinning disk animation starts. This works as expected. Also, when I press the stop button, the animation stops. When a song is already playing and play is pressed on another player, the other player animation and sound is stopped and the clicked player in set to play mode with the animation. All of this is working properly. What I would like to have is, how can I stop the animation when the song is over? My JavaScript knowledge is limited and I don't know how to do this and there are multiple players on my page.

Here's my code until now.

$(function() {
  var activePlayerStartBtn;

  function stopOtherPlayerSetNewAsActive(element) {
    var playerElements = ['', '2'];

    playerElements.forEach(function(el) {
      $('#so' + el).addClass('hide-player');
    });

    $('.bottom-player').removeClass('-move-down');

    var id = '#so' + $(element).parent().data('id');
    console.log('id', id);
    $(id).removeClass('hide-player');

    var toShow = $(element).parent().find('.pp-btn.hide')[0];
    $(element).addClass('hide');
    $(toShow).removeClass('hide');

    var clippedImg = $(element).parent().find('.-clipped')[0];
    $(clippedImg).addClass('-rotating');

    if (activePlayerStartBtn) {
      var stopButton = $(activePlayerStartBtn).parent().find('.pp-btn').not('.hide')[0];
      $(stopButton).addClass('hide');
      $(activePlayerStartBtn).removeClass('hide');

      var priorClippedImg = $(activePlayerStartBtn).parent().find('.-clipped')[0];
      $(priorClippedImg).removeClass('-rotating');
    }
    activePlayerStartBtn = element;
  }

  function stopPlayer(element) {
    $(element).addClass('hide');
    $(activePlayerStartBtn).removeClass('hide');
    $('.bottom-player').addClass('-move-down');

    var clippedImg = $(element).parent().find('.-clipped')[0];
    $(clippedImg).removeClass('-rotating');
    activePlayerStartBtn = null;
  }

  var widget1 = SC.Widget("so");
  $("#playSound").click(function() {
    widget1.play();
    stopOtherPlayerSetNewAsActive("#playSound");
  });

  $("#stopSound").click(function() {
    widget1.pause();
    stopPlayer('#stopSound');
  });

  var widget2 = SC.Widget("so2");

  $("#playSound2").click(function() {
    widget2.play();
    stopOtherPlayerSetNewAsActive("#playSound2");
  });
  $("#stopSound2").click(function() {
    widget2.pause();
    stopPlayer('#stopSound2');
  });
});
.bottom-player {
  left: 0;
  bottom: 0;
  width: 100%;
  position: fixed;
  padding: 20px 0px;
  background-color: #32333b;
  border-top: 3px solid #f70;
  transition: .4s ease-in-out;
}

.-move-down {
  transform: translatey(100%);
  opacity: 0;
}

.hide-player {
  display: none;
}

.hide-play-btn {
  margin-left: -20px;
}

.button-wrapper {
  position: relative;
  overflow: hidden;
  max-width: 200px;
  display: inline-block;
  margin: 4px 5px;
}

.-clipped {
  width: 100%;
  transition: all .4s ease;
  -webkit-transition: all .4s ease;
  clip-path: circle(100% at 50% 50%);
  -webkit-clip-path: circle(100% at 50% 50%);
  -moz-transition-delay: -0.4s;
}

.-rotating {
  animation: loading 10s linear infinite;
  -webkit-animation: loading 10s linear infinite;
  clip-path: circle(45% at 50% 50%);
  -webkit-clip-path: circle(45% at 50% 50%);
  animation-delay: .5s;
  -webkit-animation-delay: .5s;
  opacity: .75;
}

.pp-btn {
  position: absolute;
  width: 100%;
  max-width: 60px;
  cursor: pointer;
  transform: translate(-50%, -55%);
  top: 50%;
  left: 50%;
  opacity: .7;
  clip-path: circle(33% at 49.9% 49.5%);
  -webkit-clip-path: circle(33% at 49.9% 49.5%);
}

.hide {
  display: none;
}

@keyframes loading {
  0% {
    transform: rotate(0);
  }
  100% {
    transform: rotate(360deg);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<script type="text/javascript" src="https://u.jimcdn.com/cms/o/s64e01451c5929131/userlayout/js/api.js">
</script>

<div class="button-wrapper" data-id="">
  <img src="https://i1.sndcdn.com/artworks-000282974765-ufgq02-t500x500.jpg" class="-clipped">

  <img id="playSound" src="https://u.jimcdn.com/cms/o/s64e01451c5929131/userlayout/font/sc-playbtn.svg" onmousedown="return false;" alt="play" title="play" class="pp-btn" name="playSound">
  <img id="stopSound" src="https://u.jimcdn.com/cms/o/s64e01451c5929131/userlayout/font/sc-pausebtn.svg" alt="pause" title="pause" class="pp-btn hide" name="stopSound">
</div>

<div class="button-wrapper" data-id="2">
  <img src="https://i1.sndcdn.com/artworks-000282974765-ufgq02-t500x500.jpg" class="-clipped">

  <img id="playSound2" src="https://u.jimcdn.com/cms/o/s64e01451c5929131/userlayout/font/sc-playbtn.svg" alt="play" title="play" class="pp-btn" name="playSound">
  <img id="stopSound2" src="https://u.jimcdn.com/cms/o/s64e01451c5929131/userlayout/font/sc-pausebtn.svg" alt="pause" title="pause" class="pp-btn hide" name="stopSound2">
</div>

<div class="bottom-player -move-down">


  <iframe id="so" class="hide-play-btn hide-player" name="so" frameborder="0" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/381324509&amp;color=%23f70&amp;inverse=true&amp;auto_play=false&amp;hide_related=true&amp;show_comments=false&amp;show_user=false&amp;show_reposts=false&amp;show_teaser=false"
    scrolling="no" height="20" width="100%">
</iframe>

  <iframe id="so2" class="hide-play-btn hide-player" name="so2" frameborder="0" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/380275043&amp;color=%23f70&amp;inverse=true&amp;auto_play=false&amp;hide_related=true&amp;show_comments=false&amp;show_user=false&amp;show_reposts=false&amp;show_teaser=false"
    scrolling="no" height="20" width="100%">
</iframe>

</div>


Solution

  • The widget in your JavaScript code is linked to the iFrame player using the SoundCloud Widget API. So then, to answer your question you'll need to check their docs and see if there is an event you can use that 'fires' once the song has finished.

    To make this work we have to combine two events. The first one is the READY event and the second the FINISH one. We can only register the finish event once the widget is fully initialised for this to work properly. If you skip this it won't work. Here's how the two work together. Once the song has finished, it will call stopPlayer().

    widget1.bind(SC.Widget.Events.READY, function() {
      widget1.bind(SC.Widget.Events.FINISH, function() {
        stopPlayer('#stopSound');
      });
    });
    

    Here’s a working example based on your code. Example on JSFiddle