Home > OS >  How can I make a mouseleave animation play using forEach loop with AnimeJS
How can I make a mouseleave animation play using forEach loop with AnimeJS

Time:11-10

I am using Anime.js to animate an SVG when mouseleave each item.

I have a list within a loop, with an SVG at the end of each list. The issue with my code is that all SVGs animate at the same time when hovering over each item. When I mouseleave each item, I would like the function to animate each SVG separately relative to the hovered item.

I don't know what I'm doing wrong, but I've been stuck for hours.

I could have simply animated with CSS, but it's hard to animate the SVG path as I want without using a library.

Here is my code:

let hoverItem = document.querySelectorAll(".item");

hoverItem.forEach((line) => {
  line.addEventListener("mouseleave", function () {
    anime
      .timeline({
        loop: false
      })
      .add({
        targets: "path",
        d: [
          { value: "M 10 80 Q 645 128 1290 80" },
          { value: "M 10 80 Q 645 11 1290 80" },
          { value: "M 10 80 Q 645 121 1290 80" },
          { value: "M 10 80 Q 645 34 1290 80" },
          { value: "M 10 80 Q 645 102 1290 80" },
          { value: "M 10 80 Q 645 65 1290 80" },
          { value: "M 10 80 Q 645 80 1290 80" }
        ],
        easing: "easeOutElastic(1, .6)",
        duration: 600
      });
  });
});
<ul>

  <li >
    <div >TITLE</div>
    <svg width="1290" height="110" viewBox="0 0 1290 110">
      <path d="M 10 80 Q 640 80 1290 80" stroke-width="1.5" stroke="#D7C9B8" fill="transparent" />
    </svg>
  </li>

  <li >
    <div >TITLE</div>
    <svg width="1290" height="110" viewBox="0 0 1290 110">
      <path d="M 10 80 Q 640 80 1290 80" stroke-width="1.5" stroke="#D7C9B8" fill="transparent" />
    </svg>
  </li>

  <li >
    <div >TITLE</div>
    <svg width="1290" height="110" viewBox="0 0 1290 110">
      <path d="M 10 80 Q 640 80 1290 80" stroke-width="1.5" stroke="#D7C9B8" fill="transparent" />
    </svg>
  </li>

</ul>

Any help would be appreciated.

CodePudding user response:

To do what you require you need to set the targets property to the path related to the .item which raised the mouseleave event.

To do that you can get a reference to the .item element from the Event object passed to the event handled, then querySelector() to get the related path.

let hoverItem = document.querySelectorAll(".item");

hoverItem.forEach((line) => {
  line.addEventListener("mouseleave", function(e) {
    anime.timeline({
      loop: false
    }).add({
      targets: e.target.querySelector('path'),
      d: [{
        value: "M 10 80 Q 645 128 1290 80"
      }, {
        value: "M 10 80 Q 645 11 1290 80"
      }, {
        value: "M 10 80 Q 645 121 1290 80"
      }, {
        value: "M 10 80 Q 645 34 1290 80"
      }, {
        value: "M 10 80 Q 645 102 1290 80"
      }, {
        value: "M 10 80 Q 645 65 1290 80"
      }, {
        value: "M 10 80 Q 645 80 1290 80"
      }],
      easing: "easeOutElastic(1, .6)",
      duration: 600
    });
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha512-z4OUqw38qNLpn1libAN9BsoDx6nbNFio5lA6CuTp9NlK83b89hgyCVq N5FdBJptINztxn1Z3SaKSKUS5UP60Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<ul>
  <li >
    <div >TITLE</div>
    <svg width="1290" height="110" viewBox="0 0 1290 110">
      <path d="M 10 80 Q 640 80 1290 80" stroke-width="1.5" stroke="#D7C9B8" fill="transparent" />
    </svg>
  </li>
  <li >
    <div >TITLE</div>
    <svg width="1290" height="110" viewBox="0 0 1290 110">
      <path d="M 10 80 Q 640 80 1290 80" stroke-width="1.5" stroke="#D7C9B8" fill="transparent" />
    </svg>
  </li>
  <li >
    <div >TITLE</div>
    <svg width="1290" height="110" viewBox="0 0 1290 110">
      <path d="M 10 80 Q 640 80 1290 80" stroke-width="1.5" stroke="#D7C9B8" fill="transparent" />
    </svg>
  </li>
</ul>

  • Related