SVG transformation from path to another - css

So I have this SVG animation I'm trying to make work, I made a quick smaller version of the real image below to explain what I'm trying to do.
The biggest issue I faced was making the <line> elements "follow" the position of the <path> or even <circle> elements.
This is the first stage of the animation
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 124 82">
<defs>
<style>
.cls-1 {
fill: none;
stroke: #000;
stroke-miterlimit: 10;
stroke-width: 2px;
}
</style>
</defs>
<title>Untitled-5</title>
<path d="M107,94a10,10,0,1,1-10,10,10,10,0,0,1,10-10m0-2a12,12,0,1,0,12,12,12,12,0,0,0-12-12Z" transform="translate(-95 -34)"/>
<path d="M139,36a10,10,0,1,1-10,10,10,10,0,0,1,10-10m0-2a12,12,0,1,0,12,12,12,12,0,0,0-12-12Z" transform="translate(-95 -34)"/>
<path d="M207,69a10,10,0,1,1-10,10,10,10,0,0,1,10-10m0-2a12,12,0,1,0,12,12,12,12,0,0,0-12-12Z" transform="translate(-95 -34)"/>
<line class="cls-1" x1="38" y1="21" x2="17" y2="61"/>
<line class="cls-1" x1="54" y1="16" x2="102" y2="40"/>
</svg>
Then after a few seconds I want it to smoothly animate to the positions of this next SVG. After that it should just smootly alternate between the two.
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 112 68">
<defs>
<style>
.cls-1 {
fill: none;
stroke: #000;
stroke-miterlimit: 10;
stroke-width: 2px;
}
</style>
</defs>
<title>Untitled-5</title>
<path d="M104,53A10,10,0,1,1,94,63a10,10,0,0,1,10-10m0-2a12,12,0,1,0,12,12,12,12,0,0,0-12-12Z" transform="translate(-92 -28)"/>
<path d="M151,74a10,10,0,1,1-10,10,10,10,0,0,1,10-10m0-2a12,12,0,1,0,12,12,12,12,0,0,0-12-12Z" transform="translate(-92 -28)"/>
<path d="M192,30a10,10,0,1,1-10,10,10,10,0,0,1,10-10m0-2a12,12,0,1,0,12,12,12,12,0,0,0-12-12Z" transform="translate(-92 -28)"/>
<line class="cls-1" x1="49" y1="52" x2="22" y2="39"/>
<line class="cls-1" x1="66" y1="48" x2="92" y2="20"/>
</svg>
Thanks in advance for help!

Trying to animate lines that connect the edges of the circles is going to be quite hard with SMIL animation. The endpoints will take non-linear paths across the screen.
However if you change the lines so that they connect the centre of the circles, things get a lot simpler. To hide the parts of the lines that are inside the circles, you can just move them behind the circles, and then give the circles a solid fill. Or you could use a circle mask to hide the extended lines, if you really need transparent circles.
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 124 82">
<defs>
<style>
.cls-1 {
fill: none;
stroke: #000;
stroke-miterlimit: 10;
stroke-width: 2px;
}
</style>
</defs>
<title>Untitled-5</title>
<line class="cls-1" x1="12" y1="70" x2="44" y2="12">
<animate attributeName="y1" from="70" to="35" dur="2s" fill="freeze"/>
<animate attributeName="x2" from="44" to="59" dur="2s" fill="freeze"/>
<animate attributeName="y2" from="12" to="56" dur="2s" fill="freeze"/>
</line>
<line class="cls-1" x1="44" y1="12" x2="112" y2="45">
<animate attributeName="x1" from="44" to="59" dur="2s" fill="freeze"/>
<animate attributeName="y1" from="12" to="56" dur="2s" fill="freeze"/>
<animate attributeName="x2" from="112" to="100" dur="2s" fill="freeze"/>
<animate attributeName="y2" from="45" to="12" dur="2s" fill="freeze"/>
</line>
<circle cx="12" cy="70" r="11" fill="white" stroke="black" stroke-width="2">
<animate attributeName="cy" from="70" to="35" dur="2s" fill="freeze"/>
</circle>
<circle cx="44" cy="12" r="11" fill="white" stroke="black" stroke-width="2">
<animate attributeName="cx" from="44" to="59" dur="2s" fill="freeze"/>
<animate attributeName="cy" from="12" to="56" dur="2s" fill="freeze"/>
</circle>
<circle cx="112" cy="45" r="11" fill="white" stroke="black" stroke-width="2">
<animate attributeName="cx" from="112" to="100" dur="2s" fill="freeze"/>
<animate attributeName="cy" from="45" to="12" dur="2s" fill="freeze"/>
</circle>
</svg>

Related

Why is my SVG animation loop skipping some parts?

I am working on a little svg component that produces graphs as in the snippet below.
I want to animate it. Right now, I just try to make a breathing-like effect but the line animation doesn't loop correctly. I split it into 2 parts and use an animateTransform trick to pause one while the other is executing. It works on the first iteration but not on the second and the rest.
To the SVG Jedi who might come across this topic, please let me know if I should change some of the animation attributes to make it more smooth/performant. This is the product of many trials & errors and I'm no expert in the field.
The relevant part is here
<line :x1="ox" :y1="oy" :stroke="isHeading ? 'white' : '#FFFFF0'">
<animateTransform
id="pause"
begin="expandAnim.end"
dur="3s"
type="translate"
attributeType="XML"
attributeName="transform"
repeatCount="indefinite"
/>
<animateTransform
id="pause2"
begin="pause.end"
dur="3s"
type="translate"
attributeType="XML"
attributeName="transform"
repeatCount="indefinite"
/>
<animate
id="expandAnim"
attributeName="x2"
:from="cx"
:to="dx"
dur="3s"
begin="0; pause.end"
repeatCount="indefinite"
/>
<animate
fill="freeze"
attributeName="y2"
:from="cy"
:to="dy"
dur="3s"
begin="0; pause.end"
repeatCount="indefinite"
/>
<animate
id="collapseAnim"
attributeName="x2"
fill="freeze"
:from="dx"
:to="cx"
dur="3s"
begin="3; expandAnim.end"
repeatCount="indefinite"
/>
<animate
attributeName="y2"
fill="freeze"
:from="dy"
:to="cy"
dur="3s"
begin="3; expandAnim.end"
repeatCount="indefinite"
/>
</line>
Here is a complete snippet version (please edit if you know how to collapse the code)
svg {
background-color:black
}
.is-hl {
fill: white;
stroke: white;
}
.heading-placeholder {
fill: transparent;
stroke: white;
}
circle {
fill: transparent;
stroke: white;
}
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" class="article-fingerprint d-flex">
<rect id="overlay" width="100%" height="100%" fill="url(#g1)"></rect>
<g transform="translate(125, 125)">
<circle fill="url(#bgGradient)" cx="0" cy="0" r="64.66666666666667"></circle>
<g class="type-element" idx="0">
<line x1="3.959691317243109e-15" y1="-64.66666666666667" stroke="#FFFFF0">
<animateTransform id="pause" begin="expandAnim.end" dur="3s" type="translate" attributeType="XML" attributeName="transform" repeatCount="indefinite"></animateTransform>
<animateTransform id="pause2" begin="pause.end" dur="3s" type="translate" attributeType="XML" attributeName="transform" repeatCount="indefinite"></animateTransform>
<animate id="expandAnim" attributeName="x2" from="5.5460389524011505e-15" to="6.158362351974827e-15" dur="3s" begin="0; pause.end" repeatCount="indefinite"></animate>
<animate fill="freeze" attributeName="y2" from="-90.57368959380808" to="-100.57368959380808" dur="3s" begin="0; pause.end" repeatCount="indefinite"></animate>
<animate id="collapseAnim" attributeName="x2" fill="freeze" from="6.158362351974827e-15" to="5.5460389524011505e-15" dur="3s" begin="3; expandAnim.end" repeatCount="indefinite"></animate>
<animate attributeName="y2" fill="freeze" from="-100.57368959380808" to="-90.57368959380808" dur="3s" begin="3; expandAnim.end" repeatCount="indefinite"></animate>
</line>
<circle cx="3.959691317243109e-15" cy="-64.66666666666667" r="1" class="origin"></circle>
<!---->
<!---->
<path id="circlePath24336" d="M5.5460389524011505e-15,-90.57368959380808 L6.158362351974827e-15,-100.57368959380808 L5.5460389524011505e-15,-90.57368959380808" fill="none"></path>
<circle r="2.590702292714141">
<animateMotion dur="6s" repeatCount="indefinite" fill="freeze">
<mpath xlink:href="#circlePath24336"></mpath>
</animateMotion>
</circle>
</g>
</g>
</svg>
As a side question, as I didn't dive in the performance aspect of it yet, does it look like a wise way to proceed with this animation? Or would it be better to stick to a CSS scale animation with the center as origin?
Extra question also: is it feasible to trigger this animation on hover? I haven't spent too much time on it but since the small animated lines and circles are in a child component of the overlay used to trigger, I'm not sure of how to propagate a SVG event such as e.g. overlay.mouseover to it. Note that I'm using vue.
Since your animation was complicated. I didn't bother trying to debug it. I just rewrote it in a more simple form.
svg {
background-color:black
}
.is-hl {
fill: white;
stroke: white;
}
.heading-placeholder {
fill: transparent;
stroke: white;
}
circle {
fill: transparent;
stroke: white;
}
<svg xmlns="http://www.w3.org/2000/svg" width="250" height="250" class="article-fingerprint d-flex">
<rect id="overlay" width="100%" height="100%" fill="url(#g1)"></rect>
<g transform="translate(125, 125)">
<circle fill="url(#bgGradient)" cx="0" cy="0" r="64.66666666666667"></circle>
<g class="type-element" idx="0">
<line x1="3.959691317243109e-15" y1="-64.66666666666667" stroke="#FFFFF0">
<animate attributeName="x2"
dur="6s" repeatCount="indefinite"
values="0; 0; 0"
keyTimes="0; 0.5; 1"/>
<animate attributeName="y2"
dur="6s" repeatCount="indefinite"
values="-90.573; -100.573; -90.573"
keyTimes="0; 0.5; 1"/>
</line>
<circle r="2.590702292714141">
<animateTransform attributeName="transform"
type="translate"
dur="6s" repeatCount="indefinite"
values="0,-90.573; 0,-100.573; 0,-90.573"
keyTimes="0; 0.5; 1"/>
</circle>
</g>
</g>
</svg>

How can I make gradient line segments move along an SVG path

I have an animation I would like to make on an HTML5 document. I would like to have some short line segments move along a path. The line segments should have a gradient so that the front is opaque and the tail fade out to fully transparent.
I could use a stroke-dasharray and animate an offset (https://css-tricks.com/svg-line-animation-works/#article-header-id-4) but so far as I can tell linear gradients for strokes behave essentially to the entire shape, not just the stroke segment (https://codepen.io/plava/pen/BjavpN).
Is there perhaps a way that I can take a line and slide it along another path? That would let me apply a gradient to that line alone. My lines are moving from left to right sort of following a sine wave like curve, so if the gradient doesn't bend with the line that is okay.
This is part of an Electron app, so it only needs to be compatible with a somewhat recent version of Chromium.
One way would be to use multiple paths with different length dashes and different opacities. As long as the dash arrays have the same total length, and the dashoffsets plus the first element of the dash array is the same value for each path, the ends of the dashes will be in the same position:
#path {
stroke-dasharray: 10 90;
animation: dash 5s linear alternate infinite;
stroke: black;
stroke-width: 5;
}
#path2 {
stroke-dasharray: 20 80;
animation: dash2 5s linear alternate infinite;
stroke: rgba(0,0,0,0.5);
stroke-width: 5;
}
#keyframes dash {
from {
stroke-dashoffset: 100;
}
to {
stroke-dashoffset: 0;
}
}
#keyframes dash2 {
from {
stroke-dashoffset: 110;
}
to {
stroke-dashoffset: 10;
}
}
It's kind of a hassle to keep adding more css, so I automated the creation of the css using some javascript here: https://jsfiddle.net/aqwg7ed6/
That fiddle automatically creates 32 paths which creates a nice effect.
here's how i managed to do so:
<svg id="group-01" width="1668" height="1527" viewBox="0 0 1668 1527" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<path id="loop-01" d="M 417.00,-648.50 C 647.03,-648.50 833.50,-462.03 833.50,-232.00 833.50,-232.00 833.50,253.00 833.50,253.00 833.50,483.03 647.03,669.50 417.00,669.50 417.00,669.50 417.00,669.50 417.00,669.50 186.97,669.50 0.50,483.03 0.50,253.00 0.50,253.00 0.50,-232.00 0.50,-232.00 0.50,-462.03 186.97,-648.50 417.00,-648.50 417.00,-648.50 417.00,-648.50 417.00,-648.50 Z" />
<path id="loop-02" d="M 1250.00,-648.50 C 1480.03,-648.50 1666.50,-462.03 1666.50,-232.00 1666.50,-232.00 1666.50,253.00 1666.50,253.00 1666.50,483.03 1480.03,669.50 1250.00,669.50 1250.00,669.50 1250.00,669.50 1250.00,669.50 1019.97,669.50 833.50,483.03 833.50,253.00 833.50,253.00 833.50,-232.00 833.50,-232.00 833.50,-462.03 1019.97,-648.50 1250.00,-648.50 1250.00,-648.50 1250.00,-648.50 1250.00,-648.50 Z" />
<path id="loop-03" d="M 418.00,670.50 C 648.03,670.50 834.50,856.97 834.50,1087.00 834.50,1087.00 834.50,1572.00 834.50,1572.00 834.50,1802.03 648.03,1988.50 418.00,1988.50 418.00,1988.50 418.00,1988.50 418.00,1988.50 187.97,1988.50 1.50,1802.03 1.50,1572.00 1.50,1572.00 1.50,1087.00 1.50,1087.00 1.50,856.97 187.97,670.50 418.00,670.50 418.00,670.50 418.00,670.50 418.00,670.50 Z" />
<path id="loop-04" d="M 1251.00,670.50 C 1481.03,670.50 1667.50,856.97 1667.50,1087.00 1667.50,1087.00 1667.50,1572.00 1667.50,1572.00 1667.50,1802.03 1481.03,1988.50 1251.00,1988.50 1251.00,1988.50 1251.00,1988.50 1251.00,1988.50 1020.97,1988.50 834.50,1802.03 834.50,1572.00 834.50,1572.00 834.50,1087.00 834.50,1087.00 834.50,856.97 1020.97,670.50 1251.00,670.50 1251.00,670.50 1251.00,670.50 1251.00,670.50 Z" />
<radialGradient id="fade-01" cx="0" cy="0" fx="0" fy="0" r="200" gradientUnits="userSpaceOnUse">
<stop stop-color="#80D2B5" stop-opacity="1" offset="0" />
<stop stop-color="#0D1115" stop-opacity="0" offset="1" />
</radialGradient>
<radialGradient id="fade-02" cx="0" cy="0" fx="0" fy="0" r="200" gradientUnits="userSpaceOnUse">
<stop stop-color="#5332D5" stop-opacity="1" offset="0" />
<stop stop-color="#0E1216" stop-opacity="0" offset="1" />
</radialGradient>
<mask id="tail-01" maskUnits="userSpaceOnUse">
<use style="fill:none;stroke:#fff;stroke-width:2;stroke-dasharray:100% -100%" xlink:href="#loop-01">
<animate attributeName="stroke-dashoffset" from="100%" to="-100%" dur="10s" repeatCount="indefinite" />
</use>
</mask>
<mask id="tail-02" maskUnits="userSpaceOnUse">
<use style="fill:none;stroke:#fff;stroke-width:2;stroke-dasharray:100% -100%" xlink:href="#loop-02">
<animate attributeName="stroke-dashoffset" from="100%" to="-100%" dur="10s" repeatCount="indefinite" />
</use>
</mask>
<mask id="tail-03" maskUnits="userSpaceOnUse">
<use style="fill:none;stroke:#fff;stroke-width:2;stroke-dasharray:100% -100%" xlink:href="#loop-03">
<animate attributeName="stroke-dashoffset" from="100%" to="-100%" dur="10s" repeatCount="indefinite" />
</use>
</mask>
<mask id="tail-04" maskUnits="userSpaceOnUse">
<use style="fill:none;stroke:#fff;stroke-width:2;stroke-dasharray:100% -100%" xlink:href="#loop-04">
<animate attributeName="stroke-dashoffset" from="100%" to="-100%" dur="10s" repeatCount="indefinite" />
</use>
</mask>
</defs>
<g style="mask:url(#tail-01)">
<circle style="fill:url(#fade-01);" cx="0" cy="0" r="200">
<animateMotion keyPoints="0;1" keyTimes="0;1" dur="10s" repeatCount="indefinite">
<mpath xlink:href="#loop-01" />
</animateMotion>
</circle>
</g>
<g style="mask:url(#tail-02)">
<circle style="fill:url(#fade-02);" cx="0" cy="0" r="200">
<animateMotion keyPoints="0;1" keyTimes="0;1" dur="10s" repeatCount="indefinite">
<mpath xlink:href="#loop-02" />
</animateMotion>
</circle>
</g>
<g style="mask:url(#tail-03)">
<circle style="fill:url(#fade-02);" cx="0" cy="0" r="200">
<animateMotion keyPoints="0;1" keyTimes="0;1" dur="10s" repeatCount="indefinite">
<mpath xlink:href="#loop-03" />
</animateMotion>
</circle>
</g>
<g style="mask:url(#tail-04)">
<circle style="fill:url(#fade-01);" cx="0" cy="0" r="200">
<animateMotion keyPoints="0;1" keyTimes="0;1" dur="10s" repeatCount="indefinite">
<mpath xlink:href="#loop-04" />
</animateMotion>
</circle>
</g>
<rect x="833.5" y="-648.5" width="833" height="1318" rx="416.5" stroke="white" stroke-opacity="0.08" />
<rect x="834.5" y="670.5" width="833" height="1318" rx="416.5" stroke="white" stroke-opacity="0.08" />
<rect x="1.5" y="670.5" width="833" height="1318" rx="416.5" stroke="white" stroke-opacity="0.08" />
<rect x="0.5" y="-648.5" width="833" height="1318" rx="416.5" stroke="white" stroke-opacity="0.08" />
</svg>

SMIL Animation Not Ending On Mouseout

I'm trying to make an SVG icon that animates using SMIL (well, I don't care if it's SMIL or CSS, I just don't want to use JS) on hover and I've gotten pretty far but I've run into a problem that I can't find answered or even mentioned online. The animation starts on mouseover (hover) but on mouseout one of the animated elements (2nd circle) keeps animating and I'm at a total loss as to why.
You can also see it at https://codepen.io/anon/pen/LmjpVQ
Thanks for any help you can provide in advance.
svg { width: 100px; color: red; }
<svg id="location" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60">
<defs>
<clipPath id="circleClip">
<path d="M49,19c0,7-12,26-18.97,26C23,45,12,26,12,19H49z M72-12h-84v84h84V-12z" />
</clipPath>
</defs>
<g clip-path="url(#circleClip)">
<g transform="matrix(1, 0, 0, 0.43999, 0, 25.2)">
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="14">
<animate attributeType="XML" attributeName="r" from="0" to="20" begin="location.mouseover" end="location.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="location.mouseover" end="location.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="0">
<animate ttributeType="XML" attributeName="r" from="0" to="20" begin="location.mouseover+2s" end="location.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="location.mouseover+2" end="location.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
</g>
</g>
<path fill="currentColor" stroke="currentColor" stroke-width="0" d="M30,7c7.18,0,13,5.82,13,13S30,45,30,45S17,27.18,17,20S22.82,7,30,7z" />
<path fill="#fff" stroke-width="0" d="M30,15c2.76,0,5,2.24,5,5s-2.24,5-5,5c-2.76,0-5-2.24-5-5S27.24,15,30,15" />
</svg>
The trap you got caught in was that, unlike HTML elements, mouse events are raised as a default only when the pointer is over an area that is painted (stroke or fill)., but no matter what opacity is set to. You can even fine-tune pointer-events to either include or exclude events for visibility: hidden or fill: none.
The mouseover event is raised every time the spreading circle you animated passes under the pointer, With pointer-events:all you could prevent mousout when the mouse ends up over the interior, but only until the animation repeat resets the radius. This makes things pretty confusing.
The most simple solution is to lay an invisible rect with opacity="0" on top of the whole icon, so that there are clearly defined borders for "inside" and "outside". For more finetuning, define a shape that covers the area where you want to capture mouse moves.
svg { width: 100px; color: red; }
<svg id="loc" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60">
<defs>
<clipPath id="c">
<path d="M49,19c0,7-12,26-18.97,26C23,45,12,26,12,19H49z M72-12h-84v84h84V-12z" />
</clipPath>
</defs>
<g clip-path="url(#c)">
<g transform="matrix(1, 0, 0, 0.43999, 0, 25.2)">
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="14">
<animate attributeType="XML" attributeName="r" from="0" to="20" begin="loc.mouseover" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="loc.mouseover" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="0">
<animate ttributeType="XML" attributeName="r" from="0" to="20" begin="loc.mouseover+2s" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="loc.mouseover+2" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
</g>
</g>
<path fill="currentColor" stroke="currentColor" d="M30,7c7.18,0,13,5.82,13,13S30,45,30,45S17,27.18,17,20S22.82,7,30,7z" />
<path fill="#fff" d="M30,15c2.76,0,5,2.24,5,5s-2.24,5-5,5c-2.76,0-5-2.24-5-5S27.24,15,30,15" />
<rect opacity="0" width="100%" height="100%" />
</svg>

svg fill animation does not work in firefox

Does anybody know why this code doesnt work in FF ? In chrome everything is ok but not in FF. The dots dont fill with the white color, just stay unfilled.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 129.57 26.18">
<defs>
<style>.cls-1{fill:none;stroke:#fff;stroke-miterlimit:10;stroke-width:2px;}</style>
</defs>
<title>kropeczki</title>
<g id="Warstwa_2" data-name="Warstwa 2">
<g id="Layer_1" data-name="Layer 1">
<circle class="cls-1" cx="13.09" cy="13.09" r="12.09">
<animate
attributeName="fill" from="none" to="#fff" begin="0.7" dur=".1s" fill="freeze" repeatCount="1"/>
</circle>
<circle class="cls-1" cx="64.79" cy="13.09" r="12.09">
<animate
attributeName="fill" from="none" to="#fff" begin="1" dur=".1s" fill="freeze" repeatCount="1"/>
</circle>
<circle class="cls-1" cx="116.49" cy="13.09" r="12.09">
<animate
attributeName="fill" from="none" to="#fff" begin="1.3" dur=".1s" fill="freeze" repeatCount="1"/>
</circle>
</g>
</g>
</svg>
Considering that SMIL doesn't work cross browser, may I suggest you use CSS animation instead
Animate the color none won't work, use transparent
body {
background: gray;
}
.cls-1 {
fill: transparent;
stroke: #fff;
stroke-miterlimit: 10;
stroke-width: 2px;
-webkit-animation-name: setcolor;
-webkit-animation-duration: 2s;
-webkit-animation-fill-mode: forwards;
animation-name: setcolor;
animation-duration: 2s;
animation-fill-mode: forwards;
}
.cls-1:nth-child(2) {
-webkit-animation-delay: .5s;
animation-delay: .5s;
}
.cls-1:nth-child(3) {
-webkit-animation-delay: 1s;
animation-delay: 1s;
}
#keyframes setcolor {
100% {
fill: white;
}
}
#-webkit-keyframes setcolor {
100% {
fill: white;
}
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 129.57 26.18">
<title>kropeczki</title>
<g id="Warstwa_2" data-name="Warstwa 2">
<g id="Layer_1" data-name="Layer 1">
<circle class="cls-1" cx="13.09" cy="13.09" r="12.09">
</circle>
<circle class="cls-1" cx="64.79" cy="13.09" r="12.09">
</circle>
<circle class="cls-1" cx="116.49" cy="13.09" r="12.09">
</circle>
</g>
</g>
</svg>
Note, since Chrome favor CSS/Web animations over SMIL, the future of SMIL might be somewhat unpredictable, so I would recommend to wait using it until its future is more secured.
According to the SVG and SMIL specifications durations are not allowed to start with a full stop. Adding a leading 0 as the specification demands so that .7 becomes 0.7 fixes things in Firefox.
I've also added a background rect as white on white does not show up too well in a snippet.
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 129.57 26.18">
<defs>
<style>.cls-1{fill:none;stroke:#fff;stroke-miterlimit:10;stroke-width:2px;}</style>
</defs>
<title>kropeczki</title>
<g id="Warstwa_2" data-name="Warstwa 2">
<rect width="100%" height="100%" fill="black"/>
<g id="Layer_1" data-name="Layer 1">
<circle class="cls-1" cx="13.09" cy="13.09" r="12.09">
<animate
attributeName="fill" from="none" to="#fff" begin="0.7" dur="0.1s" fill="freeze" repeatCount="1"/>
</circle>
<circle class="cls-1" cx="64.79" cy="13.09" r="12.09">
<animate
attributeName="fill" from="none" to="#fff" begin="1" dur="0.1s" fill="freeze" repeatCount="1"/>
</circle>
<circle class="cls-1" cx="116.49" cy="13.09" r="12.09">
<animate
attributeName="fill" from="none" to="#fff" begin="1.3" dur="0.1s" fill="freeze" repeatCount="1"/>
</circle>
</g>
</g>
</svg>

SVG <animate> offset from 0 not working

The purpose of the animation is that fill background colour as loading battery. The solution seems to me apple gradient animation which shows as loading. But in the current SVG linearGradient animate not working when attribute offset="0%"
div {
float: left;
width: 50%;
padding: 10px;
box-sizing: border-box;
}
<div>
<p><small>offset from 0%</small> <strong>not working</strong></p>
<svg viewBox="0 0 110 88" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="mysvg">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group" fill="#EAEAEA">
<rect id="Brick-4" x="77.5" y="10" width="13.5" height="68" rx="3"></rect>
<rect id="Brick-3" x="56" y="10" width="13.5" height="68" rx="3"></rect>
<rect id="Brick-2" x="34.5" y="10" width="13.5" height="68" rx="3"></rect>
<rect id="Brick-1" x="13" y="10" width="13.5" height="68" rx="3"></rect>
<path d="M104,30.2724875 C104.164709,30.2576038 104.331485,30.25 104.5,30.25 C107.537566,30.25 110,32.7220822 110,35.7458573 L110,53.1708094 C110,56.2060875 107.531385,58.6666667 104.5,58.6666667 C104.331455,58.6666667 104.164681,58.6590557 104,58.6441617 L104,82.0033234 C104,85.3151964 101.311488,88 97.9970362,88 L6.0029638,88 C2.68761844,88 0,85.3182852 0,82.0033234 L0,5.99667663 C0,2.68480358 2.68851188,0 6.0029638,0 L97.9970362,0 C101.312382,0 104,2.68171476 104,5.99667663 L104,30.2724875 L104,30.2724875 Z M5,10.991014 C5,7.68226832 7.68678744,5 11.0051618,5 L92.9948382,5 C96.3113975,5 99,7.68493655 99,10.991014 L99,77.008986 C99,80.3177317 96.3132126,83 92.9948382,83 L11.0051618,83 C7.68860254,83 5,80.3150634 5,77.008986 L5,10.991014 Z"
fill="url(#fromzero)
"></path>
<defs>
<linearGradient id="fromzero" x1="0">
<stop offset="0%" stop-color="#4c7eaf"></stop>
<stop offset="0%" stop-color="#828282"></stop>
<animate attributeName="x1" dur="5s" from="0%" to="100%" repeatCount="indefinite" />
</linearGradient>
</defs>
</g>
</g>
</svg>
</div>
<div>
<p><small>offset from 1%</small> <strong>working</strong></p>
<svg viewBox="0 0 110 88" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="mysvg">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group" fill="#EAEAEA">
<rect id="Brick-4" x="77.5" y="10" width="13.5" height="68" rx="3"></rect>
<rect id="Brick-3" x="56" y="10" width="13.5" height="68" rx="3"></rect>
<rect id="Brick-2" x="34.5" y="10" width="13.5" height="68" rx="3"></rect>
<rect id="Brick-1" x="13" y="10" width="13.5" height="68" rx="3"></rect>
<path d="M104,30.2724875 C104.164709,30.2576038 104.331485,30.25 104.5,30.25 C107.537566,30.25 110,32.7220822 110,35.7458573 L110,53.1708094 C110,56.2060875 107.531385,58.6666667 104.5,58.6666667 C104.331455,58.6666667 104.164681,58.6590557 104,58.6441617 L104,82.0033234 C104,85.3151964 101.311488,88 97.9970362,88 L6.0029638,88 C2.68761844,88 0,85.3182852 0,82.0033234 L0,5.99667663 C0,2.68480358 2.68851188,0 6.0029638,0 L97.9970362,0 C101.312382,0 104,2.68171476 104,5.99667663 L104,30.2724875 L104,30.2724875 Z M5,10.991014 C5,7.68226832 7.68678744,5 11.0051618,5 L92.9948382,5 C96.3113975,5 99,7.68493655 99,10.991014 L99,77.008986 C99,80.3177317 96.3132126,83 92.9948382,83 L11.0051618,83 C7.68860254,83 5,80.3150634 5,77.008986 L5,10.991014 Z"
fill="url(#fromone)
"></path>
<defs>
<linearGradient id="fromone" x1="0">
<stop offset="1%" stop-color="#4c7eaf"></stop>
<stop offset="1%" stop-color="#828282"></stop>
<animate attributeName="x1" dur="5s" from="0%" to="100%" repeatCount="indefinite" />
</linearGradient>
</defs>
</g>
</g>
</svg>
</div>
Chaning the code to this
<linearGradient id="fromzero" x1="0">
<stop offset="50%" stop-color="#4c7eaf"></stop>
<stop offset="50%" stop-color="#828282"></stop>
<animate attributeName="x1" dur="5s" from="-100%" to="100%" repeatCount="indefinite" />
</linearGradient>
Makes the gradient split the background-color in the two colors, and moves it from -100% to 100%, making it possible to go from 0% to 100%, while giving it the exact same effect.
I've now also added the animation you wanted. It is being triggered by clicking on the svg element.
Here's a Fiddle of the result
Hope this helps

Resources