Circles "waves" animations with CSS keyframes - html

I'm trying to animate circles to achieve an infinite effect of colliding waves.
I laid the base but I can't make the order of the animations smooth and linear.
Codepen available here.
<div class="circles-container"
<!-- 1er circle -->
<svg width="1280" height="1280" xmlns="http://www.w3.org/2000/svg" style="z-index: 1;">
<path class="circle-1" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
</svg>
<!-- 2eme circle -->
<svg width="1280" height="1280" xmlns="http://www.w3.org/2000/svg" style="z-index: 2;">
<path class="circle-2" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
</svg>
<!-- 3eme circle -->
<svg width="1280" height="1280" xmlns="http://www.w3.org/2000/svg" style="z-index: 3;">
<path class="circle-3" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
</svg>
</div>
.circles-container { position: relative; }
.circles-container svg {
position: absolute;
top: 0;
left: 0;
}
.circle-1 {
animation: scaleCircle 7.5s ease-in-out infinite;
transform: scale(0);
transition: all 2s ease-in-out;
color: #1D1D28;
}
.circle-2 {
animation: scaleCircle 5s ease-in-out infinite 2.5s;
transform: scale(0);
transition: all 2s ease-in-out;
color: #420DC4;
}
.circle-3 {
animation: scaleCircle 5s ease-in-out infinite;
transform: scale(0);
transition: all 2s ease-in-out;
color: #1D1D28;
}
#keyframes scaleCircle {
0% {
transform: scale(0);
}
100% {
transform: scale(2);
}
}
Here is the scenario:
When loading, a first blue circle is displayed.
A first black circle grows until it crushes the blue circle
at 50% of step's 1 animation, a new blue circle is displayed and enlarged until it overwrites the black circle created during step 1
back to step 1
In my render, you can see that the circles are showing but some are hiding too soon, etc. The circles should display one after the other in a linear fashion.
Is it possible to do this in full CSS with keyframes ?

Not sure if this is exactly what you are going for but maybe you can tinker with it.
So with 4 circles you can animate the scale basically the way you have it. And then for their svg container, you animate the z-index so whenever a wave starts it gets its highest z-index and then it deceases before the next wave starts.
<div class="circles-container">
<!-- 1er cercle -->
<svg class="circle-parent-1" width="1280" height="1280" xmlns="http://www.w3.org/2000/svg">
<path class="circle-1" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
</svg>
<!-- 2eme cercle -->
<svg class="circle-parent-2" width="1280" height="1280" xmlns="http://www.w3.org/2000/svg" >
<path class="circle-2" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
</svg>
<svg class="circle-parent-3" width="1280" height="1280" xmlns="http://www.w3.org/2000/svg" >
<path class="circle-3" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
</svg>
<svg class="circle-parent-4" width="1280" height="1280" xmlns="http://www.w3.org/2000/svg" >
<path class="circle-4" d="M0 0h640c0 353.466-286.534 640-640 640V0Z" fill="currentColor" fill-rule="evenodd" />
</svg>
body {
margin: 0;
padding: 0;
}
.circles-container { position: relative; }
.circles-container svg {
position: absolute;
top: 0;
left: 0;
}
.circle-parent-1 {
animation: zIndexCircle 8s ease-in-out infinite;
animation-delay: 0s;
}
.circle-parent-2 {
animation: zIndexCircle 8s ease-in-out infinite;
animation-delay: 2s;
}
.circle-parent-3 {
animation: zIndexCircle 8s ease-in-out infinite;
animation-delay: 4s;
}
.circle-parent-3 {
animation: zIndexCircle 8s ease-in-out infinite;
animation-delay: 4s;
}
.circle-parent-4 {
animation: zIndexCircle 8s ease-in-out infinite;
animation-delay: 6s;
}
.circle-1 {
animation: scaleCircle 8s ease-in-out infinite;
animation-delay:0s;
transform: scale(0);
color: #1D1D28;
}
.circle-2 {
animation: scaleCircle 8s ease-in-out infinite;
animation-delay:2s;
transform: scale(0);
color: #420DC4;
}
.circle-3 {
animation: scaleCircle 8s ease-in-out infinite;
animation-delay:4s;
transform: scale(0);
color: #1D1D28;
}
.circle-4 {
animation: scaleCircle 8s ease-in-out infinite;
animation-delay:6s;
transform: scale(0);
color: #420DC4;
}
#keyframes zIndexCircle {
0% {
z-index:5;
}
25% {
z-index: 4;
}
50% {
z-index:3;
}
75% {
z-index:2;
}
100% {
z-index:1;
}
}
#keyframes scaleCircle {
0% {
transform: scale(0);
}
75% {
transform: scale(2);
}
100% {
transform: scale(2);
}
}
https://codepen.io/todilo-the-vuer/pen/XWEmdXL

Related

How to animate a svg loader such that It grows and shrinks at certain points of the circle?

the required loader is to be of the following gif given above but needs to be implemented in a svg.
the code given below is the svg I have implemented so far but I am not able to get the required animation as that of a gif. Can somebody point out where I am going wrong or help me with how to get the animations right. Thanks in advance
svg{
width: 250px;
height: 250px;
position: relative;
}
/* .circles{
transform: rotate(-90deg);
} */
#inner{
stroke-dasharray: 314 314;
stroke-dashoffset: 314;
transform: rotate(-90deg);
transform-origin: 50% 50%;
/* animation: rotate 2s linear infinite; */
animation: animate 2s ease-in-out infinite;
}
#keyframes animate{
0%,100%{
stroke-dashoffset: 314;
}
50%{
stroke-dashoffset: 0;
}
50.1%{
stroke-dashoffset: 628 ;
}
}
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="svg.css">
<title>Document</title>
</head>
<body>
<svg>
<g class="circles">
<circle cx="125" cy="125" r="50" fill="none" stroke-width="15px" stroke="#E0E3E9">
</circle>
<circle id="inner" cx="125" cy="125" r="50" fill="none" stroke-width="12px" stroke="#6B04A8">
</circle>
</g>
</svg>
</body>
</html>
I hope this is what you need: instead of animating the stroke-dashoffset I'm animating the stroke-dasharray
svg {
width: 250px;
height: 250px;
position: relative;
}
/* .circles{
transform: rotate(-90deg);
} */
#inner {
stroke-dasharray: 1 314;
stroke-dashoffset: 314;
transform: rotate(-90deg);
transform-origin: 50% 50%;
/* animation: rotate 2s linear infinite; */
animation: animate 2s ease-in-out infinite;
}
#keyframes animate {
100% {
stroke-dasharray: 314;
}
}
svg {
border: 1px solid;
}
<svg>
<g class="circles">
<circle cx="125" cy="125" r="50" fill="none" stroke-width="15px" stroke="#E0E3E9">
</circle>
<circle id="inner" cx="125" cy="125" r="50" fill="none" stroke-width="12px" stroke="#6B04A8">
</circle>
</g>
</svg>
Second attempt:
The OP is commenting
for the first 50% of the circle it has to grow and after crossing the 50% only it should shrink
svg {
width: 250px;
height: 250px;
position: relative;
}
/* .circles{
transform: rotate(-90deg);
} */
#inner {
transform: rotate(-90deg);
transform-origin: 50% 50%;
animation: animate 5s ease-in-out infinite;
}
#keyframes animate{
0%{
stroke-dasharray: 0 314;
stroke-dashoffset: 314;
}
50%{
stroke-dasharray: 157 157;
stroke-dashoffset: 314;
}
75%{
stroke-dasharray: 157 157;
stroke-dashoffset: 157;
}
100%{
stroke-dasharray: 0 314;
stroke-dashoffset: 0;
}
}
svg {
border: 1px solid;
}
<svg>
<g class="circles">
<circle cx="125" cy="125" r="50" fill="none" stroke-width="15px" stroke="#E0E3E9">
</circle>
<circle id="inner" cx="125" cy="125" r="50" fill="none" stroke-width="12px" stroke="#6B04A8" stroke-dasharray="0 314" stroke-dashoffset = "157">
</circle>
</g>
</svg>

simplify this css svg animation

I'm working on this to have the rect to change colors. Each rect will change on a 0.1s delay.
Let's say I want to have more rectangles or path, how can I simplify the code? I think it could be simplified using scss but what about using CSS? is there a smarter way to do so rather than the way I have done?
#svg rect:nth-child(1) {
animation: ani 1.8s linear infinite;
animation-delay: 0.1s;
}
#svg rect:nth-child(1):hover {
animation-play-state: paused;
}
#svg rect:nth-child(2) {
animation: ani 1.8s linear infinite;
animation-delay: 0.2s;
}
#svg rect:nth-child(2):hover {
animation-play-state: paused;
}
#svg rect:nth-child(3) {
animation: ani 1.8s linear infinite;
animation-delay: 0.3s;
}
#svg rect:nth-child(3):hover {
animation-play-state: paused;
}
#svg rect:nth-child(4) {
animation: ani 1.8s linear infinite;
animation-delay: 0.4s;
}
#svg rect:nth-child(4):hover {
animation-play-state: paused;
}
#svg rect:nth-child(5) {
animation: ani 1.8s linear infinite;
animation-delay: 0.5s;
}
#svg rect:nth-child(5):hover {
animation-play-state: paused;
}
#keyframes ani {
0% {
fill: #0057B8;
}
20% {
fill: #F11E4A;
}
40% {
fill: #F8A527;
}
60% {
fill: #266D7F;
}
80% {
fill: #82A;
}
100% {
fill: #0057B8;
}
}
<svg id="svg" width="401" height="275" viewBox="0 0 401 275" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="401" height="275" fill="white"/>
<rect x="50" y="91" width="57" height="57" fill="#C4C4C4"/>
<rect x="118" y="91" width="57" height="57" fill="#C4C4C4"/>
<rect x="186" y="91" width="57" height="57" fill="#C4C4C4"/>
<rect x="254" y="91" width="57" height="57" fill="#C4C4C4"/>
</svg>
For the :hover and base rect animation duplication, they can each be refactored into their own block.
#svg rect {
--animation-delay: 0.1s;
animation: ani 1.8s linear infinite var(--animation-delay);
}
#svg rect:hover {
animation-play-state: paused;
}
I would store the animation delay in a custom property and add it to the lone animation call.
#svg rect {
--animation-delay: 0.1s;
animation: ani 1.8s linear infinite var(--animation-delay);
}
Now you can override the delay later when necessary, such as:
#svg rect:nth-child(3) { --animation-delay: 0.2s; }
The delay will automatically update for that child's animation.
Here's the complete code:
#svg rect {
--animation-delay: 0.1s;
animation: ani 1.8s linear infinite var(--animation-delay);
}
#svg rect:hover {
animation-play-state: paused;
}
<!-- No way to shorten this in pure CSS 😠 -->
#svg rect:nth-child(2) { --animation-delay: 0.2s; }
#svg rect:nth-child(3) { --animation-delay: 0.3s; }
#svg rect:nth-child(4) { --animation-delay: 0.4s; }
#svg rect:nth-child(5) { --animation-delay: 0.5s; }
#keyframes ani {
0% {
fill: #0057B8;
}
20% {
fill: #F11E4A;
}
40% {
fill: #F8A527;
}
60% {
fill: #266D7F;
}
80% {
fill: #82A;
}
100% {
fill: #0057B8;
}
}
<svg id="svg" width="401" height="275" viewBox="0 0 401 275" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="401" height="275" fill="white" />
<rect x="50" y="91" width="57" height="57" fill="#C4C4C4" />
<rect x="118" y="91" width="57" height="57" fill="#C4C4C4" />
<rect x="186" y="91" width="57" height="57" fill="#C4C4C4" />
<rect x="254" y="91" width="57" height="57" fill="#C4C4C4" />
</svg>
jsFiddle
All your :hover effects are the same, and so are your animation properties so you can simplify those to one rule each:
#svg rect {
animation: ani 1.8s linear infinite;
}
#svg rect:hover {
animation-play-state: paused;
}
that would already reduce the lines a lot, for the animation delays themselves your method is ok.
If you are intrested in a CSS solution you can do something like below. It's a bit different animation but you can easily scale it by keeping the same code.
The trick is to animate the same gradient for all the boxes to simulate the color changes. Note how I made the pseudo element relative to the .box not the child elements to have the same layer
.box {
display:inline-flex;
margin:5px;
padding:50px 20px;
position:relative;
background:right/800% 100%;
background-image:linear-gradient(to left,#0057B8,#F11E4A,#F8A527,#266D7F,#82A,#0057B8);
animation: ani 1.8s linear infinite;
}
.box > div {
margin:5px;
height:55px;
width:55px;
background-image:inherit;
-webkit-mask: linear-gradient(#fff,#fff);
mask: linear-gradient(#fff,#fff);
}
.box > div:before {
content:"";
position:absolute;
top:0;
left:0;
right:0;
bottom:0;
background: right/1000% 100%;
background-image:inherit;
animation: ani 2s linear infinite;
}
.box > div:hover:before {
animation-play-state:paused;
}
#keyframes ani {
100% {
background-position:left;
}
}
<div class="box">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
<br>
<div class="box">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>

SVG Ripple Effect: Not Getting Proper Ripple Effect Animations

I am struggling on ripple effect using SVG I struck on animations not getting proper ripple effect need three ripples after two ripples third should hide and also the smoothness is there any possibilities by using three different animations can anyone point me in right direction Thanks In Advance.
body{ background: #802a10d6;}
svg {
position: relative;
z-index: 10;
transition: all 0.5s linear;
}
img {
position: absolute;
height: 66px;
width: 66px;
top: 75px;
left: 75px;
transition: all 1.5s linear;
}
.rp1,
.rp2,
.rp3 {
content: ' ';
position: absolute;
transition: all 1.5s linear;
z-index: 1;
animation: pulse 2s linear infinite;
}
.rp1 { animation-delay: 0.5s; }
.rp2 {animation-delay: 0.7s; }
.rp3{ animation-delay: 1s; }
#keyframes pulse {
to{
opacity: 0;
transform: scale(1);
transition: all 0.5 linear;
}
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg" height="900" width="900">
<svg>
<circle class="rp1" cx="100" cy="100" r="35" stroke="#ffffff" stroke-width="2" fill="transparent" />
<circle class="rp2" cx="100" cy="100" r="45" stroke="#ffffff" stroke-width="2" fill="transparent" />
<circle class="rp3" cx="100" cy="100" r="55" stroke="#ffffff" stroke-width="2" fill="transparent" />
<img src="https://image.ibb.co/dBkJkV/person-4.png"/>
</svg>
</svg>
I hope this is what you wanted to achieve. Observation: although you can use opacity here, I would use stroke-opacity
body{ background: #802a10d6;}
svg {
position: relative;
/*z-index: 10;
transition: all 0.5s linear;*/
border:1px solid
}
/*img {
position: absolute;
height: 66px;
width: 66px;
top: 75px;
left: 75px;
transition: all 1.5s linear;
}*/
.rp1,
.rp2,
.rp3 {
/*content: ' ';
position: absolute;
transition: all 1.5s linear;
z-index: 1;*/
stroke-opacity: 0;
animation: pulse 2s linear infinite;
}
.rp1 { animation-delay: 0.5s; }
.rp2 {animation-delay: 0.7s; }
.rp3{ animation-delay: 1s; }
#keyframes pulse {
0%{stroke-opacity: 0;}
50%{stroke-opacity: 1;}
100%{
stroke-opacity: 0;
/*transform: scale(1);
transition: all 0.5 linear;*/
}
<svg height="200" width="200">
<circle class="rp1" cx="100" cy="100" r="35" stroke="#ffffff" stroke-width="2" fill="transparent" />
<circle class="rp2" cx="100" cy="100" r="45" stroke="#ffffff" stroke-width="2" fill="transparent" />
<circle class="rp3" cx="100" cy="100" r="55" stroke="#ffffff" stroke-width="2" fill="transparent" />
<image xlink:href="https://image.ibb.co/dBkJkV/person-4.png" height="66" width="66" x="66" y="66"></image>
</svg>

Filling a rotating circular SVG with a pattern image

So i've got this text that rotates around this circle using SVG. I'd like to fill it with an image to make it less bland. This is the code I have in my HTML.
<div id="container">
<div id="circle">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="300px"
height="300px" viewBox="0 0 300 300" enable-background="new 0 0 300 300" xml:space="preserve">
<defs>
<pattern id='my_portrait'>
<image xlink:href="http://gastv.mx/wp-content/uploads/2014/05/jumex.jpg" x="-30" y="-30"
width="380" height="267" />
</pattern>
<path id="circlePath" d=" M 150, 150 m -60, 0 a 60,60 0 0,1 120,0 a 60,60 0 0,1 -120,0 " />
</defs>
<circle cx="150" cy="100" r="75" fill="none"/>
<g id="rotating_text">
<use xlink:href="#circlePath" fill="rgb(81,84,77)" stroke="black" stroke-width="2px"/>
<text fill="#000">
<textPath xlink:href="#circlePath" fill="white">Curse this circular mass of misery!!!</textPath>
</text>
</g>
</svg>
</div>
</div>
And this is the CSS defining speed and browser support.
#circle svg {
width: 100%;
-webkit-animation-name: rotate;
-moz-animation-name: rotate;
-ms-animation-name: rotate;
-o-animation-name: rotate;
animation-name: rotate;
-webkit-animation-duration: 20s;
-moz-animation-duration: 20s;
-ms-animation-duration: 20s;
-o-animation-duration: 20s;
animation-duration: 20s;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
-ms-animation-iteration-count: infinite;
-o-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-moz-animation-timing-function: linear;
-ms-animation-timing-function: linear;
-o-animation-timing-function: linear;
animation-timing-function: linear;
}
#-webkit-keyframes rotate {
from {
-webkit-transform: rotate(360deg);
}
to {
-webkit-transform: rotate(0);
}
}
#-moz-keyframes rotate {
from {
-moz-transform: rotate(360deg);
}
to {
-moz-transform: rotate(0);
}
}
#-ms-keyframes rotate {
from {
-ms-transform: rotate(360deg);
}
to {
-ms-transform: rotate(0);
}
}
#-o-keyframes rotate {
from {
-o-transform: rotate(360deg);
}
to {
-o-transform: rotate(0);
}
}
#keyframes rotate {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0);
}
}
I've tried a couple of different methods of trying to fill the inside circle but nothing ever seems to make a difference. Any help would be sorely appreciated!
add patternUnits="userSpaceOnUse" height="380" width="267" in my_portrait
and also add fill="url(#my_portrait)" in circlePath
#circle svg {
width: 100%;
-webkit-animation-name: rotate;
-moz-animation-name: rotate;
-ms-animation-name: rotate;
-o-animation-name: rotate;
animation-name: rotate;
-webkit-animation-duration: 20s;
-moz-animation-duration: 20s;
-ms-animation-duration: 20s;
-o-animation-duration: 20s;
animation-duration: 20s;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
-ms-animation-iteration-count: infinite;
-o-animation-iteration-count: infinite;
animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-moz-animation-timing-function: linear;
-ms-animation-timing-function: linear;
-o-animation-timing-function: linear;
animation-timing-function: linear;
}
#-webkit-keyframes rotate {
from {
-webkit-transform: rotate(360deg);
}
to {
-webkit-transform: rotate(0);
}
}
#-moz-keyframes rotate {
from {
-moz-transform: rotate(360deg);
}
to {
-moz-transform: rotate(0);
}
}
#-ms-keyframes rotate {
from {
-ms-transform: rotate(360deg);
}
to {
-ms-transform: rotate(0);
}
}
#-o-keyframes rotate {
from {
-o-transform: rotate(360deg);
}
to {
-o-transform: rotate(0);
}
}
#keyframes rotate {
from {
transform: rotate(360deg);
}
to {
transform: rotate(0);
}
}
<div id="container">
<div id="circle">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="300px"
height="300px" viewBox="0 0 300 300" enable-background="new 0 0 300 300" xml:space="preserve">
<defs>
<pattern id='my_portrait' patternUnits="userSpaceOnUse" height="380" width="267">
<image xlink:href="http://gastv.mx/wp-content/uploads/2014/05/jumex.jpg" x="-30" y="-30"
width="380" height="267" />
</pattern>
<path id="circlePath" d=" M 150, 150 m -60, 0 a 60,60 0 0,1 120,0 a 60,60 0 0,1 -120,0 " fill="url(#my_portrait)" />
</defs>
<circle cx="150" cy="100" r="75" fill="none"/>
<g id="rotating_text">
<use xlink:href="#circlePath" fill="rgb(81,84,77)" stroke="black" stroke-width="2px"/>
<text fill="#000">
<textPath xlink:href="#circlePath" fill="white">Curse this circular mass of misery!!!</textPath>
</text>
</g>
</svg>
</div>
</div>

SVG width attribute css animation in firefox

SVG width attribute css animation not working in Firefox but in chrome it working perfectly. Please check the below snippet demo.
Does any wrong in my codes? Is there a way to apply the animation over the attribute width?
svg {
display: inline-block;
}
#-moz-keyframes glareAnim1 {
0% {
width: 0;
}
50% {
width: 10px;
}
100% {
width: 0;
}
}
#-webkit-keyframes glareAnim1 {
0% {
width: 0;
}
50% {
width: 10px;
}
100% {
width: 0;
}
}
#keyframes glareAnim1 {
0% {
width: 0;
}
50% {
width: 10px;
}
100% {
width: 0;
}
}
.glare-top {
-moz-animation: glareAnim1 2s linear infinite;
-webkit-animation: glareAnim1 2s linear infinite;
animation: glareAnim1 2s linear infinite;
}
#-moz-keyframes glareAnim2 {
0% {
width: 10px;
}
50% {
width: 0;
}
100% {
width: 10px;
}
}
#-webkit-keyframes glareAnim2 {
0% {
width: 10px;
}
50% {
width: 0;
}
100% {
width: 10px;
}
}
#keyframes glareAnim2 {
0% {
width: 10px;
}
50% {
width: 0;
}
100% {
width: 10px;
}
}
.glare-bottom {
-moz-animation: glareAnim2 2s linear infinite;
-webkit-animation: glareAnim2 2s linear infinite;
animation: glareAnim2 2s linear infinite;
}
#-moz-keyframes translateDoor {
0% {
-moz-transform: translate(-1px, 0);
transform: translate(-1px, 0);
opacity: 1;
width: 1px;
height: 6px;
}
15% {
width: 4px;
}
50% {
-moz-transform: translate(16px, 0);
transform: translate(16px, 0);
opacity: 1;
width: 2px;
}
51% {
opacity: 0;
}
100% {
-moz-transform: translateX(-10px);
transform: translateX(-10px);
opacity: 0;
}
}
#-webkit-keyframes translateDoor {
0% {
-webkit-transform: translate(-1px, 0);
transform: translate(-1px, 0);
opacity: 1;
width: 1px;
height: 6px;
}
15% {
width: 4px;
}
50% {
-webkit-transform: translate(16px, 0);
transform: translate(16px, 0);
opacity: 1;
width: 2px;
}
51% {
opacity: 0;
}
100% {
-webkit-transform: translateX(-10px);
transform: translateX(-10px);
opacity: 0;
}
}
#keyframes translateDoor {
0% {
-moz-transform: translate(-1px, 0);
-ms-transform: translate(-1px, 0);
-webkit-transform: translate(-1px, 0);
transform: translate(-1px, 0);
opacity: 1;
width: 1px;
height: 6px;
}
15% {
width: 4px;
}
50% {
-moz-transform: translate(16px, 0);
-ms-transform: translate(16px, 0);
-webkit-transform: translate(16px, 0);
transform: translate(16px, 0);
opacity: 1;
width: 2px;
}
51% {
opacity: 0;
}
100% {
-moz-transform: translateX(-10px);
-ms-transform: translateX(-10px);
-webkit-transform: translateX(-10px);
transform: translateX(-10px);
opacity: 0;
}
}
.researchDoor {
fill: #464949;
-moz-animation: translateDoor 5s linear infinite;
-webkit-animation: translateDoor 5s linear infinite;
animation: translateDoor 5s linear infinite;
}
.research0 {
fill: #FFFFFF;
stroke: #464949;
stroke-width: 2;
stroke-miterlimit: 10;
}
.research1 {
fill: #FCBD38;
overflow: hidden;
}
.research2 {
fill: #464949;
}
.research3 {
fill: none;
stroke: #464949;
stroke-width: 2;
stroke-linecap: square;
stroke-miterlimit: 10;
}
<svg version="1.1" x="0px" y="0px" viewBox="0 0 100 120" style="enable-background:new 0 0 100 120;" xml:space="preserve">
<path id="XMLID_42_" class="research0" d="M57.9,25.5c-3-6.4-8.3-11.6-8.3-11.6c-5.1,5-8.3,11.5-8.3,11.5v5.8L57.7,32L57.9,25.5z" />
<g id="XMLID_40_">
<rect x="41.4" y="25.9" class="research1" width="16.3" height="11.5" />
<path class="research2" d="M56.7,26.9v9.5H42.4v-9.5H56.7 M58.7,24.9H40.4v13.5h18.3V24.9L58.7,24.9z" />
</g>
<polygon id="XMLID_43_" class="research3" points="33.5,85.2 40.8,37.7 58.8,37.7 66.2,85.2 " />
<!-- door -->
<rect x="41" y="28.9" class="researchDoor" />
<!-- left top wind -->
<rect x="30" class="glare-top" y="28" fill="#464949" width="14" height="2" />
<!-- left bottom wind -->
<rect x="30" class="glare-bottom" y="32" fill="#464949" width="14" height="2" />
<!-- right top wind -->
<rect x="62" y="28" class="glare-top" fill="#464949" width="14" height="2" />
<!-- right bottom wind -->
<rect x="62" y="32" class="glare-bottom" fill="#464949" width="14" height="2" />
<!--
<line id="glareLeftTop" class="research3" x1="36.6" y1="28.7" x2="32.8" y2="28.7"/>
<line id="glareLeftBottom" class="research3" x1="36.6" y1="33.3" x2="23.8" y2="33.3"/>
<line id="glareTopRight" class="research3" x1="62.9" y1="28.7" x2="66.6" y2="28.7"/>
<line id="glareTopBottom" class="research3" x1="62.9" y1="33.3" x2="75.6" y2="33.3"/>
-->
<line id="XMLID_2_" class="research3" x1="76.3" y1="85.3" x2="23.7" y2="85.3" />
<line id="XMLID_64_" class="research3" x1="60.7" y1="37.7" x2="38.8" y2="37.7" />
<line id="XMLID_70_" class="research3" x1="58.7" y1="44.3" x2="40.8" y2="44.3" />
<line id="XMLID_79_" class="research3" x1="60.2" y1="51.7" x2="39.3" y2="51.7" />
<line id="XMLID_80_" class="research3" x1="61.7" y1="61" x2="37.8" y2="61" />
<line id="XMLID_90_" class="research3" x1="63.5" y1="69.3" x2="36.8" y2="69.3" />
<g id="XMLID_49_">
<path class="research2" d="M49.8,76.2c1.5,0,2.8,1.2,2.8,2.8v5.2H47v-5.2C47,77.4,48.2,76.2,49.8,76.2 M49.8,74.2
c-2.6,0-4.8,2.1-4.8,4.8v7.2h9.5v-7.2C54.5,76.3,52.4,74.2,49.8,74.2L49.8,74.2z" />
</g>
</svg>
Consider using lines with a stroke-width equal to the height of the rectangles instead of rectangles in your animation.
The stroke-dasharray lines will be used for animation.
At 0% {stroke-dasharray: 0.10;} for an animated line equal to 10px
the line will be hidden
At 50% {stroke-dasharray: 10,0;} the line will be shown in full
At 100% {stroke-dasharray: 0.10;} the line will be hidden again
.glare-top {
-webkit-animation: glareAnim1 2s linear infinite;
stroke-dasharray:0,10;
animation: glareAnim1 2s linear infinite;
}
#-webkit-keyframes glareAnim1 {
0% {stroke-dasharray:0,10;}
50% {stroke-dasharray:10,10;}
100%{stroke-dasharray:0,10;}
}
.glare-bottom {
-webkit-animation: glareAnim2 2s linear infinite;
stroke-dasharray:0,10;
animation: glareAnim2 2s linear infinite;
}
#-webkit-keyframes glareAnim2 {
0% {stroke-dasharray:10,0;}
50% {stroke-dasharray:0,10;}
100%{stroke-dasharray:10,0;}
}
<svg version="1.1" viewBox="0 0 100 120" >
<!-- left top wind -->
<polyline class="glare-top" points="27,28 37,28" stroke="#464949" stroke-width="2" />
<!-- left bottom wind -->
<polyline class="glare-bottom" points="27,33 37,33" stroke="#464949" stroke-width="2" />
</svg>
I have shortened your code to show the basic animation of the lines and the door.
svg {
display: inline-block;
}
.glare-top {
-webkit-animation: glareAnim1 2s linear infinite;
stroke-dasharray:0,10;
animation: glareAnim1 2s linear infinite;
}
#-webkit-keyframes glareAnim1 {
0% {stroke-dasharray:0,10;}
50% {stroke-dasharray:10,10;}
100%{stroke-dasharray:0,10;}
}
#keyframes glareAnim1 {
0% {stroke-dasharray:0,10;}
50% {stroke-dasharray:10,10;}
100%{stroke-dasharray:0,10;}
}
.glare-bottom {
-moz-animation: glareAnim2 2s linear infinite;
-webkit-animation: glareAnim2 2s linear infinite;
stroke-dasharray:0,10;
animation: glareAnim2 2s linear infinite;
}
#-webkit-keyframes glareAnim2 {
0% {stroke-dasharray:10,0;}
50% {stroke-dasharray:0,10;}
100%{stroke-dasharray:10,0;}
}
#keyframes glareAnim2 {
0% {stroke-dasharray:10,0;}
50% {stroke-dasharray:0,10;}
100%{stroke-dasharray:10,0;}
}
.researchDoor {
fill: #464949;
stroke-dasharray:0,6;
animation: translateDoor 5s linear infinite;
}
#keyframes translateDoor {
0% {
transform: translate(-1px, 0);
opacity: 1;
stroke-dasharray:0,6;
}
15% {
stroke-dasharray:1.4,4.6;
}
50% {
transform: translate(8px, 0);
stroke-dasharray:5,1;
}
70% {
transform: translate(12.8px, 0);
stroke-dasharray:3.5,2.5;
}
100% {
transform: translateX(16px);
stroke-dasharray:0,6;
}
}
.research0 {
fill: #FFFFFF;
stroke: #464949;
stroke-width: 2;
stroke-miterlimit: 10;
}
.research1 {
fill: #FCBD38;
overflow: hidden;
}
.research2 {
fill: #464949;
}
.research3 {
fill: none;
stroke: #464949;
stroke-width: 2;
stroke-linecap: square;
stroke-miterlimit: 10;
}
<svg version="1.1" viewBox="0 0 100 120" >
<path id="XMLID_42_" class="research0" d="M57.9,25.5c-3-6.4-8.3-11.6-8.3-11.6c-5.1,5-8.3,11.5-8.3,11.5v5.8L57.7,32L57.9,25.5z" />
<g id="XMLID_40_">
<rect x="41.4" y="25.9" class="research1" width="16.3" height="11.5" />
<path class="research2" d="M56.7,26.9v9.5H42.4v-9.5H56.7 M58.7,24.9H40.4v13.5h18.3V24.9L58.7,24.9z" />
</g>
<polygon id="XMLID_43_" class="research3" points="33.5,85.2 40.8,37.7 58.8,37.7 66.2,85.2 " />
<!-- door -->
<!-- <rect x="41" y="28.9" class="researchDoor" /> -->
<polyline class="researchDoor" points="41,32 47,32" stroke="#464949" stroke-width="6" />
<!-- left top wind -->
<polyline class="glare-top" points="27,28 37,28" stroke="#464949" stroke-width="2" />
<!-- right top wind -->
<polyline class="glare-top" points=" 62,28 72,28" stroke="#464949" stroke-width="2" />
<!-- left bottom wind -->
<polyline class="glare-bottom" points="27,33 37,33" stroke="#464949" stroke-width="2" />
<!-- right bottom wind -->
<polyline class="glare-bottom" points=" 62,33 72,33" stroke="#464949" stroke-width="2" />
<line id="XMLID_2_" class="research3" x1="76.3" y1="85.3" x2="23.7" y2="85.3" />
<line id="XMLID_64_" class="research3" x1="60.7" y1="37.7" x2="38.8" y2="37.7" />
<line id="XMLID_70_" class="research3" x1="58.7" y1="44.3" x2="40.8" y2="44.3" />
<line id="XMLID_79_" class="research3" x1="60.2" y1="51.7" x2="39.3" y2="51.7" />
<line id="XMLID_80_" class="research3" x1="61.7" y1="61" x2="37.8" y2="61" />
<line id="XMLID_90_" class="research3" x1="63.5" y1="69.3" x2="36.8" y2="69.3" />
<g id="XMLID_49_">
<path class="research2" d="M49.8,76.2c1.5,0,2.8,1.2,2.8,2.8v5.2H47v-5.2C47,77.4,48.2,76.2,49.8,76.2 M49.8,74.2
c-2.6,0-4.8,2.1-4.8,4.8v7.2h9.5v-7.2C54.5,76.3,52.4,74.2,49.8,74.2L49.8,74.2z" />
</g>
</svg>
In SVG 1.1 width is an attribute and cannot be animated with CSS animation.
In the SVG 2 specification width is a CSS property which can therefore be animated with CSS animation.
Chrome has implemented this part of the SVG 2 specification, Firefox had not when this question was first written, but it has now. In fact Firefox has had this functionality for quite a while now.