Restart Animation in Css3: Any Better Way Than Removing the Element

Restart animation in CSS3: any better way than removing the element?

Just set the animation property via JavaScript to "none" and then set a timeout that changes the property to "", so it inherits from the CSS again.

Demo for Webkit here: http://jsfiddle.net/leaverou/xK6sa/
However, keep in mind that in real world usage, you should also include -moz- (at least).

Restart CSS3 animation using Javascript

You could check for the end of the animation by responding to the endanimation event (of which there are several browser-dependent variants), reloading the relevant nodes, and repeating the whole process. Note I applied a factor 10 to the speed of the animations so you can see the effect faster:

// Define a function that listens to all prefix variants of endanimation events:function whenAnimationEnd(element, callback) {    element.addEventListener('animationend', callback, false);    element.addEventListener('webkitAnimationEnd', callback, false);    element.addEventListener('oanimationend', callback, false);    element.addEventListener('MSAnimationEnd', callback, false);}
(function repeat() { whenAnimationEnd(document.querySelector('.click_through2'), function(e) { var container = document.querySelector('.ad_container'); var dupe = container.cloneNode(true); container.parentNode.replaceChild(dupe, container); repeat(); });}());
 .ad_container {     height: 250px;     position: relative;     width: 300px;     overflow: hidden; } .ad_container div, .ad_container a, .logo, .sfv2 {  position: absolute; } .title {     bottom: 45px;     left: 5px;     right: 5px; } .title h2 {     color: #fff;     font-family: Helvetica,arial,sans-serif;     font-size: 21px;     font-weight: 400;     line-height: 1;     margin: 0;     text-align: center; } .click_through {     background-color: #fff200;     border-radius: 5px;     bottom: 12px;     box-shadow: 0 0 15px rgba(0, 0, 0, 0.35);     color: #ce1e25;     font-family: Helvetica,arial,sans-serif;     font-size: 14px;     font-weight: 700;     left: 0;     line-height: 1;     margin: 0 auto;     padding: 5px;     right: 0;     text-align: center;     width: 70px;     text-decoration: none; } .click_through1 {  animation: tbio 0.7s ease-out 0s both;  -moz-animation: tbio 0.7s ease-out 0s both;  -webkit-animation: tbio 0.7s ease-out 0s both;  -ms-animation: tbio 0.7s ease-out 0s both;  -o-animation: tbio 0.7s ease-out 0s both; } .click_through2 {  animation: tbio 0.7s ease-out 1s both;  -moz-tbio tbio 0.7s ease-out 1s both;  -webkit-tbio tbio 0.7s ease-out 1s both;  -ms-tbio tbio 0.7s ease-out 1s both;  -o-tbio tbio 0.7s ease-out 1s both;  width: 80px; } .logo {  top: 8px;  left: 8px; } .title1 {  animation: ltrio 0.6s ease 0s both;  -moz-animation: ltrio 0.6s ease 0s both;  -webkit-animation: ltrio 0.6s ease 0s both;  -ms-animation: ltrio 0.6s ease 0s both;  -o-animation: ltrio 0.6s ease 0s both; } .title2, .title3 {  opacity: 0; } .title2 {  animation: ltrio 0.6s ease 0.55s both;  -moz-animation: ltrio 0.6s ease 0.55s both;  -webkit-animation: ltrio 0.6s ease 0.55s both;  -ms-animation: ltrio 0.6s ease 0.55s both;  -o-animation: ltrio 0.6s ease 0.55s both; } .title3 {  animation: ltrio 0.6s ease 1s both;  -moz-nimation: ltrio 0.6s ease 1s both;  -webkit-nimation: ltrio 0.6s ease 1s both;  -ms-onimation: ltrio 0.6s ease 1s both;  -o-nimation: ltrio 0.6s ease 1s both; } .sfv2 {     right: 12px;     top: 34px;     animation: fio 0.6s ease 1.1s both;     -moz-animation: fio 0.6s ease 1.1s both;     -webkit-animation: fio 0.6s ease 1.1s both;     -ms-animation: fio 0.6s ease 1.1s both;     -o-animation: fio 0.6s ease 1.1s both; }  @keyframes ltrio {  0% {   opacity: 0;  }  20% {   opacity: 1;  }  50% {   opacity: 1;  }  80% {   opacity: 0;  }  100% {   opacity: 0;  } } @-moz-keyframes ltrio {  0% {   opacity: 0;  }  20% {   opacity: 1;  }  50% {   opacity: 1;  }  80% {   opacity: 0;  }  100% {   opacity: 0;  } }
@-ms-keyframes ltrio { 0% { -ms-transform: translateY(-350px); opacity: 0; } 25% { -ms-transform: translateY(0); opacity: 1; } 75% { -ms-transform: translateY(0); opacity: 1; } 100% { -ms-transform: translateY(350px); opacity: 0; } } @-o-keyframes ltrio { 0% { -o-transform: translateX(-350px); opacity: 0; } 25% { -o-transform: translateX(0); opacity: 1; } 75% { -o-transform: translateX(0); opacity: 1; } 100% { -o-transform: translateX(350px); opacity: 0; } } @keyframes tbio { 0% { transform: translateY(350px); opacity: 0; } 25% { transform: translateY(0); opacity: 1; } 75% { transform: translateY(0); opacity: 1; } 100% { transform: translateY(350px); opacity: 0; } } @-moz-keyframes tbio { 0% { -moz-transform: translateY(350px); opacity: 0; } 25% { -moz-transform: translateY(0); opacity: 1; } 75% { -moz-transform: translateY(0); opacity: 1; } 100% { -moz-transform: translateY(350px); opacity: 0; } } @-webkit-keyframes tbio { 0% { -webkit-transform: translateY(350px); opacity: 0; } 25% { -webkit-transform: translateY(0); opacity: 1; } 75% { -webkit-transform: translateY(0); opacity: 1; } 100% { -webkit-transform: translateY(350px); opacity: 0; } } @-ms-keyframes tbio { 0% { -ms-transform: translateY(350px); opacity: 0; } 25% { -ms-transform: translateY(0); opacity: 1; } 75% { -ms-transform: translateY(0); opacity: 1; } 100% { -ms-transform: translateY(350px); opacity: 0; } } @-o-keyframes tbio { 0% { -o-transform: translateY(350px); opacity: 0; } 25% { -o-transform: translateY(0); opacity: 1; } 75% { -o-transform: translateY(0); opacity: 1; } 100% { -o-transform: translateY(350px); opacity: 0; } } @keyframes fio { 0% { opacity: 0; } 20% { opacity: 1; } 50% { opacity: 1; } 80% { opacity: 0; } 100% { opacity: 0; } }
<div class="ad_container"> <img class="sfv1" src="http://i.imgur.com/3VWKopF.jpg"> <div class="title title1">  <h2>Great value<br/> <strong>Spanish Properties</strong><br/> starting at £65k</h2> </div> <div class="title title2">  <h2>Stunning properties in <br/><strong>Costa del Sol, <br/>Blanca & Murcia</strong></h2> </div> <div class="title title3">  <h2>Over <strong>10,000 <br/>Spanish properties sold</strong></h2> </div> <a class="click_through click_through1" href="/">View here</a> <a class="click_through click_through2" href="/">Learn more</a></div>

CSS animation doesn't restart when resetting class

I think I figured it out. According to this, css animation can't get applied to the same node twice (even if you have a different animation!). So I had to clone the node, remove the original, and add back the cloned node.

Restart CSS animation on the same element

When you bind event handler on div as well as on images inside the div, it will be called twice as there is no e.preventBubble() in event handler. You can avoid this by using it only on the div.

Second issue is that after first click inside the div, the transition is in final state and you don't move it to initial state. I would achieve required behavior by using 2 classes. One for transition and one for initial state, final state is implicit here, opacity:1 is default value.

.pantalla.invisible {
opacity: 0;
}

.pantalla.horizTranslateApareix {
-webkit-transition: 1s;
-moz-transition: 1s;
-ms-transition: 1s;
-o-transition: 1s;
transition: 1s;
}

Main part is in JS. We start by removing the transition, otherwise it would took 1s to hide the image as well. Then we hide the image and return the transition, do image swapping and finally show the image again, starting the transition.

function canviaImatge()
{
img2.classList.remove('horizTranslateApareix');
img2.classList.add('invisible');
img2.offsetHeight; // <-- force repaint, otherwise browser optimize and nothing changes
img2.classList.add('horizTranslateApareix');

// image swapping

img2.classList.remove('invisible');
}

This would be the ideal case, but browsers optimize, so we can't use it as simply as that. Browsers do as much as possible without repainting the page, so they merge several opearions to one and we loose our functionality. That's where magic comes in place. We enforce repaint asking for img2.offsetHeight, which has to recalculate positions and repaint the relevant part of page (possibly whole page). Other ways to achieve it, is to move code to setTimeout function, which can't be optimized either.

setTimeout(function() {
img2.classList.add('horizTranslateApareix');
img2.classList.remove('invisible');
}, 1)

Demo at http://jsfiddle.net/Gobie/e4m3R/2/

How do I re-trigger a WebKit CSS animation via JavaScript?

I found the answer based on the source code and examples at the CSS3 transition tests github page.

Basically, CSS animations have an animationEnd event that is fired when the animation completes.

For webkit browsers this event is named “webkitAnimationEnd”. So, in order to reset an animation after it has been called you need to add an event-listener to the element for the animationEnd event.

In plain vanilla javascript:

var element = document.getElementById('box');

element.addEventListener('webkitAnimationEnd', function(){
this.style.webkitAnimationName = '';
}, false);

document.getElementById('button').onclick = function(){
element.style.webkitAnimationName = 'shake';
// you'll probably want to preventDefault here.
};

and with jQuery:

var $element = $('#box').bind('webkitAnimationEnd', function(){
this.style.webkitAnimationName = '';
});

$('#button').click(function(){
$element.css('webkitAnimationName', 'shake');
// you'll probably want to preventDefault here.
});

The source code for CSS3 transition tests (mentioned above) has the following support object which may be helpful for cross-browser CSS transitions, transforms, and animations.

Here is the support code (re-formatted):

var css3AnimationSupport = (function(){
var div = document.createElement('div'),
divStyle = div.style,
// you'll probably be better off using a `switch` instead of theses ternary ops
support = {
transition:
divStyle.MozTransition === ''? {name: 'MozTransition' , end: 'transitionend'} :
// Will ms add a prefix to the transitionend event?
(divStyle.MsTransition === ''? {name: 'MsTransition' , end: 'msTransitionend'} :
(divStyle.WebkitTransition === ''? {name: 'WebkitTransition', end: 'webkitTransitionEnd'} :
(divStyle.OTransition === ''? {name: 'OTransition' , end: 'oTransitionEnd'} :
(divStyle.transition === ''? {name: 'transition' , end: 'transitionend'} :
false)))),
transform:
divStyle.MozTransform === '' ? 'MozTransform' :
(divStyle.MsTransform === '' ? 'MsTransform' :
(divStyle.WebkitTransform === '' ? 'WebkitTransform' :
(divStyle.OTransform === '' ? 'OTransform' :
(divStyle.transform === '' ? 'transform' :
false))))
//, animation: ...
};
support.transformProp = support.transform.name.replace(/([A-Z])/g, '-$1').toLowerCase();
return support;
}());

I have not added the code to detect “animation” properties for each browser. I’ve made this answer “community wiki” and leave that to you. :-)

Reuse CSS animation in reversed direction (by resetting the state?)

No, there is no way to restart the animation using CSS alone. You'd have to use JavaScript to remove the animation from the element and then re-apply it to the element (after a delay) for it to restart.

The below is what the W3C's CSS3 Animation Spec says (in a different context, but the point should hold good for this case also):

Note also that changing the value of ‘animation-name’ does not necessarily restart an animation (e.g., if a list of animations are applied and one is removed from the list, only that animation will stop; The other animations will continue). In order to restart an animation, it must be removed then reapplied.

emphasis is mine

This CSS Tricks Article by Chris Coiyer also indicates the same and provides some JS solutions for restarting an animation. (Note: The article has a reference to Oli's dabblet which claims that altering properties like duration, iteration count makes it restart on Webkit but it seems to be outdated as they no longer work on Chrome).


Summary:

While you have already touched upon the following, I am going to re-iterate for completeness sake:

  • Once an animation is applied on the element, it remains on the element until it is removed.
  • UA does keep track of the animation being on the element and whether it has completed or not.
  • When you apply the same animation on :checked (albeit with a different direction), the UA does nothing because the animation already exists on the element.
  • The switch of positions (instantaneous) while clicking the checkbox is because of the transform that is applied within the :checked selector. The animation's presence makes no difference.

Solutions:

As you can see from the below snippet, achieving this with a single animation is pretty complex even when using JavaScript.

var input = document.getElementsByClassName("my-checkbox")[0];
input.addEventListener('click', function() { if (this.checked) { this.classList.remove('my-checkbox'); window.setTimeout(function() { input.classList.add('anim'); input.classList.add('checked'); }, 10); } else { this.classList.remove('anim'); window.setTimeout(function() { input.classList.remove('checked'); input.classList.add('my-checkbox'); }, 10); }});
input {  transform: translate3d(50px, 0, 0);}.my-checkbox {  animation: moveLeft 1s;  animation-direction: reverse;}.checked {  transform: translate3d(0px, 0, 0);}.anim{  animation: moveLeft 1s;}@keyframes moveLeft {  from {    transform: translate3d(50px, 0, 0);  }  to {    transform: translate3d(0px, 0, 0);  }}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script><input type="checkbox" class="my-checkbox">

Restart CSS3 Animation without javascript?

Unfortunately it's not possible to set a delay before each animation, but you can set a delay inside the animation. Just let the animation do nothing for a while until you reach a certain percentage.

Here's the updated code.

@keyFrames scale {
90% {
transform: scale(1)
}
95% {
transform: scale(1.3)
}
100% {
transform: scale(1);
}
}

.animated-btn {
display: inline-block;
animation: scale ease-in 1;
animation-fill-mode: forwards;
animation-duration: 12.4s;
animation-delay: 0s;
animation-iteration-count: infinite;
/* Or the shorthand:
animation: scale 1.4s 0s infinite ease-in forwards;
*/
}


Related Topics



Leave a reply



Submit