'animation-direction' not working. Why? - css

Here's the fiddle: http://jsfiddle.net/joplomacedo/mnj8n/
#-webkit-keyframes half-flip {
0% { -webkit-transform: rotateX(0deg); }
100% { -webkit-transform: rotateX(90deg); }
}
.half-flip-out {
-webkit-animation: half-flip 1s;
-webkit-transform: rotateX(90deg);
}
.half-flip-in {
-webkit-animation: half-flip 1s reverse;
-webkit-transform: rotateX(0deg);
}
I'm toggling the classes with jQuery. For some reason, .half-flip-in is doing exactly the same as .half-lip-out. I can't figure out why.

The problem does not lie in animation-direction. I'll explain more later so let's just dive into it for now.
Your CSS3 keyframes animation declarations should look like this instead:
#-webkit-keyframes half-flip {
0% {
-webkit-transform: rotateX(0deg);
}
100% {
-webkit-transform: rotateX(90deg);
}
}
#-webkit-keyframes half-flip02 {
0% {
-webkit-transform: rotateX(90deg);
}
100% {
-webkit-transform: rotateX(0deg);
}
}
.half-flip-out {
-webkit-animation: half-flip 1s;
}
.half-flip-in {
-webkit-animation: half-flip02 1s;
}
As you can see in the above, there are 2 #-webkit-keyframes declarations - each being the direct opposite of the other. Note also that I removed -webkit-transform: rotateX(0deg); and -webkit-transform: rotateX(90deg); from both .half-flip-out and .half-flip-in. The reason is simple: It is already defined in the keyframes animation at 0%, which is the 1st frame, and at 100%, which is the last frame.
Next, you should clear up your jQuery. It is not necessary to use a counter to decide which class to add or remove from the DIV. Also, shorter codes in jQuery equates to faster execution. Always optimize your codes.
This is how your jQuery looks like:
var folding_img_wrap = $('.folding_img_wrap'),
toggle_count = 0;
$('.toggle').on('click', function() {
if (toggle_count % 2 === 0) {
folding_img_wrap.addClass('half-flip-out').removeClass('half-flip-in');
} else {
folding_img_wrap.removeClass('half-flip-out').addClass('half-flip-in');
}
toggle_count++;
});
And this is how I recommend it should be:
var folding_img_wrap = $('.folding_img_wrap'),
$(".toggle").toggle(function(){
folding_img_wrap.addClass('half-flip-in').removeClass('half-flip-out');
},function(){
folding_img_wrap.removeClass('half-flip-out').addClass('half-flip-in');
});
You can view my solution here.
Remember also to use the -moz- prefixes for your CSS3 declarations otherwise, this is only gonna be working on Chrome & Safari. Also note that keyframes isn't supported in IE9 or in Opera.

Related

Animating rotation of elements starting at different rotation angles

I'm trying to create a simple animation, an element should do a full spin around a radius(using transform-origin), the problem is that I want that element to begin with an angle.
For a spin that starts from 0deg, I know I can do:
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
But I want it to start with an angle, and this doesn't work:
#keyframes spin {
0% { transform: rotate(45deg); }
100% { transform: rotate(45deg); }
}
I understand why. because its the same point... but how do i do a full spin in this case?
Here's a simplified version of it. I have no problem with mixing this with JS to make it work:
https://jsfiddle.net/shock/qqdkj7hx/
Try the following:
#keyframes spin {
0% { transform: rotate(45deg); }
100% { transform: rotate(405deg); }
}
FIDDLE

Waving flag effect CSS3 performance issues

I have a set of boxes where each box has an animation:
#keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(0); }
100% { transform: scale(1); }
}
In order to create a waving flag effect, I use the animation-delay CSS property:
.pulsate1 {
-webkit-animation-delay: 2s;
}
.pulsate2 {
-webkit-animation-delay: 2.05s;
}
/* And so on up to pulsate20 */
These pulsateN classes are wrapped around each row of boxes.
There is some occasional flickering using this method, as seen in this fiddle. Is there another better solution?
The flickering occurs because CSS doesn't know what to do with scale of 0. Change it to something low like 0.001 and enjoy your smoothly-waving flag :)
#keyframes pulse {
0% { transform: scale(1) translateZ(0); }
50% { transform: scale(0.001) translateZ(0) }
100% { transform: scale(1) translateZ(0) }
}
(As mentioned by skyline You can add translateZ(0) to take advantage of the GPU)
scale() is a 2D transformation style. Try adding translateZ(0) or translate3d(0,0,0) to the animation. This will trick the browser into thinking it's doing 3D transformations and will offload the work to the GPU if available. I'm not seeing any flickering on Chrome 49.
#keyframes pulse {
0% { transform: scale(1) translateZ(0); }
50% { transform: scale(0) translateZ(0); }
100% { transform: scale(1) translateZ(0); }
}
Here's an article explaining the performance benefits of translate3d: https://aerotwist.com/blog/on-translate3d-and-layer-creation-hacks/

CSS3 animation iteration count 1 vs infinite chrome compatibility

Ok. I tried to search for this question. and it's very simple. I have a css swing animation working good in firefox but not in chrome. Of course, I added the webkit prefix. but still no luck. I changed the iteration count to infinite and finally it is working, but no I don't want it to run infinitely. Is this really a bug? does anybody find a solution? here's the link to the code I made in jsfiddle .. http://jsfiddle.net/7t1uvyup/2/ and here's the actual code.
.x{
height:50px;
width:50px;
background:#000;
position:fixed;
}
.x:hover
{
-webkit-animation: swing 1s ease;
animation: swing 1s ease;
/* change webkit iteration count to infinite and it will work on chrome but of course with infinite animation */
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
#-webkit-keyframes swing
{
15%
{
-webkit-transform: translateX(5px);
transform: translateX(5px);
}
30%
{
-webkit-transform: translateX(-5px);
transform: translateX(-5px);
}
50%
{
-webkit-transform: translateX(3px);
transform: translateX(3px);
}
65%
{
-webkit-transform: translateX(-3px);
transform: translateX(-3px);
}
80%
{
-webkit-transform: translateX(2px);
transform: translateX(2px);
}
100%
{
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
#keyframes swing
{
15%
{
-webkit-transform: translateX(5px);
transform: translateX(5px);
}
30%
{
-webkit-transform: translateX(-5px);
transform: translateX(-5px);
}
50%
{
-webkit-transform: translateX(3px);
transform: translateX(3px);
}
65%
{
-webkit-transform: translateX(-3px);
transform: translateX(-3px);
}
80%
{
-webkit-transform: translateX(2px);
transform: translateX(2px);
}
100%
{
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
<div class="x"></div>
I did some research.. CSS is Hardware-Accelerated..
So this is not just a weird random bug.
I ran into this problem just now. To me it seems that the animation takes place in very short period of time and many times it is not noticable to human eyes; i.e. Chrome does not respect animation duration parameter when webkit-animation-iteration-count is not infinite.
To me it doesn't seem to be a random bug. It is reliably reproducible.
Try visiting http://www.w3schools.com/css/css3_animations.asp with different browsers. Chrome shows the worst performance; CSS3 animation box does not animate; it just stays.

div animate on hover

I would like to know how to make a div play a CSS animation while hovering over it, and how to make it play the animation backwards when the mouse stops hovering over it. I already have my animation, generated with a handy online CSS keyframes animation generator program.
.element-animation{
-webkit-animation: animationFrames ease 1s;
-webkit-animation-iteration-count: 1;
-webkit-transform-origin: 0% 0%;
-webkit-animation-fill-mode:forwards; /*Chrome 16+, Safari 4+*/
}
#-webkit-keyframes animationFrames {
0% {
left:0px;
top:0px;
opacity:1;
-webkit-transform: rotate(0deg) scaleX(1) scaleY(1) ;
}
20% {
-webkit-transform: rotate(60deg) ;
}
40% {
-webkit-transform: rotate(40deg) ;
}
60% {
-webkit-transform: rotate(54deg) ;
}
80% {
-webkit-transform: rotate(42deg) ;
}
100% {
left:0px;
top:0px;
opacity:1;
-webkit-transform: rotate(46deg) scaleX(1) scaleY(1) ;
}
}
All help greatly appreciated!
Add :hover to css class like this element-animation:hover
Check fiddle http://jsfiddle.net/PawelK/SF4Zy/3/ tested with Chrome
To trigger the CSS animation on the hover event, you will need to add an event listener via JavaScript.
document.querySelector('#div1').addEventListener('mouseenter', function(){
this.classList.add('element-animation');
});
Or, if you are using jQuery:
$('#div1').on('mouseenter', function(){
$(this).addClass('element-animation');
});
fiddle

Preseve a state with CSS 3 transforms

I would like to create an animation in two parts. I explain a bit.
I have a rectangle, at the beggining of the animation, the top will have an animation to be shrink. After this end of this animation, I would like to keep this state, use js to detect when the animation is finished and add my second animation the shrink the bottom of the rectangle. At the moment, there are the two animations, but don't keep in mind the previous state.
#-webkit-keyframes scale {
100% {
-webkit-transform-origin: 50% 100%;
-webkit-transform: perspective(900px) rotateX(10deg);
}
}
#-moz-keyframes scale {
100% {
-moz-transform-origin: 50% 100%;
-moz-transform: perspective(900px) rotateX(10deg);
}
}
.scale {
-webkit-transform-origin: 50% 100%;
-webkit-transform: perspective(900px) rotateX(10deg);
-moz-transform-origin: 50% 100%;
-moz-transform: perspective(900px) rotateX(10deg);
}
#-webkit-keyframes toto {
100% {
-webkit-transform-origin: 50% 0%;
-webkit-transform: perspective(900px) rotateX(-10deg);
}
}
#-moz-keyframes toto {
100% {
-moz-transform-origin: 50% 0%;
-moz-transform: perspective(900px) rotateX(-10deg);
}
}
.scale2 {
background: purple !important;
-webkit-animation: toto 1.4s ease forwards !important;
-moz-animation: toto 1.4s ease forwards !important;
}
A little jsfiddle with the code : http://jsfiddle.net/JeremDsgn/Dfyam/2/
I would recommend that you use a plugin such as jQuery Transit since it is ideal for preserving the state of your css3 transitions/transforms, especially if you are planning on doing a lot of animations. It is a lot easier than maintaining a big CSS file.
Example:
//Initial settings on Window DIV
$('#window').css( { 'transformOrigin': '50% 100%', perspective: '900', rotateX: 10 } );
$('#yoyo').on("click", function () {
$('#window').transition( { background: 'purple' }, 1400, 'in', function () {
//Do any additional animations here, such as change the background again
$('#window').delay(2000).transition( { background: 'blue' }, 3000, 'out');
});
});
JS Fiddle Demo
You can do one of two things:
Add a from or 0% to your second animation:
http://jsfiddle.net/trolleymusic/y2Hxc/
#-webkit-keyframes scale {
100% {
-webkit-transform-origin: 50% 100%;
-webkit-transform: perspective(900px) rotateX(10deg);
}
}
#-webkit-keyframes toto {
from {
-webkit-transform-origin: 50% 100%;
-webkit-transform: perspective(900px) rotateX(10deg);
}
to {
-webkit-transform-origin: 50% 0%;
-webkit-transform: perspective(900px) rotateX(-10deg);
}
}
Or add the current transform properties to the element as inline styles using javascript before adding the second transition - I think this is what you were talking about wanting:
http://jsfiddle.net/trolleymusic/TbwfC/
// Listener
$('window').addEventListener('webkitAnimationEnd', function() {
this.style.webkitTransform = window.getComputedStyle(this)["-webkit-transform"];
this.style.webkitTransformOrigin = window.getComputedStyle(this)["-webkit-transform-origin"];
this.className = 'scale2';
}, false);
So you get the current transform matrix and origin from window.getComputedStyle, and apply it to the element before changing the class name.
I have removed the -moz- prefixed lines to keep the code shorter - as ROFLwTIME pointed out it can get long quickly. Obviously using the second solution you will have to watch how you implement it in other browsers as they will need to read their respective prefixes or the non prefixed versions of transform and transform-origin.
A quick plug for SASS
If you are concerned with the complexity and size of your CSS I would consider looking at SASS (http://sass-lang.com) and Compass (http://compass-style.org), especially for transforms and animation. Instead of writing:
-webkit-transform: rotateX(10deg);
-moz-transform: rotateX(10deg);
-ms-transform: rotateX(10deg);
-o-transform: rotateX(10deg);
transform: rotateX(10deg);
You write:
#include transform(rotateX(10deg));
And SASS will output all of those lines into your CSS. It makes writing animations, transforms and transitions much more manageable.

Resources