SVG анимация с CSS кликом - PullRequest
3 голосов
/ 29 марта 2020

У меня есть сердечная кнопка, когда при щелчке она заполняет SVG красным снизу вверх, а когда она не нажата, она заполняет SVG сверху вниз. Вот то, что я искал до сих пор: JSFiddle

Я новичок в такого рода техниках, как ключевые кадры и клипы. Все это можно сделать только через css?

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>

Любые альтернативы и решения приветствуются! Заранее спасибо!

1 Ответ

2 голосов
/ 30 марта 2020

Рассмотрите возможность заливки цветом с помощью фильтров feFlood и анимации с изменением атрибута dy фильтра feoffset.
Повторные щелчки изменяют анимацию направления цвета

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>  
...