Search code examples
javascriptcsssvgsvg-filterssvg-animate

How to animate fill instead of path in an SVG progress bar


I want to use the following SVG for donation page. I want to fill all of the heart (not just the border), and make it filled from the bottom to the top. How can I change the filling direction?

https://jsfiddle.net/kimmobrunfeldt/dnLLgm5o/

<div id="container">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" x="0px" y="0px" viewBox="0 0 100 100">
              <path fill-opacity="0" stroke-width="1" stroke="#bbb" d="M81.495,13.923c-11.368-5.261-26.234-0.311-31.489,11.032C44.74,13.612,29.879,8.657,18.511,13.923  C6.402,19.539,0.613,33.883,10.175,50.804c6.792,12.04,18.826,21.111,39.831,37.379c20.993-16.268,33.033-25.344,39.819-37.379  C99.387,33.883,93.598,19.539,81.495,13.923z"/>
              <path id="heart-path" fill-opacity="0" stroke-width="3" stroke="#ED6A5A" d="M81.495,13.923c-11.368-5.261-26.234-0.311-31.489,11.032C44.74,13.612,29.879,8.657,18.511,13.923  C6.402,19.539,0.613,33.883,10.175,50.804c6.792,12.04,18.826,21.111,39.831,37.379c20.993-16.268,33.033-25.344,39.819-37.379  C99.387,33.883,93.598,19.539,81.495,13.923z"/>
          </svg>
</div>

// [email protected] version is used
// Docs: http://progressbarjs.readthedocs.org/en/1.0.0/

var bar = new ProgressBar.Path('#heart-path', {
easing: 'easeOut',
duration: 5400
});

bar.set(0);
bar.animate(1.0);  // Number from 0.0 to 1.0

Thanks.


Solution

  • You can use a mask and move it upward from the bottom on the heart as donations are made. [EDIT]:Included is an interval timer to animate the fill. See example below:

    <!DOCTYPE HTML>
    <html>
    <body>
    <div style='width:200px;height:200px;'>
      <svg  x="0px" y="0px" viewBox="0 0 100 100" >
      <defs>
        <mask id="heart">
            <path fill=white d="M81.495,13.923c-11.368-5.261-26.234-0.311-31.489,11.032C44.74,13.612,29.879,8.657,18.511,13.923  C6.402,19.539,0.613,33.883,10.175,50.804c6.792,12.04,18.826,21.111,39.831,37.379c20.993-16.268,33.033-25.344,39.819-37.379  C99.387,33.883,93.598,19.539,81.495,13.923z"/>
        </mask>
    </defs>
      <rect id=heartRect x=0 y="100%"  fill=red width="100%" height="100%"  mask="url(#heart)" />
      <path id=heartPath stroke="red" fill=none stroke-width=3 d="M81.495,13.923c-11.368-5.261-26.234-0.311-31.489,11.032C44.74,13.612,29.879,8.657,18.511,13.923  C6.402,19.539,0.613,33.883,10.175,50.804c6.792,12.04,18.826,21.111,39.831,37.379c20.993-16.268,33.033-25.344,39.819-37.379  C99.387,33.883,93.598,19.539,81.495,13.923z"/>
      </svg>
    </div>
     <button onClick=donateAnimate()>Donate Animate()</button>
     <script>
    //---button---
    function donateAnimate()
    {
    var iT = setInterval(donate, 50 )
    var Donations=0
    function donate()
    {
         if(Donations>=1)
        clearInterval(iT);
        var bb=heartPath.getBBox()
        var bby=bb.y
        var bbh=bb.height
        //---bottom of heart---
        var heartBase=bby+bbh
    
        if(Donations<1)
        {
            Donations+=.05
            var percent=(1-Donations)*heartBase
            heartRect.setAttribute("y",percent)
        }
    
    }
    
    }
     </script>
    </body>
    </html>