CSS Animate SVG stroke stop at last frame - css

CodePen
In the above codepen there is an SVG that the stroke animates into view, but at the end it just disappears.
Is there a way to keep it into view once its loaded?
.path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear alternate;
}
#keyframes dash {
from {
stroke-dashoffset: 1000;
}
to {
stroke-dashoffset: 0;
}
}

add these two properties to your .path
animation-fill-mode: forwards; // Stay on the last frame
animation-iteration-count: 1;// Run only once
Css will be:
.path {
stroke-dasharray: 1000;
stroke-dashoffset: 1000;
animation: dash 5s linear alternate;
animation-fill-mode: forwards; // Stay on the last frame
animation-iteration-count: 1;
}
Codepen is Here,its working fine.

This is not exactly what the OP asked for, but in case you wish to use svg's <animate> tag for your animation and encountered the same issue, you can use the fill attribute. Like this:
<animate ... fill="freeze"/>
This will freeze the animation at its last frame on completion. For example:
<svg viewBox="-5 -5 100 20" xmlns="http://www.w3.org/2000/svg">
<rect width="90" height="10">
<animate attributeName="width" values="0;90" dur="3s" repeatCount="1" fill="freeze"/>
</rect>
</svg>
See reference here.

Related

Animation-delay property isn't working in loop

I want to make an animation where each path is displayed one after the other and that over and over again. (Loop)
I have used these 2 Properties:
"animation-delay: 1s;"
and
"animation-iteration-count: infinite;"
:root{
--pink: #e6187e;
--green-100: green;
--white: white;
}
body{
background-color: #1f2937;
}
#keyframes fadeInOut {
0% {opacity: 0;}
100% {opacity: 1;}
}
.octagon.animate{
.octagon_outline1,
.octagon_outline2,
.octagon_outline3{
animation-name: fadeInOut;
animation-iteration-count: infinite;
animation-timing-function: ease;
animation-direction: reverse;
animation-fill-mode: forwards;
}
.octagon_outline1{animation-duration: 1s; animation-delay: 1s;}
.octagon_outline2{animation-duration: 1s; animation-delay: 2s;}
.octagon_outline3{animation-duration: 1s; animation-delay: 3s;}
}
<svg xmlns="http://www.w3.org/2000/svg" class="octagon animate" viewBox="0 0 500 480">
<path d="m189.06 102.25 120.95-.04 84.83 80.68v114.99l-84.81 80.56H189.05l-84.89-80.55V182.8l84.9-80.55z" class="octagon_center"/>
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="23" d="M179.31 79.05 319.7 79l98.46 94.25v134.31l-98.43 94.12H179.3l-98.53-94.1V173.14l98.54-94.09z" class="octagon_outline octagon_outline1"/>
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="23" d="m165.22 46.51 169.27-.06L453.2 160.33v162.29L334.52 436.34H165.21l-118.8-113.7V160.2L165.22 46.51z" class="octagon_outline octagon_outline2"/>
<path fill="none" stroke="#000" stroke-miterlimit="10" stroke-width="23" d="m150.71 11.57 198.33-.07 139.08 134.29v191.37l-139.05 134.1H150.69L11.5 337.18V145.63L150.71 11.57z" class="octagon_outline octagon_outline3"/>
</svg>
But the command "animation-delay: 1s;" is only shown in the first run and is not used after that.
You can find my code here:
https://codepen.io/bastidesign/pen/eYyxZao
It have to look like this: gif animation Octagon
Could you help me out?
The animation-delay property delays the start of the animation only, but after it’s started it runs continuously. What you want is to have a delay between iterations, which is doable but not using animation-delay, it's not a straightforward thing.
Here's a solution that could get the job done: CSS Keyframe Animation with Delay Between Iterations

Odd shape SVG Animation

I have this so far on codepen
https://codepen.io/phfilly/pen/gXbmmO?editors=1100
<div class="container">
<svg viewBox="-5 0 62.772 74.316" class="logo">
<path d="M43.034,33.66" class="logo-line"></path>
<path d="M9.607,33.012" class="logo-line-1"></path>
<path class="logo-line-two" d="M26.256,54.721c-9.245,0-16.766-7.59-16.766-16.92c0-4.496,1.729-8.73,4.867-11.921L33.171,6.882l5.514,5.561
l-6.921,6.99l6.344,6.4c0,0,0,0.001,0.001,0.001l0.002,0.002c3.168,3.196,4.911,7.445,4.911,11.964
C43.021,47.129,35.501,54.721,26.256,54.721z M26.253,24.995l-6.373,6.436c-1.67,1.698-2.595,3.965-2.595,6.37
c0,4.992,4.024,9.054,8.97,9.054c4.946-0.001,8.972-4.062,8.972-9.054c0-2.419-0.934-4.692-2.631-6.404L26.253,24.995z"></path>
<path class="logo-line-three" d="M26.387,64.316c-7.049,0-13.675-2.77-18.659-7.799C2.744,51.488-0.001,44.801,0,37.688
c0-7.076,2.722-13.739,7.663-18.763L26.394,0l5.515,5.56L13.186,24.476c-3.474,3.532-5.391,8.227-5.391,13.212
c0,5.012,1.933,9.725,5.444,13.268c3.511,3.543,8.181,5.494,13.147,5.494c10.252,0,18.591-8.416,18.591-18.762
c0-5.015-1.936-9.729-5.45-13.272h0.001l-9.11-9.192l5.512-5.564l9.114,9.199c4.984,5.028,7.729,11.715,7.729,18.83
C52.772,52.37,40.936,64.316,26.387,64.316z"></path>
</svg></div>
.logo path {
/* fill: #ff5825; */
/* transition: fill 0.5s; */
}
.container {
width: 100px;
display: block;
margin: auto;
padding: 50px 15px;
}
.logo-line-two, .logo-line-three {
fill: transparent;
stroke: #ff5825;
stroke-width: 1px;
stroke-dasharray: 320 320;
stroke-dashoffset: -300;
animation: dash 6s linear .5s infinite alternate;
}
#keyframes dash {
0% {
stroke-dashoffset: -300;
}
30% {
stroke-dashoffset: 0;
}
60% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: -300;
}
}
but I’m lacking a bit of knowledge on the SVG animation side of things. I would like to animate the fill colour instead (which i commented out to show the animation i’m after) and not necessarily the stroke-dash.
From my findings and research it seems that this can only be achieved by using a clipPath or is there an easier way around it? I’m not sure what attributes to use as the clipPath if that is the way.
Any help or guidelines will be greatly appreciated.
Animating fills can be messy and complicated. Since your logo consists of line segments with constant width, it makes more sense to draw it as an animated path with a stroke that matches the width of these line segments.
This is a vague approximation of what you're after; you'll have to sort out the geometry yourself.
#logo {
stroke-dasharray: 1100;
stroke-dashoffset: 1100;
animation: draw 2s forwards;
}
#keyframes draw {
to {
stroke-dashoffset: 0;
}
}
<svg width="125" height="150" viewBox="0 0 250 300">
<g transform="translate(125,170)">
<path id="logo" stroke="#000" stroke-width="30"
fill="none" stroke-linecap="butt"
d="M10.6-152.0-70.7-70.7A100 100 0 1 0 70.7-70.7L28.7
-112.7-42-42A59.4 59.4 0 1 0 42-42L10.6-73.4"
/>
</svg>
Note: If you're not sure what's going on in the <path> element, you should perhaps read up on SVG's elliptical arc commands.
The three (?) parts of your logo all have consistent width, so just redraw your logo using three thick lines rather than three outlines.

IE10 CSS Keyframes animation issue

I've create an SVG loading indicator. It works fine in Chrome et al but I can't seem to get it working in IE10 - here's the fiddle: https://jsfiddle.net/288mu88o/
#keyframes loading {
0% {
fill: red;
}
100% {
fill: yellow;
}
}
.c1, .c2, .c3, .c4, .c5, .c6, .c7, .c8, .c9, .c10, .c11, .c12, .c13, .c14, .c15 {
animation: loading 1.5s infinite;
}
.c1 {
animation-delay: 1.4s;
}
.c2 {
animation-delay: 1.3s;
}
.c3 {
animation-delay: 1.2s;
}
...
<g>
<circle fill="#D9E2E7 " cx="294.7" cy="342.1" r="3.5" class="c1" />
</g>
<g>
<circle fill="#D9E2E7 " cx="281.3" cy="344.8" r="3.5" class="c2"/>
</g>
<g>
<circle fill="#D9E2E7 " cx="270.2" cy="352.7" r="3.5" class="c3"/>
</g>
...
What am I missing?
Thanks.
IE 10 does not supprt CSS animation of SVG. You could use a third party solution like Fakesmile

How can I get an animated SVG to start "drawing itself" sooner?

I'm trying to create a loading animation with ONLY html & css that looks like an ekg readout. I have it working but I want it to start redrawing sooner (right now it completely disappears and I'd like it to start drawing the before it finishes "undrawing"
<head>
<style>
body {
background-color: #fff;
}
.path {
animation: draw 2.2s infinite ease-in-out;
-webkit-animation: draw 2.2s infinite ease-in-out;
}
#keyframes draw {
from {
stroke-dashoffset: 1100;
}
to { stroke-dashoffset: 50}
}
#-webkit-keyframes draw {
from {
stroke-dashoffset: 1100;
}
to { stroke-dashoffset: 50}
}
</style>
</head>
<div class="bg">
<svg xmlns="http://www.w3.org/2000/svg" width="670" height="236" viewBox="0 0 670 236">
<path class="path" stroke="#ca6728" stroke-width="4" stroke-linejoin="round" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="500" stroke-dashoffset="610" fill="none" d="M0,80.9h20.6c0.5,0,1.4-0.2,1.8-0.5L38,70.1
c0.5-0.3,1.2-0.3,1.6,0l12.7,9.4c0.4,0.3,1.3,0.6,1.8,0.6l13.3,0c0.6,0,1.2,0.4,1.5,0.9l6.2,11.3c0.3,0.5,0.5,0.4,0.5-0.1l4.4-90.8
c0-0.5,0.1-0.5,0.1,0l6.9,102.1c0,0.5,0.2,0.6,0.4,0l7-22.4c0.2-0.5,0.7-1,1.3-1l16.1,0c0.5,0,1.3-0.3,1.8-0.7L129,66.4
c0.4-0.4,1.1-0.3,1.5,0l13.3,13.1c0.4,0.4,1.2,0.7,1.7,0.7l20.1,0,"/>
</svg>
</div>
</html>
JS Fiddle here: https://jsfiddle.net/jzvenice/4sLw9ag9/
I think a similar effect can be achieved by playing with the stroke-dasharray values :
https://jsfiddle.net/4sLw9ag9/2/
...
stroke-dasharray="391 300" stroke-dashoffset="0"
....
#keyframes draw {
from {
stroke-dashoffset: 691;
}
to {
stroke-dashoffset: 0}
}
...
Only the first value is exact (length of the path is 391 pixels), it was detected with a line of JavaScript that is commented out and not needed for further functionality. The other value can be adjusted for what comes across best visually.
Edit - previously deleted the answer but it seems more relevant than a comment. So don't mind me undeleting with a minor update.

Vertically Align Rect Elements Inside SVG By Center of Rect

Goal:
I found a tutorial online to make a CSS3 infinite loading icon, using rectangles which grow and shrink in height. They end up appearing like:
It uses 5 divs wrapped in an outer div, and works perfectly. I want to try and recreate the effect using an SVG though, so that I can reference it with just an image, not having to add 5 HTML elements.
What I Have:
I started off with the same CSS animation code, and used 5 rects inside the svg tags. The animation works perfect, but I can't get the rectangles to be centered vertically. Since they are placed using x and y coordinates, which correspond to the top/left point of each rectangle, they are fixed to that location.
<svg version="1.1" baseProfile="full" width="250" height="250" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
<rect class="rect1" fill="black" height="30" width="6" x="0" />
<rect class="rect2" fill="black" height="30" width="6" x="10" />
<rect class="rect3" fill="black" height="30" width="6" x="20" />
<rect class="rect4" fill="black" height="30" width="6" x="30" />
<rect class="rect5" fill="black" height="30" width="6" x="40" />
</svg>
rect {
-webkit-animation: stretchdelay 1.2s infinite ease-in-out;
animation: stretchdelay 1.2s infinite ease-in-out;
alignment-baseline:bottom;
}
.rect2 {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
}
.rect3 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
}
.rect4 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
}
.rect5 {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s;
}
#-webkit-keyframes stretchdelay {
0%, 40%, 100% { -webkit-transform: scaleY(0.4) }
20% { -webkit-transform: scaleY(1.0) }
}
#keyframes stretchdelay {
0%, 40%, 100% {
transform: scaleY(0.4);
-webkit-transform: scaleY(0.4);
} 20% {
transform: scaleY(1.0);
-webkit-transform: scaleY(1.0);
}
}
See Working Example: http://codepen.io/Kelderic/pen/vuipF
One thing that is odd, it's running in CodePen, the same code doesn't run in JSFiddle. It also doesn't run when I embed the CodePen as an SVG.
Question
Is using CSS animations like this supposed to work for SVG elements, and can I fix them in the center to match the original?
Edit
js1568's answer provides what SHOULD be a fix, and it does make things work in Chrome. It has no effect in Firefox though, and after some research I've found that I'm not the only one who has had the same problem with Firefox.
Setting transform-origin on SVG group not working in FireFox
I think the only answer here is that at this time this won't work in all browsers. (If anyone does know a way, feel free to add an answer though!)
Edit 2
I figured a way to make this work in Firefox, explained in an answer below. Still no IE9-11 though.
Okay, so I figured out the answer to this, and it works in Chrome and Firefox. IE doesn't support CSS transforms on SVG elements (though it does support the transform attribute, and I'm trying to figure out a workaround).
Instead of trying to set the baseline to the center of the rect element, I just use a second animation. I move the element up and down, sync'd up time-wise. This creates the appearance that the element is centered vertically.
I had some issues getting it to sync perfectly when using the 0.4 scale, so I changed over to 0.5, which still looks good.
HTML:
<svg version="1.1" baseProfile="full" width="250" height="250" xmlns="http://www.w3.org/2000/svg" xmlns:xlink= "http://www.w3.org/1999/xlink">
<rect class="rect1" fill="black" height="30" transform="translate(2,2)" width="6" x="0" y="0" />
<rect class="rect2" fill="black" height="30" width="6" x="10" y="0" />
<rect class="rect3" fill="black" height="30" width="6" x="20" y="0" />
<rect class="rect4" fill="black" height="30" width="6" x="30" y="0" />
<rect class="rect5" fill="black" height="30" width="6" x="40" y="0" />
</svg>
CSS:
#-webkit-keyframes stretchdelay {
0% {
-webkit-transform: scaleY(1.0) translate(0,0);
} 30%,70% {
-webkit-transform: scaleY(0.5) translate(0,15px);
} 100% {
-webkit-transform: scaleY(1.0) translate(0,0);
}
}
#keyframes stretchdelay {
0% {
transform: scaleY(1.0) translate(0,0);
-webkit-transform: scaleY(1.0) translate(0,0);
} 30%,70% {
transform: scaleY(0.5) translate(0,15px);
-webkit-transform: scaleY(0.5) translate(0,15px);
} 100% {
transform: scaleY(1.0) translate(0,0);
-webkit-transform: scaleY(1.0) translate(0,0);
}
}
rect {
-webkit-animation: stretchdelay 1.2s infinite ease-in-out;
animation: stretchdelay 1.2s infinite ease-in-out;
-ms-animation: stretchdelay 1.2s infinite ease-in-out;
}
.rect2 {
-webkit-animation-delay: -1.1s;
animation-delay: -1.1s;
}
.rect3 {
-webkit-animation-delay: -1.0s;
animation-delay: -1.0s;
}
.rect4 {
-webkit-animation-delay: -0.9s;
animation-delay: -0.9s;
}
.rect5 {
-webkit-animation-delay: -0.8s;
animation-delay: -0.8s;
}
Result:
(Note, recently CodePen added a feature allowing you to embed SVGs created inline as SVG images. I found out today as I created this, that all CSS must be placed in <style> tags inside the HTML input box. If it is placed in the CSS box, it won't work.)
I have edited your codepen to include transform-origin styles:
http://codepen.io/anon/pen/ojgwr
Is this the effect you were going for?

Resources