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

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.

Related

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>

How can I make a toggle to toggle the visibility of an inline SVG?

I'm making a website where you can create your own character in order to learn more about SVGs. I want the user to be able to select different poses.
I was wondering how I could toggle the visibility of an SVG on the website to make one disappear and another appear.
Here is my SVG code:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 720 720" style="enable-background:new 0 0 720 720;" xml:space="preserve">
<g id="skin">
<circle class="skin" cx="364.42" cy="383" r="278" />
</g>
<g id="mouth">
<path class="mouth" d="M172.92,383c127.67,0,255.33,0,383,0c0,105.05-86.45,191.5-191.5,191.5S172.92,488.05,172.92,383z"/>
</g>
<g id="hair">
<path class = "hair" d="M107.4,276.86c-2.76-50.59,10.76-81.24,24.2-100.13C189.57,95.31,331.92,112,341.92,57.91
c2.04-11.03-2.07-21.46-6.93-29.61c18.47-6.31,81.92-25.39,151.28,3.28c94.59,39.09,121.88,137.21,127.56,160.84
c7.93,32.98,7.18,61.32,5.46,79.42c-38.79-64.73-78.17-85.57-107.42-92.42c-43.32-10.15-60.72,11.26-139.64,11.71
c-67.77,0.39-78.13-15.27-119.49-10.14C216.75,185.45,165.19,204.69,107.4,276.86z"/>
</g>
<g id="eyes">
<g>
<circle class = "eyes" cx="251.17" cy="271.25" r="52.4"/>
<circle class = "eyes" cx="477.67" cy="271.25" r="52.4"/>
</g>
</g>
<g id="clothing">
<rect x="236.92" y="644.4" width="255" height="180"/>
</g>
<g id="tie">
<rect class="tie" x="341.82" y="653.68" transform="matrix(0.7071 0.7071 -0.7071 0.7071 584.9371 -59.6038)" class="st0" width="45.2" height="45.2"/>
<path class="tie" d="M364.95,927.93c-6.29-12.71-12.59-25.42-18.88-38.13c3.44-63.19,6.89-126.39,10.33-189.58
c5.1,0.25,10.2,0.49,15.29,0.74c4.13,62.75,8.25,125.49,12.38,188.24C377.7,902.11,371.32,915.02,364.95,927.93z"/>
</g>
</svg>
The SVG is just a sample right now before I make the actual assets.

Variable text in SVG defined text tag

I would like to re-use def-ined shapes in SVG but with variable text.
Is the following somehow possibel ?
<svg width="1000pt" height="1000pt" viewBox="0.00 0.00 1000.00 1000.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="shape">
<rect x="10" y="0" rx="5" ry="5" width="80" height="40" style="fill:lightblue;stroke-width:0,opacity:0.5" />
<text text-anchor="middle" x="40" y="20" font-family="Helvetica,sans-Serif" font-size="8.00">variable_text</text>
</g>
</defs>
<g transform="translate(0 0)">
<use xlink:href="#shape" text="test" />
</g>
<g transform="translate(100 0)">
<use xlink:href="#shape" text="test2" />
</g>
</svg>
EDIT: since the solution would probably involve some javascript I have added the tag.
Clone the template and adjust as necessary.
let shape = document.getElementById("shape");
Array.from(document.getElementsByTagName("use")).forEach((use) => {
let text = use.getAttribute("text");
let clone = shape.cloneNode(true);
// might want to do something more robust here
clone.children[1].textContent = text;
use.parentNode.appendChild(clone);
use.parentNode.removeChild(use);
})
<svg width="1000pt" height="1000pt" viewBox="0.00 0.00 1000.00 1000.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<g id="shape">
<rect x="10" y="0" rx="5" ry="5" width="80" height="40" style="fill:lightblue;stroke-width:0,opacity:0.5" />
<text text-anchor="middle" x="40" y="20" font-family="Helvetica,sans-Serif" font-size="8.00">variable_text</text>
</g>
</defs>
<g transform="translate(0 0)">
<use xlink:href="#shape" text="test" />
</g>
<g transform="translate(100 0)">
<use xlink:href="#shape" text="test2" />
</g>
</svg>

SVG Animation works in Chrome, but doesn't in Firefox and other browsers

Okay, so I have an SVG that is basically a clock animation. It works as intended in Chrome when I'm testing it, but loses form when I try it in Firefox or Safari.
This is the SVG in question:
<svg id="svg" width="100%" viewBox="-400 -150 800 300" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1">
<defs>
<path id="sec" d="M0,-140A140,140 0 0,1 0,140A140,140 0 0,1 0,-140" stroke-dasharray="880" stroke-dashoffset="-880.1"
fill="none">
<animate id="second" attributeName="stroke-dashoffset" dur="1s" repeatCount="60" begin="0s;second.end" additive="sum"
accumulate="sum" calcMode="spline" values="0;-14.66" keyTimes="0;1" keySplines="0.42 0.0 0.58 1.0" />
</path>
<path id="min" d="M0,-130A130,130 0 0,1 0,130A130,130 0 0,1 0,-130" stroke-dasharray="817" stroke-dashoffset="-817.1"
fill="none">
<animate id="minute" attributeName="stroke-dashoffset" dur="60s" repeatCount="60" begin="0s;minute.end" additive="sum"
accumulate="sum" calcMode="spline" values="0;0;-13.613" keyTimes="0;0.9833;1" keySplines="0,0,1,1;0.42 0.0 0.58 1.0" />
</path>
<path id="hr" d="M0,-120A120,120 0 0,1 0,120A120,120 0 0,1 0,-120" stroke-dasharray="754" stroke-dashoffset="-754.1"
fill="none">
<animate id="hour" attributeName="stroke-dashoffset" dur="3600s" repeatCount="12" begin="0s;hour.end" additive="sum"
accumulate="sum" calcMode="spline" values="0;0;-62.83" keyTimes="0;0.9997222;1" keySplines="0,0,1,1;0.42 0.0 0.58 1.0" />
</path>
<mask id="mask" maskUnits="userSpaceOnUse" x="-150" y="-150" width="300" height="300">
<g stroke-width="10" stroke-linecap="round" stroke="white">
<use xlink:href="#sec" x="0" y="0" />
<use xlink:href="#min" x="0" y="0" />
<use xlink:href="#hr" x="0" y="0" />
</g>
</mask>
</defs>
<g stroke-width="7" stroke-linecap="round" mask="url(#mask)">
<g stroke="hsla(0, 95%, 25%, 1)">
<use xlink:href="#sec" />
</g>
<g stroke="hsla(188, 15%, 35%, 1)">
<use xlink:href="#min" />
</g>
<g stroke="hsla(218, 5%, 15%, 1)">
<use xlink:href="#hr" />
</g>
</g>
</svg>
<script>
window.onload = function () {
var now = new Date();
var h = now.getHours(), m = now.getMinutes(), s = now.getSeconds();
var curr = h * 60 * 60 + m * 60 + s;
svg.setCurrentTime(curr);
};
</script>
The second hand moves to the next position all the way from the top instead of animating from the previous place. You can test this yourself. This is the link to the code hosted on codepen.

Svg circular slider color changing

I have following svg and i want to create a circular slider,
and the problem is i can't found anything related to changing
stroke color of part of image.
<svg width="221px" height="221px" viewBox="0 0 221 221" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<pattern id="pattern" width="100%" height="100%">
<path d="M110.5,221 C171.527465,221 221,171.527465 221,110.5 C221,49.4725351 171.527465,0 110.5,0 C49.4725351,0 0,49.4725351 0,110.5 C0,171.527465 49.4725351,221 110.5,221 Z"
id="path-1"></path>
<use xlink:href="#path-1"></use>
</mask>
</pattern>
<defs>
<path d="M110.5,221 C171.527465,221 221,171.527465 221,110.5 C221,49.4725351 171.527465,0 110.5,0 C49.4725351,0 0,49.4725351 0,110.5 C0,171.527465 49.4725351,221 110.5,221 Z"
id="path-1"></path>
<mask id="mask-2" maskContentUnits="userSpaceOnUse" maskUnits="objectBoundingBox" x="0" y="0" width="221" height="221" fill="white">
<use xlink:href="#path-1"></use>
</mask>
</defs>
<g id="Final" stroke="none" stroke-width="1" fill="url(#psattern)" fill-rule="evenodd" opacity="0.69921875" stroke-dasharray="1,4">
<g id="voor" transform="translate(-77.000000, -230.000000)" stroke="#F5A623" stroke-width="48">
<g id="fi-strokes" stroke-width="48">
<g id="Gup" transform="translate(0.000000, -44.000000)">
<g id="Gup-5" transform="translate(20.000000, 111.000000)">
<g id="rp-4">
<g id="und" transform="translate(57.000000, 163.000000)">
<g id="reen">
<g id="Dl">
<g id="faded-ts">
<use id="Oval" mask="url(#mask-2)" xlink:href="#path-1"></use>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>
How to change part of image on mouse/touch events to another color?
I tried:
clip-path - i couldn't create smooth color changing.
linear-gradient - same problem
Any Tips?

Categories