How to stop CSS3 animation in Android Browser? - javascript

I have a div which spins:
<div class="medium animated"></div>
.medium {
position: absolute;
width: 100px;
height: 100px;
}
.animated {
animation: spin 5s linear infinite;
}
#keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
I want it to stop when I click on it. I add animation-play-state: paused in onClick event listener and it works good everywhere except iOS and Android Browser
So, okay, I want just stop the animation on click in those browsers, not pause. So I remove animated class from the DIV. It works in iOS, but doesn't work in Android Browser. The DIV continues to spin.
How can I stop the animation in Android Browser?
Here is jsfiddle with an example

Check this out — http://jsfiddle.net/sergdenisov/hpvqfut5/4/.
$('.js-start-stop').on('click', function() {
$('.js-circle').toggleClass('circle_animated');
});
$('.js-continue-pause').on('click', function() {
$('.js-circle').toggleClass('circle_paused');
});
.circle {
width: 100px;
height: 100px;
background: red;
border-radius: 50%;
overflow: hidden;
margin-bottom: 20px;
}
.circle__sector {
float: left;
width: 10%;
height: 100%;
background: yellow;
}
.circle_animated {
-webkit-animation: spin 5s linear infinite;
animation: spin 5s linear infinite;
}
.circle_paused {
-webkit-animation-play-state: paused;
animation-play-state: paused;
}
#-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="circle circle_animated js-circle">
<div class="circle__sector"></div>
</div>
<button class="js-start-stop" type="button">Start/Stop</button>
<button class="js-continue-pause" type="button">Continue/Pause</button>
I tested on Android Browser 4.1.2 and iOS Safari 8.3 and could say so:
It seems like browser bug with animation-play-state: paused, cause CSS property is really applied in iOS Safari (I think on Android it's similar). I think you can do nothing with it.
Button Start/Stop (animation) works well.

Related

SVG image not display on Safari browser

I have one problem which I don't know how to resolve it.
I have one SVG image and I have added animation on it using CSS it works fine in Chrome and Mozilla except in Safari.
The problem is that I can't see the image displayed in Safari.
<object
type="image/svg+xml"
class="img-sth"
height="150"
width="150"
data="/img/image.svg">
</object>
I have added animation on it using CSS:
.img-sth {
position: absolute;
height: 80px;
top: -3px;
left: 16px;
-webkit-animation:spin-faster 4s linear 0.01s infinite;
-moz-animation:spin-faster 4s linear 0.01s infinite;
animation:spin-faster 4s linear 0.01s infinite;
}
#-moz-keyframes spin-faster { 100% { -moz-transform: rotate(360deg); } }
#-webkit-keyframes spin-faster { 100% { -webkit-transform: rotate(360deg); } }
#keyframes spin-faster { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
Any idea?

CSS animation to occur on a timer to create a heartbeat animation

The snippet below shows a spinning circle. Every 1 second I want this circle to double in size and then shrink back to it's original size(to look like a heartbeat). The way I am attempting to do this is by creating a timer in javascript so that every one second, the class which causes the grow effect is removed from the circle, and then immediately added back on. I was hoping that having the class added back on after being removed would trigger the animation but I guess not. Right now the "heartbeat" only happens once.
Also I would like to have the circle spinning at constant speed if that's possible. Right now the circle really slows down at the end, and starts a little bit slow.
// set timeout
let tid = setTimeout(mycode, 1000);
function mycode() {
// do some stuff...
let ic = document.getElementById('inner-circle')
ic.classList.remove('heartbeat')
ic.classList.add('heartbeat')
tid = setTimeout(mycode, 1000); // repeat myself
}
function abortTimer() { // to be called when you want to stop the timer
clearTimeout(tid);
}
#spinning-circle {
animation-name: spinning-circle;
animation-duration: 10s;
animation-iteration-count: infinite;
width: 40px;
height: 40px;
}
.heartbeat {
width: 100%;
height: 100%;
animation-name: heartbeat;
animation-duration: 0.15s;
animation-iteration-count: 2;
animation-direction: alternate;
animation-fill-mode: both;
}
#inner-circle img {
width: 100%;
height: auto;
}
#-webkit-keyframes heartbeat {
100% {
transform: scale(2,2);
-webkit-transform: scale(2,2);
}
}
#-webkit-keyframes spinning-circle {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
<div id="spinning-circle">
<div id='inner-circle'>
<img src="http://i.stack.imgur.com/WbNlQ.jpg">
</div>
</div>
use setInterval() and clearInterval() instead of setTimeout(), and remove the setTimeout() inside the function mycode()
// set timeout
let tid = setInterval(mycode, 1000);
function mycode() {
// do some stuff...
let ic = document.getElementById('inner-circle')
ic.classList.remove('heartbeat')
ic.classList.add('heartbeat')
}
function abortTimer() { // to be called when you want to stop the timer
clearInterval(tid);
}
and for the animation speed add animation-timing-function: linear; to .heartbeat {} and #spinning-circle {}
You don't need javascript at all:
#spinning-circle {
margin-top: 40px;
margin-left: 40px;
animation: spinning-circle linear 10s infinite;
width: 40px;
height: 40px;
overflow: visible;
}
#inner-circle {
animation: heartbeat 1s infinite;
}
#inner-circle img {
width: 100%;
height: auto;
}
#keyframes heartbeat {
0% {
transform: scale(1);
}
25% {
transform: scale(2);
}
50% {
transform: scale(1);
}
100% {
transform: scale(1);
}
}
#keyframes spinning-circle {
0% {
transform: rotate(0turn);
}
100% {
transform: rotate(-1turn);
}
}
<div id="spinning-circle">
<div id='inner-circle'>
<img src="http://i.stack.imgur.com/WbNlQ.jpg">
</div>
</div>

How to change how fast an element spins in CSS

So the element That I am manipulating has an id of spinning and a class of rotors
I can get my element to spin. I did this by using the css code here:
.rotors {
position: relative;
top: 90px;
left: 30px;
-webkit-animation:spin .5s linear infinite;
-moz-animation:spin .5s linear infinite;
animation:spin .5s linear infinite;
} #-moz-keyframes spin { 100% { -moz-transform:rotate(360deg);}}
#-webkit-keyframes spin { 100% { -webkit-transform:rotate(360deg);}}`
#keyframes spin { 100% { -webkit-transform:rotate(360deg);}}
But Say instead of it spinning automatically on the page load that I could press a button with an id of one and it would start to spin, and if I press a second button with an id of two, it would spin even faster then the first.
I am not sure how to achieve this. I did see where some people pointed out that you can change the css of an element using javascript but am unsure on how to achieve this especially on a button click. I want it to be something like getElementById(spinning).style.property = but on button click and just changing the speed of the rotation of my element.
One option would be to change the animation-duration CSS property dynamically with JavaScript.
var rotors = document.querySelector(".rotors");
function fast() {
rotors.style.animationDuration = ".2s";
}
function slow() {
rotors.style.animationDuration = ".5s";
}
.rotors {
height: 50px; /* for demo purpose */
width: 50px; /* for demo purpose */
animation: spin .5s linear infinite;
}
#keyframes spin {
100% { transform: rotate(360deg); }
}
<p>
<button onclick="fast()">Fast</button>
<button onclick="slow()">Slow</button>
</p>
<img class="rotors" src="https://cdn.onlinewebfonts.com/svg/img_489361.png" />
Add 2 buttons and use it to change the classes like below:
function startSpinning(){
var spDiv = document.getElementById('test');
if(spDiv.classList.contains('rotorsFast')){
spDiv.classList.remove('rotorsFast');
spDiv.classList.add('rotors');
}else{
spDiv.classList.add('rotors');
}
}
function startSpinningFast(){
var spDiv = document.getElementById('test');
if(spDiv.classList.contains('rotors')){
spDiv.classList.remove('rotors');
spDiv.classList.add('rotorsFast');
}else{
spDiv.classList.add('rotorsFast');
}
}
.rotors {
position: relative;
top: 90px;
left: 30px;
-webkit-animation: spin .5s linear infinite;
-moz-animation: spin .5s linear infinite;
animation: spin .5s linear infinite;
}
.rotorsFast {
position: relative;
top: 90px;
left: 30px;
-webkit-animation: spin .2s linear infinite;
-moz-animation: spin .2s linear infinite;
animation: spin .2s linear infinite;
}
#-moz-keyframes spin {
100% {
-moz-transform: rotate(360deg);
}
}
#-webkit-keyframes spin {
100% {
-webkit-transform: rotate(360deg);
}
}
` #keyframes spin {
100% {
-webkit-transform: rotate(360deg);
}
}
<div id="test" style="width:20px">apple</div>
<button onclick="startSpinning()">spin</button>
<button onclick="startSpinningFast()">spin Fast</button>
This is a nice spot to use a CSS custom variable. When the button is clicked, we toggle a secondary class on the .rotors div. When the faster class is present, the custom variable resets the animation speed to the faster speed, which is automatically applied to the animation.
const rotors = document.querySelector('.rotors');
const btn = document.querySelector('.rotorButton');
btn.addEventListener('click', () => {
rotors.classList.toggle('faster')
});
.rotors {
--spin-speed: 2s; /* Initial speed */
position: relative;
top: 40px;
left: 30px;
background-color: yellow;
color: black;
display: inline-block;
animation: spin var(--spin-speed) linear infinite;
}
.rotors.faster {
--spin-speed: .5s; /* Faster speed 🔥 */
}
#keyframes spin {
100% {
transform: rotate(360deg);
}
}
<div class="rotors">text</div>
<button class="rotorButton" type="button">Toggle Rotor Speed</button>
jsFiddle

How do I make a div flash from 0 opacity to 1, continuously without clicking?

It's "Scroll Down" text, and I just need it to smoothly flash back and forth from 0 opacity to 1 the whole time the user is on the page.
Here's the HTML and CSS:
<div class="begin-scroll">SCROLL<br>
<span>TO BEGIN</span>
</div>
.begin-scroll{
font-family:'Charliedontsurf';
font-size:43px;
color:#FFFFFF;
position:absolute;
bottom:20%;
width: 100%;
text-align: center;
line-height:0.7em;
opacity:0;
}
.begin-scroll span{
font-size:34px;
}
This is the code that works for the type of effect I want (minus the continuous flashing):
jQuery(document).ready(function($) {
$('.begin-scroll').delay(3500).fadeTo(1000,1).fadeTo(1000,0).fadeTo(1000,1).fadeTo(1000,0).fadeTo(1000,1);
});
This is the kind of code I want, but the console log was throwing a "too much recursion" error:
jQuery(document).ready(function($) {
$('.begin-scroll').delay(3500).fadeTo(1000,1,pulsatingOut());
function pulsatingOut(){
$('.begin-scroll').fadeTo(1000, 0, pulsatingIn());
}
function pulsatingIn(){
$('.begin-scroll').fadeTo(1000, 1, pulsatingOut());
}
});
I'm not too fond of jQuery, so forgive me if this is a poorly put together and/or dumb question. Oh, and if you want to replace the jQuery altogether with plain 'ol javascript to solve this, please feel free, any solution helps.
Must it be Javascript/jQuery? This can be solved in CSS using animations and keyframes.
#-webkit-keyframes NAME-YOUR-ANIMATION {
0% { opacity: 0; }
50% { opacity: 1; }
100% {opacity: 0; }
}
#-moz-keyframes NAME-YOUR-ANIMATION {
0% { opacity: 0; }
50% { opacity: 1; }
100% {opacity: 0; }
}
#-o-keyframes NAME-YOUR-ANIMATION {
0% { opacity: 0; }
50% { opacity: 1; }
100% {opacity: 0; }
}
#keyframes NAME-YOUR-ANIMATION {
0% { opacity: 0; }
50% { opacity: 1; }
100% {opacity: 0; }
}
#box {
-webkit-animation: NAME-YOUR-ANIMATION 2s infinite; /* Safari 4+ */
-moz-animation: NAME-YOUR-ANIMATION 2s infinite; /* Fx 5+ */
-o-animation: NAME-YOUR-ANIMATION 2s infinite; /* Opera 12+ */
animation: NAME-YOUR-ANIMATION 2s infinite; /* IE 10+, Fx 29+ */
}
<div id="box" style="width: 50px; height: 50px; background-color: red;"></div>
Remove the () from your complete parameters in the .fadeTo call. You want to simply pass a reference of that function, not the result.
;(function($){
$(function(){
// store a reference (slight cache improvement)
var $el = $('.begin-scroll');
// declare the functions
function pulsatingOut(){
$el.fadeTo(1000, 0, pulsatingIn);
}
function pulsatingIn(){
$el.fadeTo(1000, 1, pulsatingOut);
}
// call first one and have it loop through
pulsatingIn();
});
})(jQuery);
.begin-scroll { width: 100px; height: 100px; background-color: #f0f; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="begin-scroll"></div>
This is similar to Brad's answer, but a more basic approach.
As Brad said, you will want to pass a callback to the fadeTo method. Callbacks are also known as delegates, function references, etc. As soon as you add the parentheses at the end, you are telling JavaScript to execute that function reference.
Since I had already developed my fiddle while Brad was answering, here's what I came up with. It's not as self-contained, but it works and gives you a simplified idea. I did have to change your text color to black.
jsfiddle: http://jsfiddle.net/o5qgq6LL/1/
function pulsatingIn(){
$(this).fadeIn(1000, pulsatingOut);
}
function pulsatingOut(){
$(this).fadeOut(1000, pulsatingIn);
}
$('.begin-scroll').delay(3500).fadeIn(1000, pulsatingOut);
.begin-scroll{
font-family:sans-serif;
font-size:43px;
color:#000;
position:absolute;
bottom:20%;
width: 100%;
text-align: center;
line-height:0.7em;
display:none;
}
.begin-scroll span{
font-size:34px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="begin-scroll">SCROLL<br>
<span>TO BEGIN</span>
</div>

CSS3 Keyframe Animations: End and stay on the last frame

I've run into some difficulty trying to play a CSS3 keyframe animation and have the relevant element stick at the last frame after the animation has completed. To my understanding, the property that I have to set for this to work should be animation-fill-mode, which should have the value of forwards; this doesn't do anything.
.animatedSprite {
.animation-name: sprite;
.animation-duration: .5s;
.animation-iteration-count: 1;
.animation-direction: normal;
.animation-timing-function: steps(3);
.animation-fill-mode: forwards;
//Vendor prefixes... }
This will just play the animation once and then go back to the first frame. I found an example of keyframe animations at JSFiddle ( http://jsfiddle.net/simurai/CGmCe/ ), and changing the fill mode to forwards and setting the iteration count to 1 wouldn't do anything there, either.
Any help would be greatly appreciated.
animation-fill-mode:forwards is the correct property to use. Is does not seem to work because the sprite image background has a default background-repeat:repeat, so the last frame you think you are seeing is actually the first frame of the repeated background image.
If you set
background: url("http://files.simurai.com/misc/sprite.png") no-repeat
animation: play .8s steps(10) forwards;
#keyframes play {
from { background-position: 0px; }
to { background-position: -500px; }
}
and run the demo the final frame is now blank - so forwards is doing what it should do. The second part of the solution is to change the final to and steps CSS properties to position the background correctly. So we really need the background to stop at -450px and use 9 steps.
-webkit-animation: play .8s steps(9) forwards;
#keyframes play {
from { background-position: 0; }
to { background-position: -450px; }
}
See demo - I only fixed the Chrome properties. Also here is the sample image in case the original disappears.
.hi {
width: 50px;
height: 72px;
background: url("http://i.stack.imgur.com/ilKfd.png") no-repeat;
-webkit-animation: play .8s steps(9) forwards;
-moz-animation: play .8s steps(10) infinite;
-ms-animation: play .8s steps(10) infinite;
-o-animation: play .8s steps(10) infinite;
animation: play .8s steps(9) forwards;
}
#-webkit-keyframes play {
from { background-position: 0px; }
to { background-position: -450px; }
}
#-moz-keyframes play {
from { background-position: 0px; }
to { background-position: -500px; }
}
#-ms-keyframes play {
from { background-position: 0px; }
to { background-position: -500px; }
}
#-o-keyframes play {
from { background-position: 0px; }
to { background-position: -500px; }
}
#keyframes play {
from { background-position: 0px; }
to { background-position: -450px; }
}
<div class="hi"></div>
Change 'infinite' to '1' in the css, this fixes it for me
just add
animation: mymove .8s forwards;
here 'mymove' is name of my keyframe
example:
<html>
<head>
<style>
div {
width: 100px;
height: 100px;
background: red;
position: relative;
animation: mymove .8s forwards;
}
#keyframes mymove {
from {top: 0px;}
to {top: 200px;}
}
</style>
</head>
<body>
<h1>The #keyframes Rule</h1>
<div></div>
</body>
</html>
The following code will make the transition stay on the last frame:
-webkit-timing-function:ease;
-webkit-iteration-count:1;

Categories