Using SVG Pattern as Background - javascript

React-Native-svg supports SVG pattern, however, I am not sure how to apply it...
When I try the minimal example from the documentation, I get a blanc screen, white screen.
<View
style={{paddingTop: 20,
height: '100%',
flex: 1,
backgroundColor: 'white'}}>
<Svg width="100%" height="100%" viewBox="0 0 800 400">
<Defs>
<Pattern
id="TrianglePattern"
patternUnits="userSpaceOnUse"
x="0"
y="0"
width="100"
height="100"
viewBox="0 0 10 10">
<Path d="M 0 0 L 7 0 L 3.5 7 z" fill="red" stroke="blue" />
</Pattern>
</Defs>
</Svg>
</View>
Why is that?

As #Robert Longson pointed out in a comment below the Q. You need a shape (like a rect or ellipse) with the id given in the pattern.
<Svg width="100%" height="100%" viewBox="0 0 800 400">
<Defs>
<Pattern
id="TrianglePattern"
patternUnits="userSpaceOnUse"
x="0"
y="0"
width="100"
height="100"
viewBox="0 0 10 10"
>
<Path d="M 0 0 L 7 0 L 3.5 7 z" fill="red" stroke="blue" />
</Pattern>
</Defs>
<Rect fill="none" stroke="blue" x="1" y="1" width="798" height="398" />
<Ellipse
fill="url(#TrianglePattern)" // make sure this is the id given in the pattern
stroke="black"
strokeWidth="5"
cx="400"
cy="200"
rx="350"
ry="150"
/>
</Svg>

Related

How to animate SVG path polymorphing circle images?

SVG animation - for example
https://theplusaddons.com/widgets/morphing-sections/
How can I do such animation?
<div class="polymorphing">
<svg viewBox="0 0 200 200" height="600" width="600" xmlns="http://www.w3.org/2000/svg">
<clipPath id="myClip">
<path fill="#FF0066"
d="M42.3,-45.7C56.3,-38.7,70.1,-26.8,73.3,-12.4C76.5,2,69.1,18.8,58.1,29.6C47.1,40.4,32.7,45.1,17.7,51.9C2.8,58.7,-12.5,67.6,-28.1,66.5C-43.7,65.4,-59.5,54.5,-69.8,39.1C-80.2,23.7,-85.1,3.9,-80.7,-13.1C-76.4,-30.2,-62.9,-44.5,-47.9,-51.3C-32.9,-58.1,-16.4,-57.5,-1.1,-56.1C14.2,-54.8,28.4,-52.7,42.3,-45.7Z"
transform="translate(100 100)" />
</clipPath>
<g clip-path="url(#myClip)">
<image class="morph-image"
xlink:href="https://theplusaddons.com/wp-content/uploads/2019/04/digitalagency3.jpg" x="0" y="0"
height="100%" width="100%">
</image>
</g>
</svg>
</div>

Is it possible to programatically control fill color of individual cells of svg pattern?

<svg viewBox="200 190 500 500" id="example">
<defs>
<pattern id="patt" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<g stroke="black" strokeWidth="0.5" >
<path id='a' fill='green' d="M0,0.054V20h21V0.054H0z M15.422,18.129l-5.264-2.768l-5.265,2.768l1.006-5.863L1.64,8.114l5.887-0.855 l2.632-5.334l2.633,5.334l5.885,0.855l-4.258,4.152L15.422,18.129z"/>
</g>
</pattern>
</defs>
<g fill="url(#patt)" stroke="orange" >
<circle cx="450" cy="300" r="100"/>
</g>
</svg>
Requirement is to create a pattern of svg in which fill color of each element in the pattern has to be manipulated.
Only when you create all colored shapes inside the <pattern> yourself:
<svg-pattern colors="green,red,blue,yellow"></svg-pattern>
<svg-pattern colors="purple,hotpink,hotpink,purple"></svg-pattern>
<script>
customElements.define("svg-pattern", class extends HTMLElement {
connectedCallback() {
let colors = this.getAttribute("colors").split(",");
let star = `v20h21v-20h-21zm15.4 18-5.3-2.8-5.3 2.8 1-5.9-4.3-4.2 5.9-.9 2.6-5.3 2.6 5.3 5.9.9-4.3 4.2 1 6z`;
let id = "unique" + Math.random();
this.innerHTML = `<svg width="180" height="180" style="display:inline-block" viewBox="0 0 200 200">
<defs>
<pattern id="${id}" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse">
<g stroke="black" strokeWidth="0.5" >
<path fill='${colors[0]}' d="m0 0 ${star}"/>
<path fill='${colors[1]}' d="m20 0 ${star}"/>
<path fill='${colors[2]}' d="m0 20 ${star}"/>
<path fill='${colors[3]}' d="m20 20 ${star}"/>
</g>
</pattern>
</defs>
<g fill="url(#${id})">
<circle cx="100" cy="100" r="100"/>
</g>
</svg>`;
}
});
</script>

Javascript to perform custom placement of svg text

I am working with a SVG element as following. In this I am using <textPath></textPath> to place a text on a path.
The svg is following
<!DOCTYPE html>
<html>
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect class="vBoxRect" width="1280" height="720" fill="green" rx="35" style="overflow: visible;"></rect>
<rect class="boundRect" x="70" y="70" width="1090" height="500" fill="green"></rect>
<g class="bound" style="transform: translate(70px, 70px);">
<path id="WorldAvg" class="WorldAvg" fill="none" stroke="white" stroke-width="5" opacity="1" d="M0,418.8448266855795L45.416666666666664,414.575606092466L90.83333333333333,411.52106545918446L136.25,407.6362492744353L181.66666666666666,404.77160362539087L227.08333333333334,393.4071256244998L272.5,391.02044947895274L317.9166666666667,386.66829128561017L363.3333333333333,379.8367479839252L408.75,378.1893224105598L454.1666666666667,369.95354728799214L499.5833333333333,368.77725419172447L545,363.8472517451793L590.4166666666666,363.6062134379884L635.8333333333334,357.4943259634553L681.25,351.27652154825586L726.6666666666666,344.34458188257486L772.0833333333334,342.18836536625594L817.5,338.5473949587725L862.9166666666666,336.1670218633692L908.3333333333334,332.6090887556393L953.75,328.1112436453848L999.1666666666666,321.4448005003716L1044.5833333333335,312.9573561957251L1090,306.4131526885112"></path>
<g class="avgLbl">
<text text-anchor="start" stroke="red">
<textPath href="#WorldAvg" startOffset="0%">10.3%</textPath>
</text>
<text text-anchor="end" stroke="red">
<textPath href="#WorldAvg" startOffset="100%">24.7%</textPath>
</text>
</g>
</svg>
</body>
</html>
My end goal is to place each text just above the path so that the text is clearly visible.
To achieve that, I tried the following which did not work. the label for 24.7% is pushed far down.
Is there a way to programatically achieve this?
const element = document.querySelectorAll('.avgLbl>text');
const comp = document.querySelector(`.bound>#WorldAvg`);
element.forEach(
(a, i) => {
const diff = comp.getBoundingClientRect().bottom - a.getBoundingClientRect().bottom;
a.setAttribute('transform', `translate(0,${diff})`)
}
);
<!DOCTYPE html>
<html>
<body>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect class="vBoxRect" width="1280" height="720" fill="green" rx="35" style="overflow: visible;"></rect>
<rect class="boundRect" x="70" y="70" width="1090" height="500" fill="green"></rect>
<g class="bound" style="transform: translate(70px, 70px);">
<path id="WorldAvg" class="WorldAvg" fill="none" stroke="white" stroke-width="5" opacity="1" d="M0,418.8448266855795L45.416666666666664,414.575606092466L90.83333333333333,411.52106545918446L136.25,407.6362492744353L181.66666666666666,404.77160362539087L227.08333333333334,393.4071256244998L272.5,391.02044947895274L317.9166666666667,386.66829128561017L363.3333333333333,379.8367479839252L408.75,378.1893224105598L454.1666666666667,369.95354728799214L499.5833333333333,368.77725419172447L545,363.8472517451793L590.4166666666666,363.6062134379884L635.8333333333334,357.4943259634553L681.25,351.27652154825586L726.6666666666666,344.34458188257486L772.0833333333334,342.18836536625594L817.5,338.5473949587725L862.9166666666666,336.1670218633692L908.3333333333334,332.6090887556393L953.75,328.1112436453848L999.1666666666666,321.4448005003716L1044.5833333333335,312.9573561957251L1090,306.4131526885112"></path>
<g class="avgLbl">
<text text-anchor="start" stroke="red">
<textPath href="#WorldAvg" startOffset="0%">10.3%</textPath>
</text>
<text text-anchor="end" stroke="red">
<textPath href="#WorldAvg" startOffset="100%">24.7%</textPath>
</text>
</g>
</svg>
</body>
</html>
You could achieve a baseline offset by adjusting dominant-baseline and dy values like so:
svg {
display: block;
height: 100vmin;
}
text {
font-size: 30px
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 720">
<rect class="vBoxRect" width="1280" height="720" fill="green" rx="35" style="overflow: visible;"></rect>
<rect class="boundRect" x="70" y="70" width="1090" height="500" fill="green"></rect>
<g class="bound" style="transform: translate(70px, 70px);">
<path id="WorldAvg" class="WorldAvg" fill="none" stroke="white" stroke-width="5" opacity="1" d="M 0 418.8 L 45.4 414.6 L 90.8 411.5 L 136.3 407.6 L 181.7 404.8 L 227.1 393.4 L 272.5 391 L 317.9 386.7 L 363.3 379.8 L 408.8 378.2 L 454.2 370 L 499.6 368.8 L 545 363.8 L 590.4 363.6 L 635.8 357.5 L 681.3 351.3 L 726.7 344.3 L 772.1 342.2 L 817.5 338.5 L 862.9 336.2 L 908.3 332.6 L 953.8 328.1 L 999.2 321.4 L 1044.6 313 L 1090 306.4"></path>
<g class="avgLbl">
<text text-anchor="start" dominant-baseline="hanging" dy="10" stroke="red">
<textPath href="#WorldAvg" startOffset="0%">10.3%</textPath>
</text>
<text text-anchor="end" dominant-baseline="hanging" dy="10" stroke="red">
<textPath href="#WorldAvg" startOffset="100%">24.7%</textPath>
</text>
</g>
</svg>
dominant-baseline="hanging"
will position your text under your <textPath>
dy="10"
allows you to finetune the vertical alignment further:
Quite often capital letters ascenders will collide with your <textPath>.

Calculate SVG.Text Length before drawing [duplicate]

I want to color the background of svg text similar to background-color in css
I was only able to find documentation on fill, which colors the text itself
Is it even possible?
You could use a filter to generate the background.
<svg width="100%" height="100%">
<defs>
<filter x="0" y="0" width="1" height="1" id="solid">
<feFlood flood-color="yellow" result="bg" />
<feMerge>
<feMergeNode in="bg"/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
</defs>
<text filter="url(#solid)" x="20" y="50" font-size="50">solid background</text>
</svg>
No this is not possible, SVG elements do not have background-... presentation attributes.
To simulate this effect you could draw a rectangle behind the text attribute with fill="green" or something similar (filters). Using JavaScript you could do the following:
var ctx = document.getElementById("the-svg"),
textElm = ctx.getElementById("the-text"),
SVGRect = textElm.getBBox();
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.setAttribute("x", SVGRect.x);
rect.setAttribute("y", SVGRect.y);
rect.setAttribute("width", SVGRect.width);
rect.setAttribute("height", SVGRect.height);
rect.setAttribute("fill", "yellow");
ctx.insertBefore(rect, textElm);
The solution I have used is:
<svg>
<line x1="100" y1="100" x2="500" y2="100" style="stroke:black; stroke-width: 2"/>
<text x="150" y="105" style="stroke:white; stroke-width:0.6em">Hello World!</text>
<text x="150" y="105" style="fill:black">Hello World!</text>
</svg>
A duplicate text item is being placed, with stroke and stroke-width attributes. The stroke should match the background colour, and the stroke-width should be just big enough to create a "splodge" on which to write the actual text.
A bit of a hack and there are potential issues, but works for me!
Instead of using a <text> tag, the <foreignObject> tag can be used, which allows for XHTML content with CSS.
No, you can not add background color to SVG elements. You can do it programmatically with d3.
var text = d3.select("text");
var bbox = text.node().getBBox();
var padding = 2;
var rect = self.svg.insert("rect", "text")
.attr("x", bbox.x - padding)
.attr("y", bbox.y - padding)
.attr("width", bbox.width + (padding*2))
.attr("height", bbox.height + (padding*2))
.style("fill", "red");
Answer by Robert Longson (#RobertLongson) with modifications:
<svg width="100%" height="100%">
<defs>
<filter x="0" y="0" width="1" height="1" id="solid">
<feFlood flood-color="yellow"/>
<feComposite in="SourceGraphic" operator="xor"/>
</filter>
</defs>
<text filter="url(#solid)" x="20" y="50" font-size="50"> solid background </text>
<text x="20" y="50" font-size="50">solid background</text>
</svg>
and we have no bluring and no heavy "getBBox" :)
Padding is provided by white spaces in text-element with filter.
It's worked for me
Going further with #dbarton_uk answer, to avoid duplicating text you can use paint-order=stroke style:
<svg>
<line x1="100" y1="100" x2="350" y2="100" style="stroke:grey; stroke-width: 100"/>
<text x="150" y="105" style="stroke:white; stroke-width:0.5em; fill:black; paint-order:stroke; stroke-linejoin:round">Hello World!</text>
</svg>
Note the stroke-linejoin:round which is needed to avoid seeing spikes for the W sharp angle.
You can combine filter with the text.
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<title>SVG colored patterns via mask</title>
</head>
<body>
<svg viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter x="0" y="0" width="1" height="1" id="bg-text">
<feFlood flood-color="white"/>
<feComposite in="SourceGraphic" operator="xor" />
</filter>
</defs>
<!-- something has already existed -->
<rect fill="red" x="150" y="20" width="100" height="50" />
<circle cx="50" cy="50" r="50" fill="blue"/>
<!-- Text render here -->
<text filter="url(#bg-text)" fill="black" x="20" y="50" font-size="30">text with color</text>
<text fill="black" x="20" y="50" font-size="30">text with color</text>
</svg>
</body>
</html>
For those wondering how to apply padding to a text element when it has a background like in the Robert's answer, do the following:
<svg>
<defs>
<filter x="-0.1" y="-0.1" width="1.2" height="1.2" id="solid">
<feFlood flood-color="#171717"/>
<feComposite in="SourceGraphic" operator="xor" />
</filter>
</defs>
<text filter="url(#solid)" x="20" y="50" font-size="50">Hello</text>
</svg>
In the example above, filter's x and y positions can be used as transform: translate(-10%, -10%) would, and width and height values can be read as 120% and 120%. So we made background 20% bigger, and offsetted it -10%, so background is now 10% bigger on each side of the text.
this is my favorite hack (not sure it should work). It refer an element that is not yet displayed, and it works pretty well
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 620 40" preserveAspectRatio="xMidYMid meet">
<defs>
<filter x="-0.02" y="0" width="1.04" height="1.1" id="removebackground">
<feFlood flood-color="#00ffff"/>
</filter>
</defs>
<!--Draw the text-->
<use xlink:href="#mygroup" filter="url(#removebackground)" />
<g id="mygroup">
<text id="text1" x="9" y="20" style="text-anchor:start;font-size:14px;">custom text with background</text>
<line x1="200" y1="18" x2="200" y2="36" stroke="#000" stroke-width="5"/>
<line x1="120" y1="27" x2="203" y2="27" stroke="#000" stroke-width="5"/>
</g>
</svg>
The previous answers relied on doubling up text and lacked sufficient whitespace.
By using atop and I was able to get the results I wanted.
This example also includes arrows, a common use case for SVG text labels:
<svg viewBox="-105 -40 210 234">
<title>Size Guide</title>
<defs>
<filter x="0" y="0" width="1" height="1" id="solid">
<feFlood flood-color="white"></feFlood>
<feComposite in="SourceGraphic" operator="atop"></feComposite>
</filter>
<marker id="arrow" viewBox="0 0 10 10" refX="5" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
<path d="M 0 0 L 10 5 L 0 10 z"></path>
</marker>
</defs>
<g id="garment">
<path id="right-body" fill="none" stroke="black" stroke-width="1" stroke-linejoin="round" d="M0 0 l30 0 l0 154 l-30 0"></path>
<path id="right-sleeve" d="M30 0 l35 0 l0 120 l-35 0" fill="none" stroke-linejoin="round" stroke="black" stroke-width="1"></path>
<use id="left-body" href="#right-body" transform="scale(-1,1)"></use>
<use id="left-sleeve" href="#right-sleeve" transform="scale(-1,1)"></use>
<path id="collar-right-top" fill="none" stroke="black" stroke-width="1" stroke-linejoin="round" d="M0 -6.5 l11.75 0 l6.5 6.5"></path>
<use id="collar-left-top" href="#collar-right-top" transform="scale(-1,1)"></use>
<path id="collar-left" fill="white" stroke="black" stroke-width="1" stroke-linejoin="round" d="M-11.75 -6.5 l-6.5 6.5 l30 77 l6.5 -6.5 Z"></path>
<path id="front-right" fill="white" stroke="black" stroke-width="1" d="M18.25 0 L30 0 l0 154 l-41.75 0 l0 -77 Z"></path>
<line x1="0" y1="0" x2="0" y2="154" stroke="black" stroke-width="1" stroke-dasharray="1 3"></line>
<use id="collar-right" href="#collar-left" transform="scale(-1,1)"></use>
</g>
<g id="dimension-labels">
<g id="dimension-sleeve-length">
<line marker-start="url(#arrow)" marker-end="url(#arrow)" x1="85" y1="0" x2="85" y2="120" stroke="black" stroke-width="1"></line>
<text font-size="10" filter="url(#solid)" fill="black" x="85" y="60" class="dimension" text-anchor="middle" dominant-baseline="middle"> 120 cm</text>
</g>
<g id="dimension-length">
<line marker-start="url(#arrow)" marker-end="url(#arrow)" x1="-85" y1="0" x2="-85" y2="154" stroke="black" stroke-width="1"></line>
<text font-size="10" filter="url(#solid)" fill="black" x="-85" y="77" text-anchor="middle" dominant-baseline="middle" class="dimension"> 154 cm</text>
</g>
<g id="dimension-sleeve-to-sleeve">
<line marker-start="url(#arrow)" marker-end="url(#arrow)" x1="-65" y1="-20" x2="65" y2="-20" stroke="black" stroke-width="1"></line>
<text font-size="10" filter="url(#solid)" fill="black" x="0" y="-20" text-anchor="middle" dominant-baseline="middle" class="dimension"> 130 cm </text>
</g>
<g title="Back Width" id="dimension-back-width">
<line marker-start="url(#arrow)" marker-end="url(#arrow)" x1="-30" y1="174" x2="30" y2="174" stroke="black" stroke-width="1"></line>
<text font-size="10" filter="url(#solid)" fill="black" x="0" y="174" text-anchor="middle" dominant-baseline="middle" class="dimension"> 60 cm </text>
</g>
</g>
</svg>
An obvious workaround to the problem of the blur produced by the filter effect is to render the <text> two times: once for the background (with transparent characters) and once for the characters (without a background filter).
For me, this was the only way to make the text readable in Safari.
<svg width="100%" height="100%">
<filter x="0" y="0" width="1" height="1" id="solid">
<feFlood flood-color="yellow" />
</filter>
<g transform="translate(20, 50)" font-size="50">
<text aria-hidden="true" fill="none" filter="url(#solid)">solid background</text>
<text fill="blue">solid background</text>
</g>
</svg>
The aria-hidden="true" attribute is there to prevent screen readers from speaking the text twice, if the user uses a screen reader.
You can add style to your text:
style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
text-shadow: rgb(255, 255, 255) -2px -2px 0px, rgb(255, 255, 255) -2px 2px 0px,
rgb(255, 255, 255) 2px -2px 0px, rgb(255, 255, 255) 2px 2px 0px;"
White, in this example.
Does not work in IE :)

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>
// progressbar.js#1.0.0 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.
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>
<div id="container">
<svg xmlns="http://www.w3.org/2000/svg" id="heart-path" fill="red" 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-path1" 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"/>
<defs style="display: none ! important;">
<symbol id="heart">
<path d="M12 21.35l-1.45-1.32c-5.15-4.67-8.55-7.75-8.55-11.53 0-3.08 2.42-5.5 5.5-5.5 1.74 0 3.41.81 4.5 2.09 1.09-1.28 2.76-2.09 4.5-2.09 3.08 0 5.5 2.42 5.5 5.5 0 3.78-3.4 6.86-8.55 11.54l-1.45 1.31z"/>
</symbol>
</defs>
<use xlink:href="#heart-path1" x="0" y="0" fill="red"/>
</svg>
</div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="24" height="576">
<defs style="display: none ! important;">
<symbol id="heart">
<path d="M12 21.35l-1.45-1.32c-5.15-4.67-8.55-7.75-8.55-11.53 0-3.08 2.42-5.5 5.5-5.5 1.74 0 3.41.81 4.5 2.09 1.09-1.28 2.76-2.09 4.5-2.09 3.08 0 5.5 2.42 5.5 5.5 0 3.78-3.4 6.86-8.55 11.54l-1.45 1.31z"/>
</symbol>
</defs>
<use xlink:href="#heart" x="0" y="0" fill="red"/>
<use xlink:href="#heart" x="0" y="24" fill="orange"/>
<use xlink:href="#heart" x="0" y="48" fill="yellow"/>
<use xlink:href="#heart" x="0" y="72" fill="green"/>
<use xlink:href="#heart" x="0" y="96" fill="blue"/>
<use xlink:href="#heart" x="0" y="120" fill="indigo"/>
<use xlink:href="#heart" x="0" y="144" fill="violet"/>
<use xlink:href="#heart" x="0" y="168" fill="cyan"/>
<use xlink:href="#heart" x="0" y="192" fill="magenta"/>
<use xlink:href="#heart" x="0" y="216" fill="lime"/>
<use xlink:href="#heart" x="0" y="240" fill="olive"/>
<use xlink:href="#heart" x="0" y="264" fill="maroon"/>
<use xlink:href="#heart" x="0" y="288" fill="purple"/>
<use xlink:href="#heart" x="0" y="312" fill="#fff"/>
<use xlink:href="#heart" x="0" y="336" fill="#e5e5e5"/>
<use xlink:href="#heart" x="0" y="360" fill="#ccc"/>
<use xlink:href="#heart" x="0" y="384" fill="#b2b2b2"/>
<use xlink:href="#heart" x="0" y="408" fill="#999"/>
<use xlink:href="#heart" x="0" y="432" fill="#7f7f7f"/>
<use xlink:href="#heart" x="0" y="456" fill="#666"/>
<use xlink:href="#heart" x="0" y="480" fill="#4c4c4c"/>
<use xlink:href="#heart" x="0" y="504" fill="#333"/>
<use xlink:href="#heart" x="0" y="528" fill="#191919"/>
<use xlink:href="#heart" x="0" y="552" fill="#000"/>
</svg>
Please check it,this will help to you.
https://jsfiddle.net/obw4asLy/1/
You will need to change your approach. As far as I can see, the library you are using will only let you animate the stroke (outside) of the path.
You want to animate the fill. Probably the simplest way is with a gradient. See Custom SVG progress bar fill for an example of how to do this.

Categories