Reputation: 107
So I'm currently trying to animate a SVG icon. I have a heart and a few lines around it all with the class of lines. By default I want the heart to just have an outline but then change the background color on click (I have that working).
The part I'm struggling with is only showing the lines around the heart on click. I know this is simple but I just can't seem to wrap my head around it. In my css I set .lines{display: none}
by default and I also created a class .lines-show{fill: red}
and I want them to show when the heart is clicked. Then I'm going to use a setTimeout() function to hide the lines after X amount of seconds. Here is a link to my codepen if this helps https://codepen.io/Brushel/pen/xXvqgK?editors=1111 Here is the code I have so far:
const lines = document.querySelectorAll(".lines");
const heart = document.querySelector('.heart');
heart.addEventListener('click', function(){
heart.classList.toggle("heart-fill-up");
});
svg {
max-height: 100px;
}
.heart {
fill: transparent;
transition: all .5s;
}
.heart-fill-up {
fill: red;
}
.lines {
display: none;
}
.lines-show {
fill: red;
}
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 298 281" style="enable-background:new 0 0 298 281;" xml:space="preserve">
<style type="text/css">
.heart{
stroke:#FF0606;
stroke-miterlimit:10;
stroke-width: 5px;
}
</style>
<title>icon_wishlist</title>
<g id="icon_wishlist">
<path class="heart" d="M66.3,69.4c-19.1,20-19.1,51.5,0,71.5l84.6,87.9l84.7-87.8c19.1-20,19.1-51.5,0-71.5
c-18-19.1-48.1-19.9-67.2-1.8c-0.6,0.6-1.2,1.2-1.8,1.8L151,85.7l-15.6-16.2c-18-19.1-48.1-19.9-67.2-1.8
C67.6,68.2,67,68.8,66.3,69.4L66.3,69.4z"/>
</g>
<path class="lines" d="M58.1,60.6L9.4,22.1c-1.5-1.2-1.8-3.4-0.6-4.9l0,0c1.2-1.5,3.4-1.8,4.9-0.6l48.6,38.5c1.5,1.2,1.8,3.4,0.6,4.9
l0,0C61.8,61.5,59.6,61.8,58.1,60.6z"/>
<path class="lines" d="M265.4,237l-48.6-38.5c-1.5-1.2-1.8-3.4-0.6-4.9v0c1.2-1.5,3.4-1.8,4.9-0.6l48.6,38.5c1.5,1.2,1.8,3.4,0.6,4.9
l0,0C269.1,237.9,266.9,238.2,265.4,237z"/>
<path class="lines" d="M40.1,230.6L88,191.3c1.5-1.2,3.7-1,4.9,0.5v0c1.2,1.5,1,3.7-0.5,4.9l-47.9,39.3c-1.5,1.2-3.7,1-4.9-0.5l0,0
C38.4,234.1,38.6,231.9,40.1,230.6z"/>
<path class="lines" d="M236.7,54.8l46-41.6c1.4-1.3,3.7-1.2,4.9,0.2v0c1.3,1.4,1.2,3.7-0.2,4.9l-46,41.6c-1.4,1.3-3.7,1.2-4.9-0.2v0
C235.2,58.3,235.3,56.1,236.7,54.8z"/>
<path class="lines" d="M16.9,139.2h34c1.9,0,3.5,1.6,3.5,3.5v0c0,1.9-1.6,3.5-3.5,3.5h-34c-1.9,0-3.5-1.6-3.5-3.5v0
C13.4,140.7,15,139.2,16.9,139.2z"/>
<path class="lines" d="M249.8,139.2h34c1.9,0,3.5,1.6,3.5,3.5v0c0,1.9-1.6,3.5-3.5,3.5h-34c-1.9,0-3.5-1.6-3.5-3.5v0
C246.3,140.7,247.8,139.2,249.8,139.2z"/>
<path class="lines" d="M154.5,237.3v34c0,1.9-1.6,3.5-3.5,3.5l0,0c-1.9,0-3.5-1.6-3.5-3.5v-34c0-1.9,1.6-3.5,3.5-3.5l0,0
C152.9,233.8,154.5,235.4,154.5,237.3z"/>
<path class="lines" d="M154.5,20.3v34c0,1.9-1.6,3.5-3.5,3.5l0,0c-1.9,0-3.5-1.6-3.5-3.5v-34c0-1.9,1.6-3.5,3.5-3.5l0,0
C152.9,16.8,154.5,18.4,154.5,20.3z"/>
</svg>
This is my desired result on click
Upvotes: 1
Views: 1975
Reputation: 3573
Edit for desired result:
You can loop over all the lines in an array by getting them all with document.getElementsByClassName("lines");
and if you convert that into an array you can do
Array.from(document.getElementsByClassName("lines")).forEach( line => {
line.style.display = "block";
});
You can have it toggle repeatedly by wrapping the toggle in a setInterval.
let interval = setInterval( () => {
heart.classList.toggle("heart-fill-up");
}, 1000);
If you don't want to use javascript, you can use a css animation set to repeat
@keyframes heart {
0% {
fill: transparent;
}
100% {
fill: red;
}
}
and apply it to your heart with
animation: heart 1s infinite
Upvotes: 0
Reputation: 1489
Since you have more than one of the element "lines" you need to sort through each of them individually (I used a for loop to do this) whenever you want to toggle their classes. I also added a setTimeOut to remove them after 1000 milliseconds.
const lines = document.querySelectorAll(".lines");
const heart = document.querySelector('.heart');
heart.addEventListener('click', function(){
heart.classList.toggle("heart-fill-up");
for (var x = 0; x < lines.length; x++){
lines[x].classList.toggle("lines-show");
}
setTimeout(function(){
for (var x = 0; x < lines.length; x++){
lines[x].classList.toggle("lines-show");
}
}, 1000);
});
.lines {
fill: transparent;
transition: all .5s;
}
.lines-show {
fill: red;
Upvotes: 1