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>