webkit animation play state hover not detected while transformX - css

I am trying to pause the animation(which is a CSS transformY) state on hover but the hover is not evenly detected accross the transform range(i observed it is properly detected in the initial range and after the transform ends)
This is the code(i simplified it to minimum for posting) :
<html>
<head>
<style>
.member{
height:50px;
width:50px;
margin:30px;
border-radius:50%;
border:1px solid #AAAAAA;
background-color:black;
transition:all 0.3s ease;
-moz-animation-name: dropHeader;
-moz-animation-iteration-count: 1;
-moz-animation-timing-function: ease-in;
-moz-animation-duration: 6s;
-webkit-animation-name: dropHeader;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in;
-webkit-animation-duration: 6s;
animation-name: dropHeader;
animation-iteration-count: 1;
animation-timing-function: ease-in;
animation-duration: 6s;
}
#-moz-keyframes dropHeader {
0% {
-moz-transform: translateX(200px);
}
100% {
-moz-transform: translateY(0);
}
}
#-webkit-keyframes dropHeader {
0% {
-webkit-transform: translateX(200px);
}
100% {
-webkit-transform: translateX(0);
}
}
#keyframes dropHeader {
0% {
transform: translateX(200px);
}
100% {
transform: translateX(0);
}
}
.member:hover{
border:3px solid #ffffff;
box-shadow: 0px 0px 0px 3px #7ec0ee;
-webkit-animation-play-state: paused;
}
</style>
</head>
<body>
<div class="member">
</div>
</body>
</html>

Okay, here is the thing, i couldn't figure out the exact reason but these are all the things i tried and failed and then succeeded (in order) :
1. Removing -webkit
2. using jquery mouseover and mouseout integrated with css animationstates "running" and pause.
3. Then, i observed that after one hover if i click multiple times somewhere else on the webapage and then hover, it worked! Which gave me a hint to the direction of introducing multiple such divs and it totally works fine now.

Related

CSS keyframe animation is pausing in middle then resuming again?

This may be a dumb question (haven't done JS/HTML in a bit). I want this animation to be smooth all the way through but for some reason, it is stopping in the middle for a short period of time then resuming. Adding more steps to try and smooth the transition only seems to make is pause for longer. Is there a fix for this?
#under {
color: black;
font-size: 28px;
animation-duration: 4s;
animation-name: example;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: ease-in-out;
}
#keyframes example {
0% {
transform: translateX(-330px);
}
50% {
transform: scaleX(3);
}
100% {
transform: translateX(330px);
}
}
<body>
<div id="under">
<p> - </p>
</div>
</body>
To keep things moving evenly, you need to define your scaleX values at 0% and 100%. In addition, I changed your timing function from ease-in-out to linear. At 50%, translateX is already at 0 since you defined the start and end values. For consistency, I added the 0 value at 50%.
#under {
background-color: #000;
color: white;
animation-duration: 4s;
animation-name: example;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: linear;
width: 100px;
height: 50px;
}
#keyframes example {
0% {
transform: scaleX(1) translateX(-330px);
}
50% {
transform: scaleX(3) translateX(0);
}
100% {
transform: scaleX(1) translateX(330px);
}
}
<div id="under"></div>

how animation-direction works in css3 animation?

As i understand, when i change the animation-direction from normal to reverse during a specific animation, the element will move towards the opposite direction right away starting from where it is now.But it seems i am wrong , here is the http://codepen.io/johnwaynerui/pen/bZvRLm When i click the reverse button, the circle does not turn around right away and moving towards the opposite direction. Are there something i misunderstand?
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"> </script>
<div id="circle"></div>
<button id='reverse'>reverse</button>
#keyframes move-right {
0% {
transform: translateX(0px);
}
20% {
transform: translateX(200px);
}
40% {
transform: translateX(400px);
}
60% {
transform: translateX(600px);
}
80% {
transform: translateX(800px);
}
100% {
transform: translateX(1000px);
}
}
#circle {
height: 50px;
width: 50px;
border-radius:25px;
background-color: teal;
-webkit-animation-duration: 20s;
-webkit-animation-timing-function: linear;
-webkit-animation-name: move-right;
-webkit-animation-iteration-count: infinite;
animation-fill-mode: both;
position:absolute;
left:30%;
top:20%;
}
#circle.reverse {
animation-direction: reverse;
}
$('#reverse').click(function () {
$('#circle').toggleClass('reverse');
});
You can check the documentation for animation-direction here.
It clearly states that, for a reverse value:
The animation plays backward each cycle. Each time the animation cycles, the animation resets to the end state and starts over again.
As per my understanding, the moment you add animation-direction: reverse; to your animation, it goes in reverse direction mode that means the end-point of original animation becomes its start-point and vice-versa. So, if your animation has run first 20% and you change its animation-direction to reverse its start and end-points get interchanged, and it suddenly jumps to the 20% point relative to these changed end-points. That's why you notice that your circle suddenly jumps to far right and then continues its movement towards left.
$('#reverse').click(function () {
$('#circle').toggleClass('reverse');
});
#keyframes move-right {
0% {
transform: translateX(0px);
}
20% {
transform: translateX(200px);
}
40% {
transform: translateX(400px);
}
60% {
transform: translateX(600px);
}
80% {
transform: translateX(800px);
}
100% {
transform: translateX(1000px);
}
}
#circle {
height: 50px;
width: 50px;
border-radius:25px;
background-color: teal;
-webkit-animation-duration: 20s;
-webkit-animation-timing-function: linear;
-webkit-animation-name: move-right;
-webkit-animation-iteration-count: infinite;
animation-fill-mode: both;
position:absolute;
left:30%;
top:20%;
}
#circle.reverse {
animation-direction: reverse;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"> </script>
<div id="circle"></div>
<button id='reverse'>reverse</button>

Chaining CSS animations with infinite loop delay issue

I have chained two animations in a loop. After a lot of tweaking the images scroll in and out without overlapping. The problem is once the animations have finished there is a 3-4 second delay before they restart. I have not set any delays in my code so think there's a problem with the keyframes but when I play around with the values the images start to overlap.
I have made a pen here. Only chrome keyframes at the moment, the animation staggers in codepen but displays fine in chrome :
http://codepen.io/Nullbreaker/pen/gnkbq
<div class="rightleftloop">
<img src="http://myshoedream.com/dzinehub/Shoefever/LL10173A-BLACK-4.jpg" class="imgformat1" alt="slide" />
</div>
<div class="rightleftloop2">
<img src="http://myshoedream.com/dzinehub/Shoefever/LL10173BJ-IVORY-4.jpg" class="imgformat1" alt="slide" />
</div>
.rightleftloop {
position: absolute;
-webkit-animation:rightleftloop;
-webkit-animation-duration: 8.5s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-fill-mode: both;
-moz-animation:rightleftloop;
-moz-animation-duration: 3.5s;
-moz-animation-iteration-count: infinite;
-moz-animation-timing-function: ease-in 0.3s;
-moz-animation-fill-mode: both;
animation:rightleftloop;
animation-duration: 3.5s;
animation-iteration-count: infinite;
animation-timing-function: ease-in 0.3s;
animation-fill-mode: both;
}
.rightleftloop2 {
position: absolute;
-webkit-animation:rightleftloop2;
-webkit-animation-duration: 8.5s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-fill-mode: both;
-moz-animation:rightleftloop;
-moz-animation-duration: 3.5s;
-moz-animation-iteration-count: infinite;
-moz-animation-timing-function: ease-in 0.3s;
-moz-animation-fill-mode: both;
animation:rightleftloop;
animation-duration: 3.5s;
animation-iteration-count: infinite;
animation-timing-function: ease-in 0.3s;
animation-fill-mode: both;
}
#-webkit-keyframes rightleftloop {
0% {right:0%;-webkit-transform: translateX(-2000px);}
10% {right:20%;}
20% {right:20%;}
30% {right:20%;-webkit-transform: translateX(-10px);}
40% {right:20%;-webkit-transform: translateX(-10px);}
60% {right:20%;-webkit-transform: translateX(-2000px);}
100% {right:100%;}
}
#-webkit-keyframes rightleftloop2 {
60% {right:0%;-webkit-transform: translateX(-2000px);}
61% {right:20%;}
63% {right:20%;}
64% {right:20%;}
65% {right:20%;}
65% {right:20%;}
66% {right:20%;}
67% {right:20%;}
68% {right:20%;-webkit-transform: translateX(-2000px);}
69% {right:20%;-webkit-transform: translateX(-1000px);}
}
Your animation keyframes were not right. I've simplified your CSS as well. You can paste this css in your pen and see the results for yourself.
body {
background:#ffffff;
font-family:'Economica', Arial, sans-serif;
font-size:30px;
font-style: normal;
font-weight: 400;
color:#000000;
}
/* as properties for both required images are the same, we are using them as one group */
.rightleftloop, .rightleftloop2 {
position: absolute;
-webkit-animation:rightleftloop;
-webkit-animation-duration: 8.5s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-fill-mode: both;
}
/* the second image animation will start with a delay of the half time as the original animation time as we set our images out of the frame from 50%-100% in the keyframes - this animation delay only comes up once before the start of the original animation */
.rightleftloop2 {
-webkit-animation-delay: 4250ms;
}
/* one animation with pre-defined delay from 50%-100% of the time as content hidden so what ever animation we need will be done between 0%-50% */
#-webkit-keyframes rightleftloop {
0% {
-webkit-transform: translateX(-500px);
}
15% {
-webkit-transform: translateX(20px);
}
35% {
-webkit-transform: translateX(20px);
}
50% {
-webkit-transform: translateX(-500px);
}
100% {
-webkit-transform: translateX(-500px);
}
}

CSS3: animated sprite + on hover transition

I'm entering the world of CSS3 animations and transitions so please forgive my ignorance.
Here's the simplified version of what I'm trying to do:
I have a ball that "pulsates" infinitely via CSS3 keyframes
I want the ball to grow bigger and stay like that when I hover over it
I want the ball to become small again when I move the mouse away from it and keep pulsating (all the transitions need to be smooth, of course).
Here's my stab at it using a mix of CSS3 animations and transitions (testing this on Chrome so far, hence webkit prefixes):
#-webkit-keyframes pulsate {
from {
-webkit-transform: scale(0.7);
}
to {
-webkit-transform: scale(0.8);
}
}
.ball {
background: blue;
width: 100px;
height: 100px;
border-radius: 50%;
transition: all 1s;
-webkit-transform: scale(0.7);
-webkit-transform-origin: center center;
-webkit-animation-duration: 800ms;
-webkit-animation-name: pulsate;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: alternate;
-webkit-animation-timing-function: ease-in-out;
}
.ball:hover {
-webkit-transform: scale(2);
-webkit-animation-play-state: paused; /* transition works but gets reset at the end*/
/*-webkit-animation: 0;*/ /* transition works only one time, and no smooth transition on mouse out */
}
jsFiddle Demo
The result is pretty close but as soon as the ball finishes expanding on hover, it suddenly becomes small again (don't understand why). I also tried disabling the animation via -webkit-animation: 0; instead of pausing it but it doesn't work well either.
I tried a different approach that uses keyframes only (no transitions) by attempting to call a different keyframe set on hover:
#-webkit-keyframes pulsate {
from {
-webkit-transform: scale(0.7);
}
to {
-webkit-transform: scale(0.8);
}
}
#-webkit-keyframes expand {
to {
-webkit-transform: scale(2);
}
}
#-webkit-keyframes shrink {
to {
-webkit-transform: scale(0.7);
}
}
.ball {
background: blue;
width: 100px;
height: 100px;
border-radius: 50%;
transition: all 2s;
-webkit-transform: scale(0.7);
-webkit-transform-origin: center center;
-webkit-animation-duration: 800ms, 800ms;
-webkit-animation-name: shrink, pulsate;
-webkit-animation-iteration-count: 1, infinite;
-webkit-animation-direction: normal, alternate;
-webkit-animation-timing-function: ease-in-out, ease-in-out;
}
.ball:hover {
-webkit-animation-name: expand;
-webkit-animation-iteration-count: 1;
-webkit-animation-direction: normal;
-webkit-animation-fill-mode: forwards;
}
jsFiddle Demo
The ball stays big as long as the mouse is over it but there's still no smooth transition when the mouse moves away from the ball. I expect it to play the shrink animation instead but it doesn't.
Am I missing something or this is impossible to implement with just pure CSS at the moment?
// Related thread but didn't work for me: Stop animation and start transition on hover
You need to add an animation delay to allow the transition to complete because it reverts back to scale(.7) at the start of the animation. Updated jsFiddle
-webkit-animation-delay:1s;
EDIT
I realized that the answer I posted here was not fully correct. True, the delay animated the transition from big back to small, but if you hover over the pulsing ball when its expanded it jumps back to it's 0 value of .7 before animating to the large scale.
Updated Demo
I came up with a fix that just uses some javascript to fix it based on this article. You do have to change the CSS a little, but it's not very noticeable in the outcome. Here is the updated code
/* CSS */
body {margin: 100px;}
#-webkit-keyframes pulsate {
0% {
-webkit-transform: scale(0.7);
}
50% {
-webkit-transform: scale(0.8);
}
100% {
-webkit-transform: scale(0.7);
}
}
.ball {
background: blue;
width: 100px;
height: 100px;
border-radius: 50%;
-webkit-transform: scale(0.7);
-webkit-transform-origin: center center;
transition: all 1s;
}
.ball.animated {
-webkit-animation-duration: 1600ms;
-webkit-animation-name: pulsate;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: alternate;
-webkit-animation-timing-function: ease-in-out;
}
/* Javascript */
var ball = document.getElementsByClassName('ball')[0],
pfx = ["webkit", "moz", "MS", "o", ""],
hovered = false;
function AnimationListener() {
if(hovered)
{
ball.classList.remove('animated');
ball.style.webkitTransform = 'scale(2)';
ball.style.transform = 'scale(2)';
}
}
function TransitionListener() {
if(!hovered)
{
ball.classList.add('animated');
}
}
function PrefixedEvent(element, type, callback) {
for (var p = 0; p < pfx.length; p++) {
if (!pfx[p]) type = type.toLowerCase();
element.addEventListener(pfx[p]+type, callback, false);
}
}
PrefixedEvent(ball, "AnimationIteration", AnimationListener);
ball.onmouseover = function() {
hovered = true;
}
ball.onmouseout = function() {
hovered = false;
PrefixedEvent(ball, "TransitionEnd", TransitionListener);
ball.style.webkitTransform = 'scale(.7)';
ball.style.transform = 'scale(.7)';
}
Just update this CSS rule, I have added From & To - in Expand & Shrink:
#-webkit-keyframes expand {
from {
-webkit-transform: scale(1);
}
to {
-webkit-transform: scale(2);
}
}
#-webkit-keyframes shrink {
from {
-webkit-transform: scale(2);
}
to {
-webkit-transform: scale(1);
}
}

CSS3 Animated Rings

Looking for some help on trying to achieve a certain animation. I'm trying to create a sequence similar to the infinite expanding rings seen here. (The example rings are contracting, I'm looking to go the other direction).
I've got a pretty good start thus far, I'm just not sure how to go about making it loop "smoothly", or if it's even possible with only CSS.
Any tips or ideas are greatly appreciated. Thanks!
Demo: http://codepen.io/fractionwhole/pen/HljuG
First, let's create 6 rings
<div id="r1" class="ring"></div>
<div id="r2" class="ring"></div>
<div id="r3" class="ring"></div>
<div id="r4" class="ring"></div>
<div id="r5" class="ring"></div>
<div id="r6" class="ring"></div>
And the CSS:
.ring {
width: 300px;
height: 300px;
border-radius: 50%;
position: absolute;
background-color: transparent;
border: 15px gray solid;
-webkit-animation-name: ani;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: ease;
-webkit-animation-duration: 6s;
-webkit-animation-direction: reverse;
}
#-webkit-keyframes ani {
0% {-webkit-transform: scale(1); opacity: 0;}
10% {-webkit-transform: scale(1); opacity: 1;}
99.9% {-webkit-transform: scale(0.1); opacity: 1}
100% {-webkit-transform: scale(0.1); opacity: 0}
}
#r2 { -webkit-animation-delay: 1s;}
#r3 { -webkit-animation-delay: 2s;}
#r4 { -webkit-animation-delay: 3s;}
#r5 { -webkit-animation-delay: 4s;}
#r6 { -webkit-animation-delay: 5s;}
The idea is to make the ring appear at minscale, go from min scale to max scale, and then make it disappear.
To make that for n rings, you don't need to create different animations, just reuse the same with an initial delay.
I misread your question and didn't see that you wanted the oposite of the video. I fixed it later setting the animaion in reverse; sorry !
webkit demo
A better solution:
CSS
.ring {
width: 300px;
height: 300px;
border-radius: 50%;
position: absolute;
background-color: transparent;
border: 15px gray solid;
-webkit-animation-name: ani;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-webkit-animation-duration: 6s;
-webkit-animation-direction: normal;
}
#-webkit-keyframes ani {
0% {-webkit-transform: scale(0.01); opacity: 0}
1% {-webkit-transform: scale(0.01); opacity: 1}
95% {-webkit-transform: scale(1); opacity: 1;}
100% {-webkit-transform: scale(1); opacity: 0;}
}
#r2 { -webkit-animation-delay: -1s;}
#r3 { -webkit-animation-delay: -2s;}
#r4 { -webkit-animation-delay: -3s;}
#r5 { -webkit-animation-delay: -4s;}
#r6 { -webkit-animation-delay: -5s;}
new demo
I have changed the keyframes so that now it can run in normal. More important, setting the delays to negative, you can keep the rings separate, but the animation starts right away.
in addition to scaling you would have to dynamically add smaller rings and attach the css animations to them after a certain period. The larger rings should be removed accordingly.
You will have to use jquery for that. The smaller rings should be id'd properly.
Suppose at t=0 you have 7 rings id'd r1-r7(outwards). When the seventh ring scales out of sight, add another ring inside(with an id of r7) and add animation to it. Repeat this infinitely.

Resources