Animation Won't Loop

I’m working through the Front-End Development Certificate, and to try out features of JQuery and other libraries, I’m creating a few projects.

The following is code I’ve written so far for a Christmas e-card.

I plan to have it end with some snowfall. I feel it’s good practice to try to create my own rather than adding a feature that someone else has made that can be added to pages.

At present, I have just created one snowflake, as it’s easier to get that to fall down repeatedly before putting many of them across the page.

However, I’ve tried for the last few hours or more to get it to repeatedly fall down across the page - using a for loop - not using a for loop - but it won’t… I’ve looked at several explanations of how to use animate, but I can’t see why it won’t repeat.

Is it something as simple as the position defined in the CSS? …etc.?

Many thanks in advance.

<!DOCTYPE html>
<html lang="en">

<head>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta charset="UTF-8">
  <title>Christmas E-Card</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"
    integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous" />
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"
    integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
  <link rel="stylesheet" href="style.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/4.1.1/animate.min.css" />
</head>

<script>
  $(document).ready(function () {
    $("#line1, #line2, #line3, #line4, #line5, #line6, #line7, #line8, #line9").hide();
    $("#title").hide();
    $(".snow1").hide();
    $("p").hide();
    // $("#title").addClass("animate__animated animate__fadeInLeft");
    $("#title").delay(3500).fadeIn(7000);
    $("p").delay(10000).fadeIn(7000);

    $("p").click(function () {
      $("p").fadeOut(2000);
      $("#title").fadeOut(4000);
      $("#line1").delay(4250).fadeIn(3000).fadeOut(3000);
      $("#line2").delay(11000).fadeIn(5000).fadeOut(5000);
      $("#line3").delay(21500).fadeIn(3000).fadeOut(3000);
      $("#line4").delay(28000).fadeIn(3000).fadeOut(22000);
      $("#line5").delay(32500).fadeIn(3000).fadeOut(17500);
      $("#line6").delay(39000).fadeIn(3000).fadeOut(11000);
      $("#line7").delay(45500).fadeIn(3000).fadeOut(3000);
      $("#line8").delay(53000).fadeIn(3000).fadeOut(3000);
      $("#line9").delay(59000).fadeIn(3000).fadeOut(3000);
      $(".snow1").delay(66000).fadeIn(3000);
    });
    $(".snow1").click(function () {
      setInterval(snowing, 2000);
    });
  });

  function snowing() {
    // for (let i = 0; i < 500; i++) {
    //   $(".snow1").animate({bottom: '0%'}, 'slow').fadeOut();
    //   i += 1;
    //   $(".snow").animate({top: '100%'}).fadeIn();
    // }
    $(".snow1").animate({bottom: '0%'})
    $(".snow1").fadeOut()
    $(".snow1").animate({top: '100%'}).fadeIn();
  }

</script>

<body>
  <div class="container-fluid main_container">
    <h1 id="title">Begin your Christmas Journey</h1>
    <p>By Clicking Here!</p>
    <h1 id="line1">I forgot to buy a card...</h1>
    <h2 id="line2">Because I've been learning JavaScript, Python, HTML and other code...</h1>
      <h1 id="line3">But I can use the skills...</h1>
      <h1 id="line4">to create a unique,</h1>
      <h1 id="line5">special,</h1>
      <h1 id="line6">portfolio-enhancing,</h1>
      <h1 id="line7">e-card</h1>
      <h1 id="line8">So Happy Christmas</h1>
      <h1 id="line9">And Happy New Year</h1>
      <div class="snow1">
      </div>
      <p></p>
      <p></p>
      <p></p>
      <p></p>
  </div>
</body>

</html>

You can loop using the complete property on the options object. You didn’t post your CSS but the element has to be positioned.

<div class="snow">
  *
</div>
body {
  background: #b01b2e;
}

.snow {
  font-size: 4rem;
  position: absolute;
  color: #eef1ff;
}
$(function () {
  function snowing() {
    $(".snow")
      .css({
        top: 0
      })
      .animate(
        {
          top: "100%"
        },
        {
          duration: 2000,
          complete: snowing
        }
      );
  }
  snowing();
});

https://api.jquery.com/animate/


Depending on what you are trying to achieve it might be easier to do it in pure CSS. You can also put the animation inside a selector that you toggle on and off on elements as needed.

body {
  background: #b01b2e;
}

.snow {
  font-size: 4rem;
  position: absolute;
  color: #eef1ff;
  opacity: 0;
  animation: snowing 2s ease-in-out infinite;
}

@keyframes snowing {
  from {
    transform: translateY(0);
  }
  to {
    opacity: 1;
    transform: translateY(100vh);
  }
}

Thanks for this. I’ll try it out and post again later about how it’s worked out

Just tried, it works. Thank you very much!

Sorry to bother you more, but could you elaborate on what I got wrong in the code that I posted?

I based it on some examples from different websites, especially this one:

I’ll have a play around with doing it in pure CSS as well, then.

Now that I have one snowflake falling down the screen repeatedly, I plan to put seven or eight others across the screen as well.

I am going to do that by creating a bunch of <div class="snow2>, <div class="snow3> … <div class="snow9> elements, insert those into the function with different coordinates.

If I have trouble I’ll ask again. Or if you think that sounds like it won’t work best, and you have time to suggest anything, it’s more than welcome.

Thanks again.

1 Like

You can use setInterval as well but you don’t need it because the animate method comes with the options. It works the same but instead of re-running the function base on a timer you re-run based on the completion of the function. The animate method just calls the function again when it has finished.

When animating elements stick to using transform/translate and other GPU-accelerated properties. Do not use position.

If you want a lot of elements you likely want to use canvas. Or a particle system lib, I don’t have an opinion on which, you can try tsParticles.

Very informative. I’ll see what happens when I cancel out the setIntervals, then.

Thanks :slight_smile:

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.