ThomasBrushel
ThomasBrushel

Reputation: 107

Animated Heart icon

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

enter image description here

Upvotes: 1

Views: 1975

Answers (2)

pfg
pfg

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

Benneb10
Benneb10

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.

http://jsfiddle.net/jnqzoq1g/

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

Related Questions