I want to build a simple click heart animation using JS. Whenever a user clicks anywhere in the screen a heart pops up from that particular point for 2 sec. It works, but if I click twice on the same position, the heart icon shifts to the top left position of the screen. Please help me to fix this bug. here is the link of my project – " https://codesandbox.io/s/dreamy-wood-2k4gyp?file=/index.js "
const wbody = document.querySelector("body");
const hearticon = document.querySelector(".heart")
wbody.addEventListener("click", (e) => {
hearticon.classList.add("active");
console.log(e);
let xValue = e.clientX - e.target.offsetLeft;
let yValue = e.clientY - e.target.offsetTop;
hearticon.style.left = `${xValue}px`
hearticon.style.top = `${yValue}px`
setTimeout(() => {
hearticon.classList.remove("active");
}, 2000);
});
body{
height: 100vh;
}
.heart {
color: red;
position: absolute;
font-size: 40px;
/* left: 50%;
right: 50%; */
transform: translate(-50%, -50%);
opacity: 0;
}
.heart.active{
animation: animate 2s linear infinite;
}
@keyframes animate {
0%{
opacity: 0;
font-size: 0px;
}
30%{
opacity: 1;
font-size: 40px;
}
50%{
opacity: 1;
font-size: 60px;
}
70%{
opacity: 1;
font-size: 50px;
}
80%{
opacity: 1;
font-size: 40px;
}
90%{
opacity: 0.3;
font-size: 20px;
}
100%{
opacity: 0;
font-size: 0px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Click Animation</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"
integrity="sha512-iecdLmaskl7CVkqkXNQ/ZH/XLlvWZOJyj7Yy7tcenmpD1ypASozpmT/E0iPtmFIB46ZmdtAc9eNBvH0H/ZpiBw=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="script.js" defer></script>
</head>
<body>
<i class="fa-solid fa-heart heart"></i>
</body>
</html>
2
Answers
When you click first time everything is ok because
e.target
= document’s body and it’s fine.But when you click second time
e.target
= heart icon.In this case
e.clientX
becomes equal toe.target.offsetLeft
(the same for clientY) and xValue and yValue are equal to 0.That’s why you have behaviour you mention.
I think you can remove subtraction
e.target.offsetLeft
from e.clientX (the same for Y) and it will work.Instead of calculating the offsets (e.g.
e.clientX - e.target.offsetLeft
), you can directly usee.offsetX
ande.offsetY
forxValue
andyValue
, respectively.