I have animation:
img.rotate {
animation-name: rotate;
animation-duration: 1.5s;
animation-iteration-count: inf
It's a very difficult process to do so. Currently the only way to change an animation mid-animation is to use a setInterval
to approximate the current keyframes percentage, save the properties of that keyframe, update the animation (in your case just the speed) then apply the new version of the animation starting from the saved point. I created a similar example in the article I wrote for CSS Tricks called Controlling CSS Animations & Transitions with Javascript
As the article described, it'd be easier to change the speed on animationIteration
, in your case that would look like this demo, but it is still far from pretty
var pfx = ["webkit", "moz", "MS", "o", ""],
rotates = $('.rotate'),
prevent = false;
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);
}
}
function listen() {
for(var i = 0, j = rotates.length; i < j; i ++) {
PrefixedEvent(rotates[i], "AnimationIteration", function() {
if(!$('#faster').is(':checked') && !prevent) {
var el = $(this),
newOne = el.clone(true)
.css({'animation':'rotate 2s linear infinite'});
el.before(newOne);
$("." + el.attr("class") + ":last").remove();
rotates = $('.rotate');
listen();
prevent = true;
}
else if($('#faster').is(':checked') && prevent) {
prevent = false;
var el = $(this),
newOne = el.clone(true)
.css({'animation':'rotate 1.5s linear infinite'});
el.before(newOne);
$("." + el.attr("class") + ":last").remove();
rotates = $('.rotate');
listen();
}
});
}
}
listen();
At the moment we cannot simply restart the animation with a different timing function (even if you pause it and run it again like Michael said). As a result you either have to use a setInterval
(which gives a higher delay) or clone the element with the changed values. For more information on the approach I used look at the demo, I added comments to all the javascript I added
EDIT based on your linked fiddle in comments
Since you're trying to simulate a roulette, you don't need to use javascript at all! Simply change your rotation
animation to change speed over time (: Here's an rough version of how you'd do so, but you should add more keyframes to make it appear more smooth than it currently behaves
@-webkit-keyframes rotate {
0% { -webkit-transform: rotate( 0deg); }
30% { -webkit-transform: rotate(2600deg); }
60% { -webkit-transform: rotate(4000deg); }
80% { -webkit-transform: rotate(4500deg); }
100% { -webkit-transform: rotate(4780deg); }
}
EDIT 2
Since you need apparently need have a random ending position and likely run it multiple times you can do something like this which is much simpler, only uses CSS transforms, and incredibly useful
var img = document.querySelector('img');
img.addEventListener('click', onClick, false);
var deg = 0;
function onClick() {
this.removeAttribute('style');
deg += 5 * Math.abs(Math.round(Math.random() * 500));
var css = '-webkit-transform: rotate(' + deg + 'deg);';
this.setAttribute(
'style', css
);
}
and the CSS
img { -webkit-transition: -webkit-transform 2s ease-out; }
Edit 3
This isn't fully relevant or irrelevant, but you can do very similar things using GSAP like I did in this project to make it more interactive/dynamic
You can do that by setting a wrapper, and counter-rotating it.
CSS
.wrapper, .inner {
position: absolute;
width: 100px;
height: 100px;
-webkit-animation-name: rotate;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
animation-name: rotate;
animation-iteration-count: infinite;
animation-timing-function: linear;
}
.wrapper {
left: 40px;
top: 40px;
-webkit-animation-duration: 2.5s;
-webkit-animation-play-state: paused;
-webkit-animation-direction: reverse;
animation-duration: 2.5s;
animation-play-state: paused;
animation-direction: reverse;
}
.wrapper:hover {
-webkit-animation-play-state: running;
animation-play-state: running;
}
.inner {
display: block;
background-color: red;
-webkit-animation-duration: 1.5s;
animation-duration: 1.5s;
}
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@-webkit-keyframes rotate {
from { -webkit-transform: rotate(0deg); }
to { -webkit-transform: rotate(360deg); }
}
demo
(hover the square to slow it)