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..

  1. retrieve current keyframe position;
  2. set appropriate direction to destination;
  3. increase speed of animation greatly until desired keyframe is reached;
  4. either pause animation or continue from new point

keyboard input…

  1. 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) + "&nbsp; 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