Animating SVG with CSS - css

I have a simple line SVG that is animating correctly. The problem is that on first load the SVG paths show and then disappear prior to the start.I have tried setting opacity on st1 and st2 to 0 and then keyframes to to opacity 1. This kind of works, but the SVG then disappears after it is run.
Am I missing something simple?
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 485 500.9" style="enable-background:new 0 0 485 500.9;" xml:space="preserve">
<style type="text/css">
.st0{clip-path:url(#SVGID_2_);fill:none;stroke:#FFFFFF;stroke-dasharray: 1000;
animation: draw 4s normal ease-in;}
.st1{clip-path:url(#SVGID_2_);fill:none;stroke:#FFFFFF;stroke-dasharray: 1000;
animation: draw 4s normal ease-in;animation-delay: 1s;}
.st2{clip-path:url(#SVGID_2_);fill:none;stroke:#FFFFFF;stroke-dasharray: 1000;
animation: draw 4s normal ease-in;animation-delay: 3s;}
#keyframes draw {
from {
stroke-dashoffset: -1000;
}
to {
stroke-dashoffset: 0;
}
}
</style>
<g>
<defs>
<rect id="SVGID_1_" x="-0.1" y="0" width="485" height="501"/>
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" style="overflow:visible;"/>
</clipPath>
<path class="st0" d="M0.4,97.4c0-14.2,14.2-14.2,14.2-14.2H100l5.1,0h86.3c0,0,14.2,0,14.2-14.2V36.4V0"/>
<path class="st1" d="M207.5,236.3l0-31.3c0,0,0-14.2-14.2-14.2h-15.1l-142.8,0.1H14.6c-14.2,0-14.2-14.2-14.2-14.2V103"/>
<path class="st2" d="M484.9,500.5H221.8c-14.2,0-14.2-14.2-14.2-14.2l-0.1-242.6"/>
</g>
</svg>
See:
https://jsfiddle.net/suLkr4po/
How do I restructure this so each path comes in after the other has finished from top to bottom?

Add animation-fill-mode: backwards to the style of the animated elements. That will apply the start value before the animation is started.

Related

Animate SVG fill shape by following the form

i wonder how to fill a form continously with html5/css3 to create a loading icon (spinner).
The fill should follow the red line (3) and leave the shape in same direction when it reaches the end (6)
If it would be a thin line i could work with fake line animation, but how i can do this with a thicker shape like this?
<svg version="1.1" id="Loader" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 255 255" style="enable-background:new 0 0 255 255; width: 255px; height: 255px" xml:space="preserve">
<g>
<path d="M169.9,73.6c9,6.2,15.3,14.9,20,23.3c4.7,8.3,7.1,17.2,7.1,26.7c0,4.9-0.7,9.6-2.1,14c-1.4,4.5-3.5,8.7-6.3,12.6
c-7.1,9.8-16.7,17.7-28.7,23.6c-12.1,5.9-24.7,8.9-37.8,8.9c-7.9,0-15.5-1.6-23-4.8c-7.5-3.2-14.2-7.8-20.1-13.7
c-5.8-6-10.4-12.6-13.5-20.1c-3.2-7.4-4.8-15-4.8-22.8c0-10.4,3.1-20.1,9.2-29.1c6.1-9,15.5-17.5,28-25.5c0,0,5.8-4.2,10.9-4.2
c5.1,0,11.1,3.1,6.6,10.3c-4.5,7.2-6.8,14.3-6.8,21.1c0,6.7,2.3,12.4,6.8,16.8c4.5,4.5,10.2,6.7,17,6.7c6.2,0,11.4-2.3,15.6-7
c4.1-4.7,6.2-10.6,6.2-17.7c0-4.9-1-9.5-3-13.7c-2-4.3-1.3-10.6,4.2-11.5C160.7,66.7,169.9,73.6,169.9,73.6z"/>
</g>
</svg>
The main idea is using a very thick line with a changing stroke-dashoffset. I clip the line with your path.
In order to understand it better you may remove the clip-path attribute.
I'm using an input type range to change the value of the stroke-dashoffset
itr.addEventListener("input",()=>{pth.setAttribute("stroke-dashoffset",itr.value)})
<p><input type="range" min="0" max="235" value="235" id="itr"/></p>
<svg version="1.1" id="Loader" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 255 255" style="enable-background:new 0 0 255 255; width: 255px; height: 255px" xml:space="preserve">
<clipPath id="clip">
<path d="M169.9,73.6c9,6.2,15.3,14.9,20,23.3c4.7,8.3,7.1,17.2,7.1,26.7c0,4.9-0.7,9.6-2.1,14c-1.4,4.5-3.5,8.7-6.3,12.6
c-7.1,9.8-16.7,17.7-28.7,23.6c-12.1,5.9-24.7,8.9-37.8,8.9c-7.9,0-15.5-1.6-23-4.8c-7.5-3.2-14.2-7.8-20.1-13.7
c-5.8-6-10.4-12.6-13.5-20.1c-3.2-7.4-4.8-15-4.8-22.8c0-10.4,3.1-20.1,9.2-29.1c6.1-9,15.5-17.5,28-25.5c0,0,5.8-4.2,10.9-4.2
c5.1,0,11.1,3.1,6.6,10.3c-4.5,7.2-6.8,14.3-6.8,21.1c0,6.7,2.3,12.4,6.8,16.8c4.5,4.5,10.2,6.7,17,6.7c6.2,0,11.4-2.3,15.6-7
c4.1-4.7,6.2-10.6,6.2-17.7c0-4.9-1-9.5-3-13.7c-2-4.3-1.3-10.6,4.2-11.5C160.7,66.7,169.9,73.6,169.9,73.6z"/>
</clipPath>
<path id="pth" fill="none" stroke-dasharray="235" stroke-dashoffset="235" stroke="rgb(250,0,0)" stroke-width="72" d="M115,60C15,175 235,175 155,65" clip-path="url(#clip)" />
</svg>
UPDATE
The OP is commenting:
Is it possible to leave the scale-input and animate the filling so the fillup is automatically and when reaching the end that the fill is removing the same direction and when the filling stroke is then empty again, then start from beginning?
For this I'm animating the stroke-dashoffset of the red line from 235 to -235. This way after animating all the dash (from 235 to 0) the animation follows (from 0 to -235) and the gap is now visible.
#keyframes anim {
100% {
stroke-dashoffset: -235;
}
}
#pth {
animation: anim 5s linear infinite;
}
<svg version="1.1" id="Loader" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 255 255" style="enable-background:new 0 0 255 255; width: 255px; height: 255px" xml:space="preserve">
<clipPath id="clip">
<path id="base" d="M169.9,73.6c9,6.2,15.3,14.9,20,23.3c4.7,8.3,7.1,17.2,7.1,26.7c0,4.9-0.7,9.6-2.1,14c-1.4,4.5-3.5,8.7-6.3,12.6
c-7.1,9.8-16.7,17.7-28.7,23.6c-12.1,5.9-24.7,8.9-37.8,8.9c-7.9,0-15.5-1.6-23-4.8c-7.5-3.2-14.2-7.8-20.1-13.7
c-5.8-6-10.4-12.6-13.5-20.1c-3.2-7.4-4.8-15-4.8-22.8c0-10.4,3.1-20.1,9.2-29.1c6.1-9,15.5-17.5,28-25.5c0,0,5.8-4.2,10.9-4.2
c5.1,0,11.1,3.1,6.6,10.3c-4.5,7.2-6.8,14.3-6.8,21.1c0,6.7,2.3,12.4,6.8,16.8c4.5,4.5,10.2,6.7,17,6.7c6.2,0,11.4-2.3,15.6-7
c4.1-4.7,6.2-10.6,6.2-17.7c0-4.9-1-9.5-3-13.7c-2-4.3-1.3-10.6,4.2-11.5C160.7,66.7,169.9,73.6,169.9,73.6z" />
</clipPath>
<use href="#base" />
<path id="pth" fill="none" style="stroke-dasharray:235; stroke-dashoffset:235;" stroke="rgb(250,0,0)" stroke-width="72" d="M115,60C15,175 235,175 155,65" clip-path="url(#clip)" />
</svg>

Rotating an SVG element using CSS :hover leads to element being translated [duplicate]

I'm having issues with the transform-origin while attempting to scale sub-elements.
While attempting to scale animate a box within a larger svg, it uses the transform origin (0,0) from the overall svg, rather than the center of the element I am trying to scale.
This makes it appear like it is "flying in from the top left" which is not what I am looking for. I am looking to make it scale from the elements center.
How do I get the transform-origin to be set relative to the specific element I am animating, without having to hardcode the (x,y) position of the sub-element itself.
Here is a simple example of the issue I'm dealing
#keyframes scaleBox {
from {transform: scale(0);}
to {transform: scale(1);}
}
#animated-box {
animation: scaleBox 2s infinite;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" style="
width: 195px;
"><defs>
<style>.cls-1{fill:#7f7777;}.cls-2{fill:#fff;}</style>
</defs>
<rect class="cls-1" x="0.5" y="0.5" width="99" height="99"></rect>
<path d="M99,1V99H1V1H99m1-1H0V100H100V0Z"></path>
<rect id="animated-box" class="cls-2" x="10.5" y="8.5" width="22" height="6"></rect></svg>
You need transform-box: fill-box;
#keyframes scaleBox {
from {transform: scale(0);}
to {transform: scale(1);}
}
#animated-box {
transform-box: fill-box;
animation: scaleBox 2s infinite;
}
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" style="
width: 195px;
"><defs>
<style>.cls-1{fill:#7f7777;}.cls-2{fill:#fff;}</style>
</defs>
<rect class="cls-1" x="0.5" y="0.5" width="99" height="99"></rect>
<path d="M99,1V99H1V1H99m1-1H0V100H100V0Z"></path>
<rect id="animated-box" class="cls-2" x="10.5" y="8.5" width="22" height="6"></rect></svg>

SVG stroke, CSS animation: not all strokes moving in the same direction

The below animation is pretty straightforward, or so I thought. You will notice that one of the strokes, and only one, starts going backwards. I fail to understand why this is the case.
.container {
width: 350px;
height: 350px;
}
#path1 {
stroke-dasharray: 170;
animation: animate1 5s infinite linear forwards;
}
#keyframes animate1 {
50% {
stroke-dashoffset: -16.4%;
stroke-dasharray: 0 87.5%;
}
100% {
stroke-dashoffset: -100%;
stroke-dasharray: 170;
}
}
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="100%" height="100%" viewBox="0 0 1000 1000" xml:space="preserve">
<a xlink:href="#">
<path id="path2" fill="#000" d="M173,226h400v400H173V226z"/>
<path id="path1" fill="none" stroke="#000" d="M108,171h500v500H108V171z"/>
</a>
</svg>
</div>
Thanks for the help, appreciate any pointers.
The total length of the path path1 is 2000 px
If you want to get 4 segments with 4 equal intervals, then the length of one stroke will be equal to one eighth of the total length: 2000 / 8 = 250 px
In this case, write stroke-dasharray = "250, 250"
Animation is achieved by reducing the stroke-dashoffset from2000px to zero
.container {
width: 350px;
height: 350px;
}
#path1 {
stroke-dasharray: 250;
stroke-dashoffset:2000;
animation: animate1 5s infinite linear forwards;
}
#keyframes animate1 {
100% {
stroke-dashoffset: 0;
stroke-dasharray: 250;
}
}
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="100%" height="100%" viewBox="0 0 1000 1000" xml:space="preserve">
<a xlink:href="#">
<path id="path2" fill="#000" d="M173,226h400v400H173V226z"/>
<path id="path1" fill="none" stroke="#000" d="M108,171h500v500H108V171z"/>
</a>
</svg>
</div>
SVG solution
<style>
.container {
width: 350px;
height: 350px;
}
</style>
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="100%" height="100%" viewBox="0 0 1000 1000" xml:space="preserve">
<a xlink:href="#">
<path id="path2" fill="#000" d="M173,226h400v400H173V226z"/>
<path id="path1" fill="none" stroke="#000" stroke-dasharray="250,250" stroke-dashoffset="2000" d="M108,171h500v500H108V171z">
<animate
attributeName="stroke-dashoffset"
from="2000"
to="0"
dur="5s"
repeatCount="indefinite" />
</path>
</a>
</svg>
</div>

How to animate a SVG text but not linear?

I have a text logo in SVG and I want to animate the whole text not just the outline. Is there any way to do this? I can show you the code working and I'm including it below too.
<svg version="1.1" id="logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="50%" height="50%;" viewBox="0 0 912 212" style="enable-background:new 0 0 912 212;" xml:space="preserve">
<defs>
<style type="text/css">
.st0{fill:none;stroke:#19a4dd;}
.st0{
stroke-dasharray: 2000;
stroke-dashoffset: 0;
-webkit-animation: dash 10s linear forwards;
-o-animation: dash 10s linear forwards;
-moz-animation: dash 10s linear forwards;
animation: dash 10s linear forwards;
}
#-webkit-keyframes dash {
from{
stroke-dashoffset: 2000;
}
to{
stroke-dashoffset: 0;
}
}
</style>
</defs>
<g>
<path class="st0" d="M195.683,105.006c0.077,12.928,9.039,25.168,26.274,25.245c8.196,0,14.708-2.907,21.065-9.716l-4.979-3.978
c-4.443,4.896-10.035,7.727-16.24,7.65c-10.188,0-17.695-6.656-19.074-15.759c0,0-0.23-1.989-0.306-3.672
c0-1.607,0.23-3.748,0.306-3.748c0.843-7.191,6.435-15.3,17.618-15.3c9.422,0,16.699,6.503,17.618,15.3l0.153,1.147h-13.559v4.973
h21.065c-0.46-16.677-10.648-27.387-25.202-27.464C205.411,79.837,195.683,91.236,195.683,105.006"/>
<path class="st0" d="M115.404,79.837c-15.244,0-26.121,11.628-26.121,25.245c0,13.77,10.265,25.092,26.121,25.092
s26.045-11.322,26.121-25.092C141.525,91.465,130.648,79.837,115.404,79.837 M115.481,132.316L115.481,132.316L115.481,132.316
M96.407,105.006c0-11.016,8.809-19.278,18.997-19.278s18.997,8.262,18.997,19.278c0,10.251-8.733,19.125-18.997,19.201
C105.139,124.207,96.483,115.257,96.407,105.006"/>
<path class="st0" d="M168.795,86.339c4.596,0,7.89,1.836,9.882,4.667c1.992,2.831,2.834,6.579,2.834,10.481v28.076h6.511V98.197
c0-6.503-2.451-10.863-6.052-13.693c-3.6-2.831-8.426-4.131-13.099-4.131s-9.652,1.301-13.405,4.131
c-3.753,2.831-6.358,7.191-6.358,13.693v31.365h6.511v-28.076c0-3.902,0.766-7.65,2.834-10.481
c1.992-2.831,5.362-4.667,9.882-4.667H168.795"/>
<path class="st0" d="M260.181,83.968c-3.753,2.831-6.358,7.191-6.358,13.693v31.365h6.511v-28.076c0-3.902,0.766-7.65,2.834-10.481
c1.992-2.831,5.362-4.667,9.882-4.667h0.153v-5.967C268.684,79.913,263.858,81.214,260.181,83.968"/>
<g>
<path class="st0" d="M40.028,129.103h19.61c7.967,0,13.635-3.213,17.465-7.803s5.669-10.71,5.669-16.371
s-1.915-11.781-5.669-16.371c-3.83-4.59-9.499-7.803-17.465-7.803h-19.61l6.358,6.12h10.571c4.979,0,9.728,1.301,13.329,4.208
c3.6,2.907,5.898,7.421,5.898,13.158l0,0v1.301l0,0c0,5.737-2.298,10.251-5.898,13.158c-3.6,2.907-8.35,4.284-13.329,4.284H40.028
V129.103z"/>
</g>
</g>
</svg>
I want the final effect to look like this.
Increase the stroke-width so it fills the shape and put a clip-path on the shape (use copy of the shape with the original stroke-width) so the stroke-width does not make the shape appear too bold.

Line animate SVG, animation not working

Ive been following tutorials and i cannot figure out why the line animation is not working, the dash offset and dash array seem to be working but the animation is not.
here is the js fiddle : http://jsfiddle.net/jp2ttb5L/5/
<style>
.path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear forwards;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
</style>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<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 1440 1080" enable-background="new 0 0 1440 1080" xml:space="preserve">
<g id="Layer_3">
<polygon class="path" fill="none" stroke="#000000" stroke-width="4" stroke-linejoin="round" stroke-miterlimit="10" points="411.3,540.5
76.3,1043 411.3,1043 746.3,1043 "/>
<polygon class="path" fill="none" stroke="#000000" stroke-width="4" stroke-linejoin="round" stroke-miterlimit="10" points="746.3,38.5
411.3,541 746.3,541 1081.2,541 "/>
<polygon class="path" fill="none" stroke="#000000" stroke-width="4" stroke-linejoin="round" stroke-miterlimit="10" points="746.3,1043.5
411.3,541 746.3,541 1081.2,541 "/>
<polygon class="path" fill="none" stroke="#000000" stroke-width="4" stroke-linejoin="round" stroke-miterlimit="10" points="1081.2,540.5
746.3,1043 1081.2,1043 1416.2,1043 "/>
</g>
</svg>
For google Chrome and other browser webkit based you can use -webkit to solve this issue:
.path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear forwards;
-webkit-animation: dash 5s linear forwards;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
#-webkit-keyframes dash {
to {
stroke-dashoffset: 0;
}
}

Resources