Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Queued CSS animations using delay or keyframes that can be interrupted smoothly

First, a fiddle: http://jsfiddle.net/AATLz/

The essence here is that there's a set of animations queued using -webkit-transition-delay. First element 0.4s, second 0.8s, third 1.4s, etc. They're queued last to first by default, and first to last when the parent has the 'expanded' class (toggled with that button).

This means that the animation when '.expanded' is added brings the boxes out one by one, and in reverse when the class is removed.

That's dandy. The problems start to arise when the class is toggled mid-animation. If you toggle, say, after the second box has animated, there's a delay before they start animating back, because a couple delay timers are being waited out.

Delays are obviously a bit clunky here.

The two alternatives I have in mind are 1) CSS keyframe animations, which I'm not entirely sure of how to activate on multiple elements in succession, and 2), JS controlled timing - using something like jQuery Transit. I'm not sure which would be more capable/graceful or if I'm missing another option.

Any input would be awesome!

like image 257
Gavin Avatar asked Nov 12 '22 23:11

Gavin


1 Answers

jsfiddle: http://jsfiddle.net/Bushwazi/fZwTT/

Changed it up a bit. Control the timing with js. Animations with css.

CSS:

* {
    margin:0;
    padding:0;
}
#container {
        background: orange;
        height: 100px;
        position: relative;
        width: 100px;  
}
.box {
        height: 100px;
        left: 0;
        position: absolute;
        top: 0;
        width: 100px; 
        -webkit-transition:all 0.5s ease-in-out 0s;
        -moz-transition:all 0.5s ease-in-out 0s;
        -o-transition:all 0.5s ease-in-out 0s;
        transition:all 0.5s ease-in-out 0s;
        -webkit-transform: translate3d(0,0,0);
}           
.box-1 {
        background: red;
}
.box-2 {
        background: green;
}
.box-3 {
        background: yellow;
}
.box-4 {
        background: blue;
}
.box-1 .box-1 {
    left:100px;
}
.box-2 .box-2 {
    left:200px;
}
.box-3 .box-3 {
    left:300px;
}
.box-4 .box-4 {
    left:400px;
}

HTML:

<div id="container" class="box-0" data-status="default" data-box="0">
    <div class="box box-1"></div>
    <div class="box box-2"></div>
    <div class="box box-3"></div>
    <div class="box box-4"></div>
</div>

<button id="ToggleAnim">Toggle</button>

JS:

(function(){
    var testies = {
        to: 0,
        init: function(){
            $button = $('#ToggleAnim');
            $anim_elm = $('#container');
            $(function(){
                testies.el();
            });
        },
        el: function(){ // el ==> event listeners
            $button.on('click', testies.toggleBoxes);
        },
        toggleBoxes: function(evt){
            var status = $anim_elm.attr('data-status'),
                    pos = $anim_elm.attr('data-box');
            window.clearTimeout(testies.to);
            // if default ==> build
            // if killing ==> build
            // if building ==> kill
            // if done ==> kill
            if(status == 'build' || status == 'done'){
                    testies.kill();
            } else {
                    testies.build();
            }
            evt.preventDefault();
        },
        build: function(){
            bpos = $anim_elm.attr('data-box');
            if(bpos < 4){
                bpos++;
                $anim_elm.attr('data-status', "build").attr('data-box', bpos).addClass('box-' + bpos);
                testies.to = window.setTimeout(testies.build, 500);
            }
            if(bpos == 4)$anim_elm.attr('data-status', "done");
            console.log('BUILD: ' + bpos);
        },
        kill: function(){
            kpos = $anim_elm.attr('data-box');
            if(kpos > 0){
                db = kpos - 1;
                $anim_elm.attr('data-status', "kill").attr('data-box', db).removeClass('box-' + kpos);
                testies.to = window.setTimeout(testies.kill, 500);
            }
            console.log('KILL: ' + kpos);
            if(kpos == 0)$anim_elm.attr('data-status', "default")
        }
    }
    testies.init();
})();
like image 196
Jason Lydon Avatar answered Nov 15 '22 11:11

Jason Lydon