SVG animation with CSS onclick

Viewed 682

I have a heart button when onclick it will fill the SVG with red from bottom to top and when unclicked it will unfill the SVG from top to bottom. Heres what I've searched so far:JSFiddle

I'm new with this kind of techniques like keyframes and clip-path thing. These can all be done via css only?

body {
  display: -webkit-box;
  display: flex;
  -webkit-box-pack: center;
          justify-content: center;
  -webkit-box-align: center;
          align-items: center;
  height: 100vh;
}

.heart-container {
  position: relative;
  width: 40px;
  height: 40px;
}

.heart-clip {
  display: block;
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  -webkit-clip-path: url(#svgPath);
          clip-path: url(#svgPath);
}
.heart-clip:hover {
  -webkit-animation: pulse .6s .3s infinite;
          animation: pulse .6s .3s infinite;
}
.heart-clip:hover::before {
  -webkit-transform: scale(1);
          transform: scale(1);
  opacity: 1;
}
.heart-clip::before {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background-color: #D32F2F;
  opacity: 0;
  -webkit-transform: scale(0);
          transform: scale(0);
  -webkit-transition: opacity .2s linear, -webkit-transform .2s linear;
  transition: opacity .2s linear, -webkit-transform .2s linear;
  transition: transform .2s linear, opacity .2s linear;
  transition: transform .2s linear, opacity .2s linear, -webkit-transform .2s linear;
  -webkit-transform-origin: center 60%;
          transform-origin: center 60%;
}

.heart-stroke {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  fill: #D32F2F;
}

@-webkit-keyframes pulse {
  0% {
    -webkit-transform: scale(1);
            transform: scale(1);
  }
  30% {
    -webkit-transform: scale(1.2);
            transform: scale(1.2);
  }
  60% {
    -webkit-transform: scale(1);
            transform: scale(1);
  }
}

@keyframes pulse {
  0% {
    -webkit-transform: scale(1);
            transform: scale(1);
  }
  30% {
    -webkit-transform: scale(1.2);
            transform: scale(1.2);
  }
  60% {
    -webkit-transform: scale(1);
            transform: scale(1);
  }
}
<svg height="0" width="0">
    <defs>
        <clipPath id="svgPath">
            <path d="M20,35.09,4.55,19.64a8.5,8.5,0,0,1-.13-12l.13-.13a8.72,8.72,0,0,1,12.14,0L20,10.79l3.3-3.3a8.09,8.09,0,0,1,5.83-2.58,8.89,8.89,0,0,1,6.31,2.58,8.5,8.5,0,0,1,.13,12l-.13.13Z"/>
        </clipPath>
    </defs>
</svg>

<div class="heart-container">
   <svg width="40" height="40" viewBox="0 0 40 40" class='heart-stroke'>
      <path d="M20,35.07,4.55,19.62a8.5,8.5,0,0,1-.12-12l.12-.12a8.72,8.72,0,0,1,12.14,0L20,10.77l3.3-3.3A8.09,8.09,0,0,1,29.13,4.9a8.89,8.89,0,0,1,6.31,2.58,8.5,8.5,0,0,1,.12,12l-.12.12ZM10.64,7.13A6.44,6.44,0,0,0,6.07,18.19L20,32.06,33.94,18.12A6.44,6.44,0,0,0,34,9l0,0a6.44,6.44,0,0,0-4.77-1.85A6,6,0,0,0,24.83,9L20,13.78,15.21,9A6.44,6.44,0,0,0,10.64,7.13Z"/>
   </svg>
   
   <a href='#' class='heart-clip'></a>
</div>

any alternatives and solutions is much appreciated! Thanks in advance!

1 Answers

Consider filling with color using the feFlood filters and animating with changing thedy attribute of the feoffset filter.
Repeated clicks change the color direction animation

var svg1 = document.getElementById("svg1"),
  close = document.getElementById('close'),
  open = document.getElementById("open");

let flag = true;

svg1.addEventListener('click', function() {
  if (flag == true) {
    close.beginElement();
    flag = false;
  } else {
    open.beginElement();
    flag = true;
  }
});
<div class="heart-container">
      
   <svg id="svg1" width="40" height="40" viewBox="0 0 40 40"  class='heart-stroke'>
       <defs>
    <filter id="red_fill" x="0%" y="0%">
      <feFlood flood-color="#ded9d5" />
      <feOffset dx="0"> 
      <!-- Animation fills of color  from top to bottom. -->
        <animate id="close" attributeName="dy" values="0;40" dur="1s" begin="indefinite" repeatCount="3" restart="whenNotActive" fill="freeze"/> 
           <!-- Animation fills of color  from bottom to top.     -->
    <animate id="open" attributeName="dy" values="40;0" dur="1s" begin="indefinite" repeatCount="3" restart="whenNotActive" fill="freeze"/> 
     
  </feOffset>
      <feComposite operator="in" in2="SourceGraphic" />
      <feComposite operator="over" in2="SourceGraphic" />
    </filter>
  </defs>
   
    <path filter="url(#red_fill)"  stroke="red" stroke-width="2" fill="red" d="M20,35.07,4.55,19.62a8.5,8.5,0,0,1-.12-12l.12-.12a8.72,8.72,0,0,1,12.14,0L20,10.77l3.3-3.3A8.09,8.09,0,0,1,29.13,4.9a8.89,8.89,0,0,1,6.31,2.58,8.5,8.5,0,0,1,.12,12l-.12.12Z"/> 
  
   </svg>
     <a href='#' class='heart-clip'></a>
</div>  

Related