简体   繁体   中英

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

在此处输入图片说明

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;

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM