Pausing CSS animation with javascript and also jumping to a specific place in the animation
I have an endless slider built entirely with CSS animations and I want to be able to manipulate the animation with javascript (onlcick and keyboard input). I want to be able to run through the animation rapidly from one frame, ie, speeding it up.. to another to give a jumping effect when a button is pressed that refers to a specific image in the slider. Also, I want to be able to step through the animation with keyboard input... ( --> , <-- )
Does anyone know how to achieve this?
on click..
- retrieve current keyframe position;
- set appropriate direction to destination;
- increase speed of animation greatly until desired keyframe is reached;
- either pause animation or continue from new point
keyboard input…
- jump to specific keyframes and continue animation
Try
html
<!-- html -->
<div id=animated></div>
css
/* css */
#animated {
animation : animationName; /* animation block(s) */
animation-play-state : paused; /* (paused; running) */
}
@keyframes animationName {
0% { .. /* css animations (`animationstart`) */ }
50% {..}
100% { .. /* css animations (`animationend` / `animationiteration` (start; end)) */ }
}
js
(function(el) {
function animations(e) {
/* `key code` to trigger event */
if (e.which === 123456) {
$(el).animate({ /* jquery animations */ }, 123456 /* duration */)
.promise().done(function() {
el.style.animationPlayState = "running";
el.style.WebkitAnimationPlayState = "running";
});
};
};
$(window).on("keydown", animations);
})($(#animated).get(0))
$(document).ready(function() {
(function reanimate(el, r, p, runner, pauser, pauseAll) {
var _state = function() {
$.when(
$("#animated").data("states", {"fxq": "animated!","cssAnimationState": (el.style.WebkitAnimationPlayState || el.style.animationPlayState),"jsAnimationState": $("#animated").queue("fx")[0]}))
.done(function(status) {
return status.data("states")
});
return String("css animation state: " + (el.style.WebkitAnimationPlayState || el.style.animationPlayState) + " js animation state: " + $("#animated").queue("fx")[0])
};
var runner = function() {
el.style.animationPlayState = "running";
el.style.WebkitAnimationPlayState = "running";
return $("data").html(_state())
};
var pauser = function() {
el.style.animationPlayState = "paused";
el.style.WebkitAnimationPlayState = "paused";
$("#animated:animated, #animated *").finish().queue("fx", []);
return $("data").html(_state())
};
$("button:last").on("click", pauser);
$("button:first").on("click", runner);
function player(e, pause, play, pauseAll) {
/*!
// settings
*/
var pauseAll = (undefined || 38); /* `up-arrow` : `pauseAll` */
var pause = (undefined || 37); /* `left-arrow` : `paused` */
var play = (undefined || 39); /* `right-arrow` : `running` */
if (e.which === play) {
e.preventDefault();
runner();
$("data").html(_state())
};
/*!
// js (jquery) animations (, css transitions,
// css animations) at `paused` css animations
*/
if (e.which === pause) {
e.preventDefault();
$.when(
$('#animated')
.animate({
width: "+=400px",
height: "+=400px",
borderRadius: "+=50%",
fontSize: "+=22px"
},
{
duration: 3500,
easing: "swing",
start: $('#animated').css({"transition": "background 3500ms linear, box-shadow 3500ms linear","-webkit-transition": "background 3500ms linear, -webkit-box-shadow 3500ms linear","-moz-transition": "background 3500ms linear, -moz-box-shadow 3500ms linear","background": "yellow","box-shadow": "0.25em 0.25em 0.25em #f57900","-webkit-transform-style": "preserve-3d","-webkit-transform": "rotateX(180deg) rotateZ(45deg)","-moz-transform-style": "preserve-3d","-transform": "rotateX(180deg) rotateZ(45deg)","-webkit-backface-visibility": "visible","-moz-backface-visibility": "visible"}).html(function() {
return $("<em>" + $('#animated').data("states").fxq + "</em>").css({"display": "block","position": "relative","top": "25%","left": "0%","transform": "rototeX(33deg)","text-shadow": "2px 2px 2px orange"}).fadeIn(2000, function() {
_state()
})
})
})
.animate({width: "100px",height: "100px",
borderTopLeftRadius: "0%",
borderTopRightRadius: "0%",
borderBottomLeftRadius: "0%",
borderBottomRightRadius: "0%",
fontSize: "10px"}, {
duration: 3500,
easing: "linear",
done: function() {
$('#animated').css({"transition": "background 3500ms ease-out, box-shadow 2500ms ease-out","-webkit-transition": "background 3500ms, -webkit-box-shadow 3500ms ease-out","-moz-transition": "background 3500ms ease-out, -moz-box-shadow 3500ms ease-out","background": "red","box-shadow": "0.0em 0.0em 0.0em transparent","-webkit-transform": "rotateX(0deg) rotateY(0deg) rotateZ(0deg)","transform": "rotateX(0deg) rotateY(0deg) rotateZ(0deg)","-moz-backface-visibility": "hidden","-webkit-backface-visibility": "hidden"}).children("em").fadeOut(2000, function() {
_state()
}).promise().done(function() {
$("em").finish().detach()
})
}
}), $("data").html(_state())).promise().done(function() {
runner();
}).always(function() {_state()})
};
/*!
// pause all css and js animations
*/
if (e.which === pauseAll) {
e.preventDefault();
(function() {
var _check = ($("#animated").queue("fx")[0] != undefined ? $("#animated:animated, #animated *").finish() && pauser() : ((el.style.animationPlayState === undefined ? el.style.WebkitAnimationPlayState : el.style.animationPlayState) === "running" ? pauser() : runner()))
return $.when(_check, $("data").html(_state()))
}())
};
};
$(window).on("keydown", player);
return $("data").html(_state())
})($("#animated").get(0), "running", "paused")
})
See http://guest271314.github.io/reanimate/
There may be several possible ways to accomplish the requirement, including CSSOM, Javascript, jQuery library. See links.
Starting and pausing css animations can be done through the
animation-play-state
property.
Starting and stopping jquery animations can be done a couple ways.
$(element).queue("fx", [])
should stop all jquery animations and clear
jquery animations
queue
. .finish()
should complete, or finish
the currently
running, or inprogress
jquery animations.
animation-play-state : paused
will not stop jquery animations.
The process could also be accomplished by inserting, replacing,
or removing style
element(s), or only text within the style
element;
animationstart
, and animationiteration
DOM events; and some other potential
options linked below.
Put the piece reanimate.js together including a couple of the above mentioned methods. css transitions were included within the jquery animations, though that portion could probably be substituted for either accessing the exact timing phase of the running css animation ("@keyframes"), and/or inserting new animations; or adjusting, or redefining timings.
This piece is just a working draft template to share prosepctive functionality. Note, webkit, firefox and opera may "render" the animations slightly differently. Using this template webkit may appear to "transition" somewhat more "smoother" to a "running" css animation than firefox. Full opera support may require some more fine tuning.
Opera appears to use -o-
, and -webkit-
prefixes for some css properties,
while using only w3c standards (no prefixes) for others. Also, each browser
may require a different "prefix" for accessing "animationstart", etc.
reanimate.js does not currently (version 1.0) attempt to access the exact css
keyframe
'(elapsedTime
) within/of the running
css animation before interrupting
them with several layered
or "reanimated" css/js animations an/or css transitions.
But rather, attempts to return the css animation(s) to the approximate position which
they were running at before the "layered" js animation interruption. Though, it should
be possible to access that exact animation elapsedTime
or timeStamp
(which may be 0
or a miiliseond-type time stamp, depending on the browser) of the keyframes
. For example,
by accssing the "animationiteration" or "animationstart" or "animationend" events,
or by possible usage of "requestAnimationFrame".
Resources:
programmatically changing webkit-transformation values in animation rules
Set Webkit Keyframes Values Using Javascript Variable position http://jsfiddle.net/russelluresti/RHhBz/2/
Alter or generate and then remove a css3 keyframe
Changing the different Keyframes in css using Javascript
https://developer.apple.com/library/safari/documentation/AudioVideo/Reference/WebKitAnimationEventClassReference/WebKitAnimationEvent/WebKitAnimationEvent.html
http://msdn.microsoft.com/en-us/library/ie/hh772074%28v=vs.85%29.aspx
http://blogs.msdn.com/b/msdn_answers/archive/2013/11/04/part-i-using-javascript-to-set-keyframes-in-css-animations-windows-store-apps-ie.aspx
http://www.w3.org/TR/animation-timing/
Hope this helps