Trigger Event Once on Leaving Parent/Screen/Overlap

Hi - I've been going around and around on a particular problem the past couple days and decided I might just be going about it wrong so wanted to see if I could get some help.

I've got a little div set up with an animation roughly like this jsfiddle

I'm doing the animation via CSS just to keep things smooth and simple. What I'm trying to do is watch the li's and trigger a sound from p5 when they hit the border of the container. I've tried a couple different approaches, right now I'm using jQuery to watch their offset() in the draw() loop and see if it falls below the offset of the parent div, as below. This succeeds but causes a retriggering of the event until the animation loops back around. I'm not sure how to get it to only trigger once per animation cycle.

function draw(){
  for (var i = 1; i < number of lis ; i++){
    var squaresOffset = jQuery('#square'+ i).offset().top; //gave all the li's an ID just to be totally sure they were being targeted properly
    var boundary = jQuery('container').offset().top;
    if (squaresOffset < boundary ){
      playSwish(); //playSwish is previously defined

I've tried lowering the frame rate so there's only enough time for one trigger, and although this mostly works, it's not really a solution. I've also tried having the sound trigger on the animation completion, which also works, but again is not ideally the behavior that I want.

It probably seems convoluted to be doing CSS animation, using jQuery to monitor elements, and p5 to trigger sounds - perhaps there's a better solution using fewer separate pieces that I'm not seeing. I'd rather not rebuild it purely in a canvas though, as I'd like the animation to be visible even with JS turned off, and the added dimension of sound to be available with JS.

Sorry if I'm not clearly communicating what I'm going for - this is my first post for code help so I'm a little new to this. Any help, insight or feedback would be very much appreciated. Thank you!


  • Sorry about that - should be fixed now - thanks for your patience.

  • Answer ✓

    Couldn't see anything happening on the jsfiddle... Anyway - it sounds like you just need to 'debounce' (this is usually a problem that happens when checking keyboard input). Try adding a boolean isPLaying = false. Then check against this before playing the sound:

    if (squaresOffset < boundary && !isPlaying){
      playSwish(); //playSwish is previously defined
      isPlaying = true; // stop the sound from playing again

    You then have to set isPLaying back to false once the sound stops...

  • Ahhh yes, of course - yeah that does the trick nicely -now I'm just doing a bit of reorganizing to set isPlaying back to false after animationEnd. Thank you!

Sign In or Register to comment.