Smoothly stop CSS keyframe animation
You aren't going to like this answer, but reality is that CSS3 animations aren't really useful to achieve this. To make this work you would need to replicate a lot of your CSS in your Javascript which kind of destroys the point (Like for example in this closely related answer Change speed of animation CSS3?). To really make it stop smoothly your best bet would be to write the animation on a platform like the Greensock animation library which provides all the tools you need to make it actually smoothly stop instead of suddenly stop.
How can I make my keyframe animation start over smoothly?
To fix the problem with the half-visible first item after the animation scrolls to the top, you should apply the same height to all items and properly vertically center the h3-tag. To make that easier, I've adjusted your html a little.
To smoothen the animation, you need to change your keyframes. First use a multiple of the height of your elements for the translateY. Then you have to change the percentages. By letting the transition start at 10% of the animation duration, your first item will be visible for a longer time after the animation restarts.
body { font-family: 'Poppins', sans-serif;}
ul { list-style: none;}
#flip { height: 43px; overflow: hidden;}
#flip .content { height: 43px; /* new */ display: flex; flex-direction: column; align-items: center; justify-content: center; /* new */}
#flip h3 { font-weight: 400; font-size: 0.5em; color: white; text-transform: uppercase; padding: 5px; animation: flip 6s infinite; /* changed */ animation-delay: 1s;}
#flip .one { background: #CD1517;}
#flip .two { background: #068587;}
#flip .three { background: #F2B134;}
#flip .four { background: #6B50BF;}
#flip .five { background: #4FB99F;}
/* changed */@-webkit-keyframes flip { 10%, 100% { transform: translateY(0px); } 25% { transform: translateY(-43px); } 40% { transform: translateY(-86px); } 55% { transform: translateY(-129px); } 75% { transform: translateY(-172px); }}
<ul id="flip"> <li class="content"> <h3 class="one">developer</h3> </li> <li class="content"> <h3 class="two">designer</h3> </li> <li class="content"> <h3 class="three">programmer</h3> </li> <li class="content"> <h3 class="four">carodej</h3> </li> <li class="content"> <h3 class="five">alluneed</h3> </li></ul>
Smooth animation stop
It's not possible without JS.
What you can do with CSS is that the animation will be paused by unchecking the checkbox and continues if you check the box again:
#toggle:checked ~ #jumping-div {
animation-play-state:running;
}
#jumping-div {
animation-play-state:paused;
animation-name: jump;
animation-duration: 2.0s;
animation-iteration-count: infinite;
}
If you want to finish on animation you may use the solution WITH JS that was discussed here:
Stopping a CSS animation but letting its current iteration finish
Stop CSS rotate animation smoothly on unknown keyframe
I would use manual animation here. The browser is in charge of its CSS animation and it will be challenging to intervene with that with perfectly synced position and speed.
As the animation is not very complex we can simply set up our own matrix, or use the helper methods, as well as using a sine function where radius is reduced when stopped.
When hitting the stop button we reduce the radius to make it appear to be stopping. We can do the opposite to start again. The benefit is that we can stop at any point and have a natural rest. If you want to offset the angle you could interpolate to that angle at the same time as reducing radius.
By using requestAnimationFrame
and transforms we will obtain smooth animation just like with CSS.
The main function would be:
angle = Math.sin(time) * radius; // sin=[-1,1] radius => angle
Then when stopping, reduce radius which will end up as angle:
radius *= 0.99;
Example
var img = $("img"), btn = $("button"), angle, maxRadius = 10, radius = maxRadius, playing = true, time= 0;
(function loop() { angle = Math.sin(time) * radius; // calc current angle setTransform(img, angle);
if (playing) { if (radius < maxRadius) radius *= 1.03; // increase 3% each frame upto max } else { radius *= 0.99; // reduce 1% each frame } time += 0.1; requestAnimationFrame(loop) // loop, can be stopped when radius < n})();
function setTransform(img, angle) { img.css("transform", "rotate(" + angle + "deg)"); img.css("-webkit-transform", "rotate(" + angle + "deg)");}
btn.on("click", function() { playing = !playing; if (playing && radius < 0.1) radius = 0.1; // give some meat in case =0});
img { transform-origin: top center; -webkit-transform-origin: top center; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><img src="http://i.stack.imgur.com/Vma8v.png"><br><button>Start / Stop smoothly</button>
How can I make this CSS keyframe animation smooth when it restarts?
background-position have to multiplication of original size.
example, if your image size is 100x100 then background-position can be 100x100, 100x200, 200x100, 200x200, and so on
body { height: 100%; /*background-color: #333;*/ background-color: #6b92b9; background-image: url('http://i.imgur.com/BiSmXaq.png'), url('http://i.imgur.com/XHuy0NJ.png'), url('http://i.imgur.com/okpRxJU.png'); animation: snow 5s linear infinite both;}@keyframes snow { 0% { background-position: 0px 0px, 0px 0px, 0px 0px; } 50% { background-color: #b4cfe0; } 100% { background-position: 300px 300px, 400px 400px, 500px 500px; background-color: #6b92b9; }}
Why does my CSS3 animation stops for a few miliseconds in each percentage range using @keyframes?
When you add 2 percent values like 20%, 30% { ... }
, 40%, 50% { ... }
, etc., the rules applied will be the same between those 2 steps/values, hence it stops for a few milliseconds.
If to remove 1 of the percent values, and you can also remove the left
from all but the first and last, you get a smooth animation
div { width: 150px; height: 150px; top: 20px; background-image: url('https://s-media-cache-ak0.pinimg.com/originals/c2/bb/ae/c2bbaed0207deef5775af9c01e1b31ba.jpg'); position: relative; background-size: cover; animation: mymove 5s linear infinite alternate; transform: rotate(0deg); transform:translate3d transition: all;}
@-webkit-keyframes mymove { from, 0% { left: -150px; transform: rotate(5deg) } 20% { transform: rotate(-5deg) } 40% { transform: rotate(5deg) } 60% { transform: rotate(-5deg) } 80% { transform: rotate(5deg) } 100% { left: 100%; transform: rotate(-5deg) }}
<div></div>
How to prevent a CSS keyframe animation from running on page load?
Solution 1 - Add down animation on first hover
Probably the best option is to not put the down animation on until the user has hovered over the container
for the first time.
This involves listening to the mouseover
event then adding a class with the animation at that point, and removing the event listener. The main (potential) downside of this is it relies on Javascript.
;(function(){ var c = document.getElementById('container'); function addAnim() { c.classList.add('animated') // remove the listener, no longer needed c.removeEventListener('mouseover', addAnim); };
// listen to mouseover for the container c.addEventListener('mouseover', addAnim);})();
#container { position:relative; width:100px; height:100px; border-style:inset;}#content { position:absolute; top:100px; width:100%; height:100%; background-color:lightgreen; opacity:0;}
/* This gets added on first mouseover */#container.animated #content { -webkit-animation:animDown 1s ease;}
#container:hover #content { -webkit-animation:animUp 1s ease; animation-fill-mode:forwards; -webkit-animation-fill-mode:forwards;}
@-webkit-keyframes animUp { 0% { -webkit-transform:translateY(0); opacity:0; } 100% { -webkit-transform:translateY(-100%); opacity:1; }}@-webkit-keyframes animDown { 0% { -webkit-transform:translateY(-100%); opacity:1; } 100% { -webkit-transform:translateY(0); opacity:0; }}
<div id="container"> <div id="content"></div></div>
Related Topics
Jquery Select Pseudo-Element :After
How to Change Reactjs Styles Dynamically
Div Square, Width Size Based on 100% Height
Capture Keys Typed on Android Virtual Keyboard Using JavaScript
Passing Parameters to JavaScript Files
How to Round Up a Number in JavaScript
Validation of File Extension Before Uploading File
What Is the Promise Disposer Pattern
Cross-Browser Method to Determine Vertical Scroll Percentage in JavaScript
Meteor.Publish: Publish Collection Which Depends on Other Collection
How to Get the Position of an Element After CSS3 Translation in JavaScript
How to Detect CSS Flex Wrap Event
Good "Background-Size: Cover" Fallbacks/Shims/Tricks for Cross-Browser Compatibility on Divs
Why Can't JavaScript .Play() Audio Files on iPhone Safari
How to Remove "Disabled" Attribute Using Jquery
JavaScript Es6 Computational/Time Complexity of Collections
Correct Path for Img on React.Js
Jsfiddle: No Connection Between HTML and Js? Can't Call Simple Function from Button