CSS3 animation is not working - css

I have created an animation for SVG using css3 which is working perfectly in Chrome and Firefox. It is partially working in Safari but not working in Internet Explorer (IE9+ which support css animations)
See Demo
CSS:
#-webkit-keyframes dash {
70%,80% {
stroke-dashoffset: 0;
fill-opacity: 0;
}
85% {
fill-opacity: 0;
stroke-opacity: 1;
}
95% {
stroke: #17739D;
stroke-dashoffset: -301;
stroke-opacity: 0;
}
100% {
fill-opacity: 1;
stroke-dashoffset: -301;
}
}
#-ms-keyframes dash {
70%,80% {
stroke-dashoffset: 0;
fill-opacity: 0;
}
85% {
fill-opacity: 0;
stroke-opacity: 1;
}
95% {
stroke: #17739D;
stroke-dashoffset: -301;
stroke-opacity: 0;
}
100% {
fill-opacity: 1;
stroke-dashoffset: -301;
}
}
#-moz-keyframes dash {
70%,80% {
stroke-dashoffset: 0;
fill-opacity: 0;
}
85% {
fill-opacity: 0;
stroke-opacity: 1;
}
95% {
stroke: #17739D;
stroke-dashoffset: -301;
stroke-opacity: 0;
}
100% {
fill-opacity: 1;
stroke-dashoffset: -301;
}
}
#keyframes dash {
70%,80% {
stroke-dashoffset: 0;
fill-opacity: 0;
}
85% {
fill-opacity: 0;
stroke-opacity: 1;
}
95% {
stroke: #17739D;
stroke-dashoffset: -301;
stroke-opacity: 0;
}
100% {
fill-opacity: 1;
stroke-dashoffset: -301;
}
}
#Layer_1 {
margin-left: auto;
margin-right : auto;
top: 50%;
position: absolute;
left: 50%;
margin-left: -65px;
margin-top: -35px;
}
svg {
background: #fff;
display: block;
}
svg * {
stroke: #666;
#stroke: #17739D;
stroke-width: 1;
fill-opacity: 0;
stroke-dasharray: 350;
stroke-dashoffset: 440;
}
svg #bp_svg * {
-webkit-animation-name : dash;
-moz-animation-name : dash;
-ms-animation-name : dash;
animation-name : dash;
-webkit-animation-duration: 4s;
-moz-animation-duration: 4s;
-ms-animation-duration: 4s;
animation-duration: 4s;
-webkit-animation-timing-function : linear;
-moz-animation-timing-function : linear;
-ms-animation-timing-function : linear;
animation-timing-function : linear;
-webkit-animation-fill-mode : forwards;
-moz-animation-fill-mode : forwards;
-ms-animation-fill-mode : forwards;
animation-fill-mode : forwards;
}
Can anyone help me to sort out what to do to make it work properly in Safari and IE also?

While CSS3 animations are supported in IE9, SVG animations are not even supported in IE11 and it's hard to tell whether they will ever be. You probably have to either rely on animated HTML elements or use JavaScript which will not benefit from the hardware acceleration used to render CSS animations but still might be a viable solution.
Another idea would be to prerender it and deploy it as a gif, either every time or only in IE.
Source: http://caniuse.com/#feat=svg-smil

CSS3 animations are not supported in IE9, which explains why it doesn't work in IE9. The same will apply for Safari,it may help to also give the versions of each browser. Please refer to this list of supported features: http://caniuse.com/css-animation

I would suggest using raphaeljs javascript library. It has great capability in animating svg.
Raphael currently supports Chrome 5.0+ Firefox 3.0+, Safari 3.0+,
Opera 9.5+ and Internet Explorer 6.0+
http://raphaeljs.com/
http://raphaeljs.com/playground.html - quick preview.

Related

SVG Keyframes animation not working when using image-webpack-loader

I'm trying to draw an SVG logo using Keyframes. It works fine stand alone when I open the SVG file by itself in the browser, but it doesn't work when I try to use it in my React project.
For mu react project, I am using image-webpack-loader to load SVG images and I have made the following alterations to webpack config file:
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
{
loader: 'file-loader',
options: {
hash: 'sha512',
digest: 'hex',
name: '[hash].[ext]',
}
},
{
loader:'image-webpack-loader',
options:{
bypassOnDebug:true,
},
}
],
}
Here's my React JS file code:
import React from 'react';
import '../stylesheets/Atom.css'
import Atom from '../Assets/images/atom.svg';
const AtomSpinner = props => {
return (
<div className='atomWrapper'>
<img className='atom' src={Atom}/>
</div>
);
};
export default AtomSpinner;
This is the CSS that I am using for this React Component as well as the SVG file. Even if I am putting all styles for the SVG and React in the same stylesheet, the SVG animation works fine when I use it in the browser. Here's the stylesheet:
.atomWrapper{
text-align: center;
}
.atom{
position:absolute;
top:50%;
left:50%;
transform: translate(-50%,-50%);
max-height:256px ;
max-width: 256px;
}
svg {
max-width: 256px;
max-height: 256px;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
}
path {
fill-opacity:0;
stroke: #000;
stroke-width: 3;
stroke-dasharray: 351.0306396484375em;
stroke-dashoffset:351em ;
-webkit-animation-name: draw;
-webkit-animation-duration: 10s;
-webkit-animation-fill-mode: forwards;
-webkit-animation-iteration-count: 2;
-webkit-animation-timing-function: ease;
}
circle {
fill-opacity:0;
stroke: #000;
stroke-width: 3;
stroke-dasharray: 304em;
stroke-dashoffset:303.5em ;
-webkit-animation-name: draw;
-webkit-animation-duration: 3s;
-webkit-animation-fill-mode: forwards;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: linear;
}
#-webkit-keyframes draw {
to {
stroke-dashoffset: 0.8;
}
to{
fill-opacity: 1;
}
}
#keyframes draw {
to {
stroke-dashoffset: 0.8;
}
to{
fill-opacity: 1;
}
}
Here's a jsFiddle with the SVG and styles in it:
https://jsfiddle.net/nxxu1Lob/1/

Why this CSS3 animation doesn't work in MS Edge or IE11?

Here is the fiddle and below is the CSS code (the HTML is just an SVG ellipse). It works in Chrome, Firefox and Opera, but doesn't work in IE and Edge. What to do to see the animation in IE and Edge?
#my-circle {
stroke: blue;
stroke-dasharray: 1100;
stroke-dashoffset: 500;
-moz-animation: draw-first-shape 1s forwards 3;
-webkit-animation: draw-first-shape 1s forwards 3;
animation: draw-first-shape 1s forwards 3;
}
#-moz-keyframes draw-first-shape {
from {
stroke-dashoffset: 1100;
}
to {
stroke-dashoffset: 0;
}
}
#-webkit-keyframes draw-first-shape {
from {
stroke-dashoffset: 1100;
}
to {
stroke-dashoffset: 0;
}
}
#keyframes draw-first-shape {
from {
stroke-dashoffset: 1100;
}
to {
stroke-dashoffset: 0;
}
}
Even though MSDN says that as of MS Edge the stroke-dashoffset property is animatable with CSS animations and transitions, it still doesn't work for some reason. If we re-create this animation using stroke-dasharray instead of stroke-dashoffset then it works as expected in Edge.
But it will still not work in IE11 or lower because again as indicated in MSDN, the stroke-dasharray is animatable using CSS animations and transitions only from MS Edge.
The modified animation still works in latest versions of Chrome, Firefox and Opera.
#my-circle {
stroke: blue;
stroke-dasharray: 1100;
stroke-dashoffset: 0;
animation: draw-first-shape 1s forwards 3;
}
#keyframes draw-first-shape {
from {
stroke-dasharray: 0, 1100;
}
to {
stroke-dasharray: 1100, 1100;
}
}
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="300" viewBox="0 0 500.00001 300" id="svg2">
<g id="layer1" transform="translate(0 -752.362)">
<ellipse id="my-circle" cx="257.013" cy="907.735" rx="201.742" ry="111.465" fill="#fff" stroke="#007400" stroke-width="3" />
</g>
</svg>
As a workaround for MS Edge, you can animate stroke-width (making a tiny variation of its value) together with stroke-dashoffset. For instance, in the case of the question:
#keyframes draw-first-shape {
from {
stroke-dashoffset: 1100;
stroke-width: 3.03;
}
to {
stroke-dashoffset: 0;
stroke-width: 3;
}
}

SVG animation not working in Safari/IE

I have this SVG line animation that draws in a text, however it doesn't seem to work on Safari nor Internet Explorer. IS there something I'm missing?
http://codepen.io/anon/pen/VYgdZv
CSS
svg path {
fill: none;
stroke: #000;
stroke-width: 4;
stroke-linecap: round;
stroke-linejoin: round;
stroke-dasharray: 1700;
stroke-dashoffset: 1700;
animation: dash 5s ease-out forwards;
-webkit-animation-name:dash;
-webkit-animation-duration:5s;
-webkit-animation-timing-function:ease-out;
-webkit-animation-fill-mode:forwards;
-moz-animation: dash 5s ease-out forwards;
-o-animation: dash 5s ease-out forwards;
-ms-animation: dash 5s ease-out forwards;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
#-moz-keyframes dash {
to {
stroke-dashoffset: 0;
}
}
#-webkit-keyframes dash {
to {
stroke-dashoffset: 0;
}
}
#-o-keyframes dash {
to {
stroke-dashoffset: 0;
}
}
#-ms-keyframes dash {
to {
stroke-dashoffset: 0;
}
}
CSS animations, transitions, transforms (as well as classList or dataset in JS) don't work in IE 11 and older. The transitions/ animations problem has just been fixed in the Edge engine (same goes for classList), but for IE11 and older, the only solution is to use JS (SMIL animations don't work either, plus Chrome might drop SMIL as well - update: SMIL is on its way out, don't use it!).
This is an example of how you can do it:
var p = document.querySelector('.animate'),
offset = 1000;
var offsetMe = function() {
if(offset < 0) offset = 1000;
p.style.strokeDashoffset = offset;
offset--;
requestAnimationFrame(offsetMe);
}
offsetMe();
#keyframes fadeInP {
to {
stroke-dashoffset: 0;
}
}
.animate {
stroke-dashoffset: 1000;
/*animation: fadeInP 10s linear infinite;*/
}
/*
CSS animations don't work for this in IE and neither do SMIL animations.
*/
<svg viewBox="0 0 400 400">
<path stroke-width='8' class="animate" stroke-dasharray="10 10" fill='none' stroke="#000" d="M 0,0 C 100,10 200,80 300,15 " />
</svg>
One quick note about your code: always write the unprefixed version of rules last and you don't need -ms-animation (IE10+ supports animations unprefixed, while IE9 does not support them at all).

CSS3 animation not running in Chrome on MY site

I'm trying to animate an SVG with CSS3. You can see an example here -
http://codepen.io/MyXoToD/pen/vBlfs
However this example works exactly as it should in Chrome, however when I implement the code on my site, it doesn't run the code. Yet it works perfectly fine in Firefox. When i Inspect element in Chrome it's putting a line through the animation properties and displaying an error saying 'Invalid property value'. Yet when I look at the example I do the same thing and I don't get the same error.
I'm a little confused and I've been debugging this for a while. It can't be my version of Chrome (which is Version 39.0.2171.95 m).
Although my code is almost exactly the same after some small modifications, here is my snippet:
img {
max-width: 80%;
width: 100%;
//position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
opacity: 0;
animation-name: show;
animation-delay: 6s;
animation-duration: 1s;
animation-fill-mode: forwards;
animation-iteration-count: 1;
animation-timing-function: linear;
}
svg {
max-width: 80%;
width: 100%;
//position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
path {
stroke-width: 2;
stroke: black;
animation-fill-mode: forwards;
animation-iteration-count: 1;
animation-name: draw;
animation-timing-function: linear;
animation-duration: 3s;
&.bird {
stroke: black;
stroke-dasharray: 2810;
stroke-dashoffset: 2810;
}
}
}
}
#keyframes draw {
to {
stroke-dashoffset: 0;
}
}
#keyframes show {
to {
opacity: 1;
}
}
You've enabled the -prefix-free mode on Codepen. It lets you use only unprefixed CSS properties everywhere. It works behind the scenes, adding the current browser’s prefix to any CSS code, only when it’s needed.
For example, on Codepen you will see:
animation-name: show;
instead of:
animation-name: show;
-webkit-animation-name: show;
-moz-animation-name: show;

How to add a spinner icon to button when it's in the Loading state?

Twitter Bootstrap's buttons have a nice Loading... state available.
The thing is that it just shows a message like Loading... passed through the data-loading-text attribute like this:
<button type="button" class="btn btn-primary start" id="btnStartUploads"
data-loading-text="#Localization.Uploading">
<i class="icon-upload icon-large"></i>
<span>#Localization.StartUpload</span>
</button>
Looking at Font Awesome, you see that there's now an animated spinner icon.
I tried to integrate that spinner icon when firing an Upload operation like this:
$("#btnStartUploads").button('loading');
$("#btnStartUploads i").removeAttr('class');
$("#btnStartUploads i").addClass('icon-spinner icon-spin icon-large');
but this had no effect at all, that is, I just see the Uploading... text on the button.
Is it possible to add an icon when the button is in the Loading state? Looks like somehow Bootstrap just removes the icon <i class="icon-upload icon-large"></i> inside the button while in the Loading state.
Here's a simple demo that shows the behavior I describe above. As you see when it enters the Loading state the icon just disappears. It reappears right after the time interval.
Simple solution for Bootstrap 3 using CSS3 animations.
Put the following in your CSS:
.glyphicon.spinning {
animation: spin 1s infinite linear;
-webkit-animation: spin2 1s infinite linear;
}
#keyframes spin {
from { transform: scale(1) rotate(0deg); }
to { transform: scale(1) rotate(360deg); }
}
#-webkit-keyframes spin2 {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(360deg); }
}
Then just add the spinning class to a glyphicon while loading to get your spinning icon:
<button class="btn btn-lg btn-warning">
<span class="glyphicon glyphicon-refresh spinning"></span> Loading...
</button>
Based on http://www.bootply.com/128062#
Note: IE9 and below do not support CSS3 animations.
If you look at the bootstrap-button.js source, you'll see that the bootstrap plugin replaces the buttons inner html with whatever is in data-loading-text when calling $(myElem).button('loading').
For your case, I think you should just be able to do this:
<button type="button"
class="btn btn-primary start"
id="btnStartUploads"
data-loading-text="<i class='icon-spinner icon-spin icon-large'></i> #Localization.Uploading">
<i class="icon-upload icon-large"></i>
<span>#Localization.StartUpload</span>
</button>
There's now a full-fledged plugin for that:
http://msurguy.github.io/ladda-bootstrap/
To make the solution by #flion look really great, you could adjust the center point for that icon so it doesn't wobble up and down. This looks right for me at a small font size:
.glyphicon-refresh.spinning {
transform-origin: 48% 50%;
}
A lazy way to do this is with the UTF-8 entity code for a half circle \25E0 (aka ◠), which looks like ◠ and then keyframe animate it. It's a simple as:
.busy
{
animation: spin 1s infinite linear;
display:inline-block;
font-weight: bold;
font-family: sans-serif;
font-size: 35px;
font-style:normal;
color:#555;
}
.busy::before
{
content:"\25E0";
}
#keyframes spin
{
0% {transform: rotate(0deg);}
100% {transform: rotate(359deg);}
}
<i class="busy"></i>
Here's my solution for Bootstrap 4:
<button id="search" class="btn btn-primary"
data-loading-text="<i class='fa fa-spinner fa-spin fa-fw' aria-hidden='true'></i>Searching">
Search
</button>
var setLoading = function () {
var search = $('#search');
if (!search.data('normal-text')) {
search.data('normal-text', search.html());
}
search.html(search.data('loading-text'));
};
var clearLoading = function () {
var search = $('#search');
search.html(search.data('normal-text'));
};
setInterval(() => {
setLoading();
setTimeout(() => {
clearLoading();
}, 1000);
}, 2000);
Check it out on JSFiddle
These are mine, based on pure SVG and CSS animations. Don't pay attention to JS code in the snippet bellow, it's just for demoing purposes. Feel free to make your custom ones basing on mine, it's super easy.
var svg = d3.select("svg"),
columnsCount = 3;
['basic', 'basic2', 'basic3', 'basic4', 'loading', 'loading2', 'spin', 'chrome', 'chrome2', 'flower', 'flower2', 'backstreet_boys'].forEach(function(animation, i){
var x = (i%columnsCount+1) * 200-100,
y = 20 + (Math.floor(i/columnsCount) * 200);
svg.append("text")
.attr('text-anchor', 'middle')
.attr("x", x)
.attr("y", y)
.text((i+1)+". "+animation);
svg.append("circle")
.attr("class", animation)
.attr("cx", x)
.attr("cy", y+40)
.attr("r", 16)
});
circle {
fill: none;
stroke: #bbb;
stroke-width: 4
}
.basic {
animation: basic 0.5s linear infinite;
stroke-dasharray: 20 80;
}
#keyframes basic {
0% {stroke-dashoffset: 100;}
100% {stroke-dashoffset: 0;}
}
.basic2 {
animation: basic2 0.5s linear infinite;
stroke-dasharray: 80 20;
}
#keyframes basic2 {
0% {stroke-dashoffset: 100;}
100% {stroke-dashoffset: 0;}
}
.basic3 {
animation: basic3 0.5s linear infinite;
stroke-dasharray: 20 30;
}
#keyframes basic3 {
0% {stroke-dashoffset: 100;}
100% {stroke-dashoffset: 0;}
}
.basic4 {
animation: basic4 0.5s linear infinite;
stroke-dasharray: 10 23.3;
}
#keyframes basic4 {
0% {stroke-dashoffset: 100;}
100% {stroke-dashoffset: 0;}
}
.loading {
animation: loading 1s linear infinite;
stroke-dashoffset: 25;
}
#keyframes loading {
0% {stroke-dashoffset: 0; stroke-dasharray: 50 0; }
50% {stroke-dashoffset: -100; stroke-dasharray: 0 50;}
100% { stroke-dashoffset: -200;stroke-dasharray: 50 0;}
}
.loading2 {
animation: loading2 1s linear infinite;
}
#keyframes loading2 {
0% {stroke-dasharray: 5 28.3; stroke-dashoffset: 75;}
50% {stroke-dasharray: 45 5; stroke-dashoffset: -50;}
100% {stroke-dasharray: 5 28.3; stroke-dashoffset: -125; }
}
.spin {
animation: spin 1s linear infinite;
stroke-dashoffset: 25;
}
#keyframes spin {
0% {stroke-dashoffset: 0; stroke-dasharray: 33.3 0; }
50% {stroke-dashoffset: -100; stroke-dasharray: 0 33.3;}
100% { stroke-dashoffset: -200;stroke-dasharray: 33.3 0;}
}
.chrome {
animation: chrome 2s linear infinite;
}
#keyframes chrome {
0% {stroke-dasharray: 0 100; stroke-dashoffset: 25;}
25% {stroke-dasharray: 75 25; stroke-dashoffset: 0;}
50% {stroke-dasharray: 0 100; stroke-dashoffset: -125;}
75% {stroke-dasharray: 75 25; stroke-dashoffset: -150;}
100% {stroke-dasharray: 0 100; stroke-dashoffset: -275;}
}
.chrome2 {
animation: chrome2 1s linear infinite;
}
#keyframes chrome2 {
0% {stroke-dasharray: 0 100; stroke-dashoffset: 25;}
25% {stroke-dasharray: 50 50; stroke-dashoffset: 0;}
50% {stroke-dasharray: 0 100; stroke-dashoffset: -50;}
75% {stroke-dasharray: 50 50; stroke-dashoffset: -125;}
100% {stroke-dasharray: 0 100; stroke-dashoffset: -175;}
}
.flower {
animation: flower 1s linear infinite;
}
#keyframes flower {
0% {stroke-dasharray: 0 20; stroke-dashoffset: 25;}
50% {stroke-dasharray: 20 0; stroke-dashoffset: -50;}
100% {stroke-dasharray: 0 20; stroke-dashoffset: -125;}
}
.flower2 {
animation: flower2 1s linear infinite;
}
#keyframes flower2 {
0% {stroke-dasharray: 5 20; stroke-dashoffset: 25;}
50% {stroke-dasharray: 20 5; stroke-dashoffset: -50;}
100% {stroke-dasharray: 5 20; stroke-dashoffset: -125;}
}
.backstreet_boys {
animation: backstreet_boys 3s linear infinite;
}
#keyframes backstreet_boys {
0% {stroke-dasharray: 5 28.3; stroke-dashoffset: -225;}
15% {stroke-dasharray: 5 28.3; stroke-dashoffset: -300;}
30% {stroke-dasharray: 5 20; stroke-dashoffset: -300;}
45% {stroke-dasharray: 5 20; stroke-dashoffset: -375;}
60% {stroke-dasharray: 5 15; stroke-dashoffset: -375;}
75% {stroke-dasharray: 5 15; stroke-dashoffset: -450;}
90% {stroke-dasharray: 5 15; stroke-dashoffset: -525;}
100% {stroke-dasharray: 5 28.3; stroke-dashoffset: -925;}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg width="600px" height="700px"></svg>
Also available on CodePen: https://codepen.io/anon/pen/PeRazr
Here is a full-fledged css solution inspired by Bulma. Just add
.button {
display: inline-flex;
align-items: center;
justify-content: center;
position: relative;
min-width: 200px;
max-width: 100%;
min-height: 40px;
text-align: center;
cursor: pointer;
}
#-webkit-keyframes spinAround {
from {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
#keyframes spinAround {
from {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
transform: rotate(359deg);
}
}
.button.is-loading {
text-indent: -9999px;
box-shadow: none;
font-size: 1rem;
height: 2.25em;
line-height: 1.5;
vertical-align: top;
padding-bottom: calc(0.375em - 1px);
padding-left: 0.75em;
padding-right: 0.75em;
padding-top: calc(0.375em - 1px);
white-space: nowrap;
}
.button.is-loading::after {
-webkit-animation: spinAround 500ms infinite linear;
animation: spinAround 500ms infinite linear;
border: 2px solid #dbdbdb;
border-radius: 290486px;
border-right-color: transparent;
border-top-color: transparent;
content: "";
display: block;
height: 1em;
position: relative;
width: 1em;
}
The only thing I found that worked was a post here:
https://stackoverflow.com/a/44548729/9488229
I improved it, and now it provides all these features:
Disable the button after click
Show an animated loading icon using native bootstrap
Re-enable the button after the page is done loading
Text goes back to original when page loading is done
Javascript:
$(document).ready(function () {
$('.btn').on('click', function() {
var e=this;
setTimeout(function() {
e.innerHTML='<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Searching...';
e.disabled=true;
},0);
return true;
});
});
You can use the Bootstrap spinner. Use "position: absolute" to make both buttons over each other. With the JavaScript code you can remove the front button and the back button will be displayed.
button {
position: absolute;
top: 50px;
left: 150px;
width: 150px;
font-size: 120%;
padding: 5px;
background: #B52519;
color: #EAEAEA;
border: none;
margin: 120px;
border-radius: 5px;
display: flex;
align-content: center;
justify-content: center;
transition: all 0.5s;
height: 40px
}
#orderButton:hover {
color: #c8c8c8;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<button><div class="spinner-border"></div></button>
<button id="orderButton" onclick="this.style.display= 'none';">Order!</button>

Resources